# MODELO DE DOMINIO: Proyectos **Módulos:** MGN-011 (Proyectos Genéricos) **Fecha:** 2025-11-24 **Referencia Odoo:** project **Referencia Gamilit:** projects_management schema --- ## Diagrama de Entidades (Texto UML) ``` [Project] - id: UUID (PK) - tenant_id: UUID (FK) - company_id: UUID (FK) - name: String - description: Text - partner_id: UUID (FK) - manager_id: UUID (FK user) - analytic_account_id: UUID (FK) - date_start: Date - date_end: Date - status: ENUM (draft, active, completed, cancelled) - privacy: ENUM (public, private, followers) 1 <----> * [Task] 1 <----> * [Milestone] 1 <----> 1 [AnalyticAccount] (MGN-008) [Task] - id: UUID (PK) - tenant_id: UUID (FK) - project_id: UUID (FK) - name: String - description: Text - assigned_to: UUID (FK user) - stage_id: UUID (FK) - parent_id: UUID (FK self) - milestone_id: UUID (FK) - date_start: Date - date_deadline: Date - priority: ENUM (low, normal, high, urgent) - planned_hours: Decimal - actual_hours: Decimal - progress: Integer (0-100) - status: ENUM (todo, in_progress, review, done, cancelled) 1 <----> * [Task] (subtareas) 1 <----> * [Timesheet] * <----> * [Task] (dependencias) [Stage] - id: UUID (PK) - tenant_id: UUID (FK) - project_id: UUID (FK) - name: String - sequence: Integer - is_closed: Boolean - fold: Boolean [Milestone] - id: UUID (PK) - tenant_id: UUID (FK) - project_id: UUID (FK) - name: String - description: Text - date: Date - status: ENUM (pending, completed) 1 <----> * [Task] [TaskDependency] - id: UUID (PK) - task_id: UUID (FK) - depends_on_id: UUID (FK task) - dependency_type: ENUM (finish_to_start, start_to_start, finish_to_finish) [ProjectTag] - id: UUID (PK) - tenant_id: UUID (FK) - name: String - color: String * <----> * [Task] (many-to-many) ``` ## Entidades Principales ### 1. Project (Proyecto) **Descripción:** Proyecto genérico de gestión de tareas. **Atributos:** - `id`: UUID - `name`: Nombre del proyecto - `description`: Descripción - `partner_id`: Cliente (opcional) - `manager_id`: Manager del proyecto - `analytic_account_id`: Cuenta analítica (1-1) - `date_start`: Fecha de inicio - `date_end`: Fecha de fin - `status`: draft, active, completed, cancelled - `privacy`: public, private, followers **Relaciones:** - 1 Project → N Tasks - 1 Project → N Milestones - 1 Project → 1 AnalyticAccount (MGN-008) - N Projects → 1 Partner (cliente) **Patrón Odoo:** project.project **Nota:** Cada proyecto tiene una cuenta analítica asociada para tracking de costos/ingresos ### 2. Task (Tarea) **Descripción:** Tarea dentro de un proyecto. **Atributos:** - `id`: UUID - `project_id`: Proyecto propietario - `name`: Nombre de la tarea - `description`: Descripción detallada - `assigned_to`: Usuario asignado - `stage_id`: Etapa actual - `parent_id`: Tarea padre (subtareas) - `milestone_id`: Milestone asociado - `date_start`: Fecha inicio - `date_deadline`: Fecha límite - `priority`: low, normal, high, urgent - `planned_hours`: Horas planificadas - `actual_hours`: Horas reales (suma de timesheets) - `progress`: Porcentaje de avance (0-100) - `status`: todo, in_progress, review, done, cancelled **Relaciones:** - N Tasks → 1 Project - N Tasks → 1 Stage - 1 Task → N Subtasks - N Tasks ←→ N Tasks (dependencias) - 1 Task → N Timesheets **Patrón Odoo:** project.task **Jerarquía:** Tareas pueden tener subtareas (parent_id) ### 3. Stage (Etapa) **Descripción:** Etapa en el flujo de trabajo del proyecto. **Atributos:** - `id`: UUID - `project_id`: Proyecto propietario - `name`: Nombre (ej: "To Do", "In Progress", "Review", "Done") - `sequence`: Orden de etapa - `is_closed`: Marca si es etapa final - `fold`: Plegada en vista Kanban **Relaciones:** - N Stages → 1 Project - 1 Stage → N Tasks **Patrón Odoo:** project.task.type **Stages típicos:** 1. To Do (sequence: 1) 2. In Progress (sequence: 2) 3. Review (sequence: 3) 4. Done (sequence: 4, is_closed: true) ### 4. Milestone (Hito) **Descripción:** Hito importante en el proyecto. **Atributos:** - `id`: UUID - `project_id`: Proyecto propietario - `name`: Nombre del milestone - `description`: Descripción - `date`: Fecha objetivo - `status`: pending, completed **Relaciones:** - N Milestones → 1 Project - 1 Milestone → N Tasks **Patrón Odoo:** project.milestone **Ejemplos:** - "Kick-off Meeting" - "Design Phase Complete" - "Development Complete" - "Go Live" ### 5. TaskDependency (Dependencia entre Tareas) **Descripción:** Dependencia entre tareas (precedencia). **Atributos:** - `id`: UUID - `task_id`: Tarea dependiente - `depends_on_id`: Tarea de la que depende - `dependency_type`: finish_to_start, start_to_start, finish_to_finish **Relaciones:** - N TaskDependencies → 1 Task (task_id) - N TaskDependencies → 1 Task (depends_on_id) **Patrón Odoo:** project.task (blocked_by) **Tipos:** - finish_to_start: Tarea B inicia cuando A termina (más común) - start_to_start: A y B inician juntas - finish_to_finish: A y B terminan juntas ### 6. ProjectTag (Etiqueta de Tarea) **Descripción:** Etiqueta para categorizar tareas. **Atributos:** - `id`: UUID - `name`: Nombre - `color`: Color para UI **Relaciones:** - N ProjectTags ←→ N Tasks **Patrón Odoo:** project.tags **Tags típicos:** - Priority tags (High, Low) - Type tags (Bug, Feature, Enhancement) - Module tags (Backend, Frontend, Database) ## Reglas de Negocio ### RN-PRO-001: Proyecto y Analítica 1-1 - TODO proyecto tiene exactamente 1 cuenta analítica - Cuenta analítica se crea automáticamente al crear proyecto - Nombre de cuenta analítica = nombre de proyecto ### RN-PRO-002: Flujo de Tareas (Kanban) - Tareas se mueven entre stages (drag & drop) - Al llegar a stage con is_closed=true, marca como 'done' - No permitir mover tarea si dependencias no completadas ### RN-PRO-003: Actualización de Horas - actual_hours = SUM(Timesheet.hours WHERE task_id = X) - Actualización automática al validar timesheet - Progress puede actualizarse manualmente o automáticamente (actual_hours / planned_hours * 100) ### RN-PRO-004: Jerarquía de Tareas - Tarea puede tener subtareas (parent_id) - Nivel máximo de anidación: 3 (configurable) - No permitir ciclos (tarea no puede ser su propia padre) ### RN-PRO-005: Dependencias - Tarea no puede iniciarse si dependencias no completadas (finish_to_start) - Sistema valida dependencias antes de mover a 'in_progress' - No permitir dependencias circulares ### RN-PRO-006: Milestones - Milestone completado cuando todas sus tareas están 'done' - Sistema actualiza status automáticamente ### RN-PRO-007: Privacy - public: Todos los usuarios ven el proyecto - private: Solo miembros asignados - followers: Solo followers del proyecto (patrón mail.followers) ### RN-PRO-008: Gantt View - Visualización de tareas en timeline - Considerar date_start, date_deadline, dependencies - Arrastrar para reprogramar ## Casos de Uso Principales 1. **UC-PRO-001:** Manager crea proyecto 2. **UC-PRO-002:** Manager asigna cliente a proyecto 3. **UC-PRO-003:** Manager crea tareas en proyecto 4. **UC-PRO-004:** Usuario asignado mueve tarea entre stages (kanban) 5. **UC-PRO-005:** Usuario asignado actualiza progress de tarea 6. **UC-PRO-006:** Empleado registra timesheet en tarea 7. **UC-PRO-007:** Manager crea milestone y asocia tareas 8. **UC-PRO-008:** Manager define dependencias entre tareas 9. **UC-PRO-009:** Usuario visualiza Gantt de proyecto 10. **UC-PRO-010:** Cliente ve avance de proyecto en portal (MGN-013) ## Validaciones y Constraints ```sql -- Date end >= date start (project) CHECK (date_end IS NULL OR date_end >= date_start) -- Date deadline >= date start (task) CHECK (date_deadline IS NULL OR date_deadline >= date_start) -- Planned hours >= 0 CHECK (planned_hours >= 0) -- Progress entre 0 y 100 CHECK (progress >= 0 AND progress <= 100) -- Priority válidos CHECK (priority IN ('low', 'normal', 'high', 'urgent')) -- Tarea no puede ser su propio padre CHECK (parent_id != id) -- Dependencia no puede ser consigo misma CHECK (task_id != depends_on_id) -- Stage sequence > 0 CHECK (sequence > 0) ``` ## Índices Requeridos ```sql CREATE INDEX idx_projects_partner_id ON projects.projects(partner_id); CREATE INDEX idx_projects_manager_id ON projects.projects(manager_id); CREATE INDEX idx_projects_status ON projects.projects(status); CREATE INDEX idx_projects_analytic_account_id ON projects.projects(analytic_account_id); CREATE INDEX idx_tasks_project_id ON projects.tasks(project_id); CREATE INDEX idx_tasks_assigned_to ON projects.tasks(assigned_to); CREATE INDEX idx_tasks_stage_id ON projects.tasks(stage_id); CREATE INDEX idx_tasks_parent_id ON projects.tasks(parent_id); CREATE INDEX idx_tasks_milestone_id ON projects.tasks(milestone_id); CREATE INDEX idx_tasks_date_deadline ON projects.tasks(date_deadline); CREATE INDEX idx_milestones_project_id ON projects.milestones(project_id); CREATE INDEX idx_task_dependencies_task_id ON projects.task_dependencies(task_id); CREATE INDEX idx_task_dependencies_depends_on_id ON projects.task_dependencies(depends_on_id); ``` ## Integración con Otros Módulos ### Con MGN-003 (Catálogos) - Project.partner_id → Partner (cliente) ### Con MGN-008 (Analítica) - Project.analytic_account_id → AnalyticAccount (1-1) - Costos/ingresos del proyecto se trackean en analítica ### Con MGN-010 (RRHH) - Task.assigned_to → Employee - Timesheet de empleado se asigna a Task ### Con MGN-013 (Portal) - Cliente ve proyecto en portal - Cliente ve tareas (read-only) - Cliente comenta en tareas ### Con MGN-014 (Mensajería) - Tareas tienen chatter - Followers reciben notificaciones - Actividades programadas en tareas ### Con MGN-012 (Reportes) - Dashboard de proyectos: - Tareas por stage - Horas planificadas vs reales - Progress por proyecto - Milestones cumplidos vs pendientes ## Referencias - [ALCANCE-POR-MODULO.md - MGN-011](../../01-definicion-modulos/ALCANCE-POR-MODULO.md#mgn-011) - [ADR-007: Database Design](../../adr/ADR-007-database-design.md) - [odoo-project-analysis.md](../../00-analisis-referencias/odoo/odoo-project-analysis.md)