12 KiB
MODELO DE DOMINIO: Mensajería y Notificaciones
Módulos: MGN-012 (Reportes), MGN-014 (Mensajería y Notificaciones) Fecha: 2025-11-24 Referencia Odoo: mail (mail.thread, mail.message, mail.followers, mail.activity) Referencia Gamilit: notifications_management schema
Diagrama de Entidades (Texto UML)
[Message]
- id: UUID (PK)
- tenant_id: UUID (FK)
- author_id: UUID (FK user)
- model: String (ej: "SaleOrder")
- res_id: UUID (ID del registro)
- message_type: ENUM (note, comment, notification, email)
- subject: String
- body: Text
- parent_id: UUID (FK self)
- subtype_id: UUID (FK)
1 <----> * [Attachment]
1 <----> * [Notification]
[Follower]
- id: UUID (PK)
- tenant_id: UUID (FK)
- model: String
- res_id: UUID
- partner_id: UUID (FK)
- user_id: UUID (FK)
[Notification]
- id: UUID (PK)
- tenant_id: UUID (FK)
- message_id: UUID (FK)
- user_id: UUID (FK)
- notification_type: ENUM (inbox, email, push)
- is_read: Boolean
- read_at: Timestamp
[Activity]
- id: UUID (PK)
- tenant_id: UUID (FK)
- model: String
- res_id: UUID
- activity_type_id: UUID (FK)
- user_id: UUID (FK)
- assigned_by: UUID (FK user)
- summary: String
- note: Text
- date_deadline: Date
- status: ENUM (pending, done, overdue, cancelled)
- completed_at: Timestamp
[ActivityType]
- id: UUID (PK)
- tenant_id: UUID (FK)
- name: String
- icon: String
- sequence: Integer
- default_user_id: UUID (FK)
[MessageSubtype]
- id: UUID (PK)
- name: String
- description: Text
- internal: Boolean
- parent_id: UUID (FK self)
[Attachment]
- id: UUID (PK)
- tenant_id: UUID (FK)
- name: String
- file_path: String
- file_size: Integer
- mimetype: String
- checksum: String
- model: String
- res_id: UUID
[EmailTemplate]
- id: UUID (PK)
- tenant_id: UUID (FK)
- name: String
- model: String
- subject: String (Handlebars template)
- body_html: Text (Handlebars template)
- email_from: String
- email_to: String
[TrackingValue]
- id: UUID (PK)
- tenant_id: UUID (FK)
- message_id: UUID (FK)
- field_name: String
- field_type: ENUM (char, integer, float, boolean, many2one, date)
- old_value: String
- new_value: String
Entidades Principales
1. Message (Mensaje/Chatter)
Descripción: Mensaje asociado a un registro (patrón mail.thread).
Atributos:
id: UUIDauthor_id: Autor del mensaje (user)model: Modelo del registro (ej: "SaleOrder")res_id: ID del registro asociadomessage_type: note, comment, notification, emailsubject: Asuntobody: Cuerpo del mensaje (HTML)parent_id: Mensaje padre (replies)subtype_id: Subtipo de mensaje
Relaciones:
- 1 Message → N Attachments
- 1 Message → N Notifications
- 1 Message → N TrackingValues
Patrón Odoo: mail.message Tipos:
- note: Nota interna (solo empleados)
- comment: Comentario (visible a followers)
- notification: Notificación automática
- email: Email enviado/recibido
2. Follower (Seguidor)
Descripción: Usuario que sigue un registro (recibe notificaciones).
Atributos:
id: UUIDmodel: Modelo del registrores_id: ID del registropartner_id: Partner seguidoruser_id: Usuario seguidor
Relaciones:
- N Followers → 1 User/Partner
Patrón Odoo: mail.followers Auto-follow:
- Usuario que crea registro se vuelve follower automáticamente
- Usuario asignado (assigned_to) se vuelve follower
- Usuario mencionado (@username) se vuelve follower
3. Notification (Notificación)
Descripción: Notificación enviada a usuario.
Atributos:
id: UUIDmessage_id: Mensaje asociadouser_id: Usuario destinatarionotification_type: inbox, email, pushis_read: Leída/No leídaread_at: Timestamp de lectura
Relaciones:
- N Notifications → 1 Message
- N Notifications → 1 User
Patrón Odoo: mail.notification Tipos:
- inbox: Notificación in-app (campana)
- email: Email enviado
- push: Push notification (mobile/web)
4. Activity (Actividad Programada)
Descripción: Actividad programada (tarea, llamada, reunión).
Atributos:
id: UUIDmodel: Modelo del registro asociadores_id: ID del registroactivity_type_id: Tipo de actividaduser_id: Usuario asignadoassigned_by: Usuario que asignósummary: Resumennote: Nota adicionaldate_deadline: Fecha límitestatus: pending, done, overdue, cancelledcompleted_at: Fecha de completado
Relaciones:
- N Activities → 1 ActivityType
- N Activities → 1 User (asignado)
Patrón Odoo: mail.activity Estados:
- pending: Pendiente
- done: Completada
- overdue: Vencida (date_deadline < HOY)
- cancelled: Cancelada
5. ActivityType (Tipo de Actividad)
Descripción: Tipo de actividad programable.
Atributos:
id: UUIDname: Nombre (ej: "Llamada", "Reunión")icon: Icono para UIsequence: Ordendefault_user_id: Usuario por defecto
Relaciones:
- 1 ActivityType → N Activities
Patrón Odoo: mail.activity.type Tipos estándar:
- Call (Llamada telefónica)
- Meeting (Reunión)
- Email (Enviar email)
- To Do (Tarea general)
6. MessageSubtype (Subtipo de Mensaje)
Descripción: Subtipo para clasificar mensajes.
Atributos:
id: UUIDname: Nombre (ej: "Status Change", "Stage Changed")description: Descripcióninternal: Solo interno (no visible a followers externos)parent_id: Subtipo padre
Relaciones:
- 1 MessageSubtype → N Messages
Patrón Odoo: mail.message.subtype Subtipos estándar:
- Discussions (Comentarios)
- Note (Notas internas)
- Status Change (Cambio de estado)
- Stage Changed (Cambio de etapa)
7. Attachment (Adjunto)
Descripción: Archivo adjunto a mensaje o registro.
Atributos:
id: UUIDname: Nombre del archivofile_path: Ruta en storage (S3 o filesystem)file_size: Tamaño en bytesmimetype: Tipo MIMEchecksum: Hash SHA256model: Modelo asociadores_id: ID del registro
Relaciones:
- N Attachments → 1 Message
- N Attachments → 1 Registro (genérico)
Patrón Odoo: ir.attachment Storage: S3 o filesystem local
8. EmailTemplate (Template de Email)
Descripción: Template configurable para emails.
Atributos:
id: UUIDname: Nombre del templatemodel: Modelo asociadosubject: Asunto (Handlebars)body_html: Cuerpo HTML (Handlebars)email_from: Email remitenteemail_to: Email destinatario (template)
Relaciones:
- 1 EmailTemplate → N Emails enviados
Patrón Odoo: mail.template Variables disponibles:
{{user.name}}
{{company.name}}
{{order.name}}
{{order.amount_total}}
9. TrackingValue (Valor Trackeado)
Descripción: Cambio de valor en campo trackeado.
Atributos:
id: UUIDmessage_id: Mensaje asociadofield_name: Nombre del campofield_type: Tipo de campoold_value: Valor anteriornew_value: Valor nuevo
Relaciones:
- N TrackingValues → 1 Message
Patrón Odoo: mail.tracking.value Ejemplo:
Field: status
Old: draft
New: confirmed
→ Mensaje: "User X changed Status from Draft to Confirmed"
Reglas de Negocio
RN-MSG-001: Auto-Follow
- Usuario que crea registro → follower automático
- Usuario asignado (assigned_to) → follower automático
- Usuario mencionado (@username) → follower automático
RN-MSG-002: Notificaciones a Followers
- Al crear mensaje tipo 'comment', notificar a followers
- Al crear mensaje tipo 'note' (internal), no notificar a followers externos
RN-MSG-003: Tracking Automático
- Decorador
@TrackChanges(['status', 'amount'])en modelo - Al actualizar campo, generar mensaje automático con TrackingValues
- Mensaje subtipo: "Status Change" o similar
RN-MSG-004: Actividades Vencidas
- Sistema marca activities con status='overdue' si date_deadline < HOY
- Enviar notificación diaria de actividades vencidas
RN-MSG-005: Email desde Templates
- Al enviar email, reemplazar variables Handlebars
- Variables disponibles: registro, user, company
- Guardar email enviado como Message tipo='email'
RN-MSG-006: Notificaciones Multi-Canal
- Usuario puede configurar preferencias:
- inbox: Siempre
- email: Solo para menciones
- push: Nunca
- Sistema respeta preferencias al crear Notification
RN-MSG-007: WebSocket Real-Time
- Notificaciones inbox se envían por WebSocket (Socket.IO)
- Cliente recibe notificación instantánea
- Badge count actualizado en tiempo real
RN-MSG-008: Chatter Genérico
- TODO modelo puede tener chatter (mixin)
- Patrón: model + res_id + messages
- UI consistente en todos los módulos
Casos de Uso Principales
- UC-MSG-001: Usuario comenta en orden de venta (chatter)
- UC-MSG-002: Sistema registra cambio automático (tracking)
- UC-MSG-003: Usuario recibe notificación in-app
- UC-MSG-004: Usuario recibe notificación por email
- UC-MSG-005: Usuario menciona a otro (@username) en comentario
- UC-MSG-006: Usuario programa actividad (llamada)
- UC-MSG-007: Sistema marca actividad como overdue
- UC-MSG-008: Usuario sigue orden de compra (follow)
- UC-MSG-009: Sistema envía email desde template
- UC-MSG-010: Usuario adjunta archivo en mensaje
Validaciones y Constraints
-- Message tipo válido
CHECK (message_type IN ('note', 'comment', 'notification', 'email'))
-- Activity status válido
CHECK (status IN ('pending', 'done', 'overdue', 'cancelled'))
-- Notification type válido
CHECK (notification_type IN ('inbox', 'email', 'push'))
-- Attachment file_size > 0
CHECK (file_size > 0)
-- Activity deadline no puede ser pasado al crear
-- (validación en backend)
-- Follower único por model + res_id + user_id
UNIQUE (tenant_id, model, res_id, user_id)
Índices Requeridos
CREATE INDEX idx_messages_model_res_id ON system.messages(model, res_id);
CREATE INDEX idx_messages_author_id ON system.messages(author_id);
CREATE INDEX idx_messages_message_type ON system.messages(message_type);
CREATE INDEX idx_followers_model_res_id ON system.followers(model, res_id);
CREATE INDEX idx_followers_user_id ON system.followers(user_id);
CREATE INDEX idx_notifications_user_id ON system.notifications(user_id);
CREATE INDEX idx_notifications_is_read ON system.notifications(is_read);
CREATE INDEX idx_activities_user_id ON system.activities(user_id);
CREATE INDEX idx_activities_status ON system.activities(status);
CREATE INDEX idx_activities_date_deadline ON system.activities(date_deadline);
CREATE INDEX idx_attachments_model_res_id ON system.attachments(model, res_id);
CREATE INDEX idx_tracking_values_message_id ON system.tracking_values(message_id);
Integración con Otros Módulos
Con TODOS los Módulos
- Chatter es transversal: todos los modelos pueden tener mensajes
- Tracking automático en modelos transaccionales
- Actividades programables en cualquier registro
Con MGN-001 (Fundamentos)
- Messages de User
- Notifications a User
- Followers son Users/Partners
Con MGN-007 (Ventas)
- Cotizaciones con chatter
- Tracking de cambios de status
- Actividades de seguimiento a cliente
Con MGN-011 (Proyectos)
- Tareas con chatter
- Actividades por tarea
- Followers de proyecto
Con MGN-013 (Portal)
- Cliente ve mensajes en portal
- Cliente puede comentar (tipo='comment')
- Cliente NO ve mensajes internos (type='note')
Implementación Técnica
Mixin de Chatter (Backend)
// Decorador para modelos con chatter
@HasChatter()
export class SaleOrder {
// ...campos
}
// Decorador para tracking
@TrackChanges(['status', 'amount_total', 'partner_id'])
export class SaleOrder {
status: string;
amount_total: number;
partner_id: string;
}
WebSocket (Real-Time)
// Enviar notificación en tiempo real
socket.to(`user:${userId}`).emit('notification', {
id: notification.id,
message: notification.message,
type: notification.type
});
Referencias
Importancia: ⭐⭐⭐⭐⭐ ESENCIAL para auditoría y colaboración