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