erp-core/docs/04-modelado/domain-models/projects-domain.md

358 lines
10 KiB
Markdown

# 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)