# TRACEABILITY-MGN-011.yaml # Matriz de Trazabilidad - MGN-011: Proyectos Genéricos # Fecha: 2025-11-24 # Versión: 1.0 module: id: MGN-011 name: "Proyectos Genéricos" description: "Gestión de proyectos: tareas, milestones, timesheet, miembros y seguimiento" priority: P1 story_points: 40 status: Diseñado metadata: total_rf: 5 total_et_backend: 5 total_et_frontend: 5 total_tables: 5 total_tests: 100 coverage: 100% requirements: - rf_id: RF-MGN-011-001 rf_title: "Gestión de Proyectos" rf_file: "requerimientos-funcionales/mgn-011/RF-MGN-011-001-gestión-de-proyectos.md" priority: P1 story_points: 8 et_backend: file: "especificaciones-tecnicas/backend/mgn-011/ET-BACKEND-MGN-011-001-gestión-de-proyectos.md" endpoints: - method: POST path: /api/v1/projects description: "Crear nuevo proyecto" - method: GET path: /api/v1/projects description: "Listar todos los proyectos" - method: GET path: /api/v1/projects/:id description: "Obtener proyecto por ID" - method: PUT path: /api/v1/projects/:id description: "Actualizar proyecto" - method: DELETE path: /api/v1/projects/:id description: "Eliminar proyecto (soft delete)" services: - name: "ProjectService" file: "src/modules/projects/services/project.service.ts" methods: - create - findAll - findOne - update - remove - validateBusinessRules controllers: - name: "ProjectController" file: "src/modules/projects/controllers/project.controller.ts" dtos: - name: "CreateProjectDto" file: "src/modules/projects/dto/create-project.dto.ts" - name: "UpdateProjectDto" file: "src/modules/projects/dto/update-project.dto.ts" - name: "ProjectResponseDto" file: "src/modules/projects/dto/project-response.dto.ts" - name: "FilterProjectDto" file: "src/modules/projects/dto/filter-project.dto.ts" et_frontend: file: "especificaciones-tecnicas/frontend/mgn-011/ET-FRONTEND-MGN-011-001-gestión-de-proyectos.md" routes: - path: "/projects" component: "ProjectsPage" - path: "/projects/create" component: "CreateProjectPage" - path: "/projects/:id/edit" component: "EditProjectPage" - path: "/projects/:id" component: "ViewProjectPage" components: - name: "ProjectsTable" file: "src/widgets/projects-table/ui/ProjectsTable.tsx" type: widget - name: "CreateProjectForm" file: "src/features/create-project/ui/CreateProjectForm.tsx" type: feature - name: "ProjectCard" file: "src/entities/project/ui/ProjectCard.tsx" type: entity - name: "ProjectPage" file: "src/pages/projects/ProjectPage.tsx" type: page api_client: - name: "projectApi" file: "src/entities/project/api/project.api.ts" methods: - getAll - getById - create - update - delete state_management: - name: "useProjectStore" file: "src/entities/project/model/project.store.ts" type: zustand - name: "useProjects" file: "src/entities/project/api/project.queries.ts" type: react-query database_tables: - schema: projects table: projects file: "database-design/schemas/projects-schema-ddl.sql" operations: - SELECT - INSERT - UPDATE - DELETE (soft) indices: - idx_projects_tenant_id - idx_projects_analytic_account_id - idx_projects_status rls_policy: tenant_isolation_projects tests: backend: unit_tests: - file: "src/modules/projects/services/project.service.spec.ts" test_cases: - "should create project with valid data" - "should link to analytic account automatically" - "should validate date range" - "should find all projects for tenant" - "should update project successfully" integration_tests: - file: "test/projects/project.controller.e2e-spec.ts" test_cases: - "POST /api/v1/projects should create project" - "GET /api/v1/projects should return all projects" - "GET /api/v1/projects/:id should return project" - "PUT /api/v1/projects/:id should update project" - "DELETE /api/v1/projects/:id should soft delete project" - "should enforce tenant isolation" - "should require authentication" - "should check permissions" frontend: component_tests: - file: "src/widgets/projects-table/ui/ProjectsTable.test.tsx" test_cases: - "should render table with projects" - "should handle pagination" - "should filter by status" - file: "src/features/create-project/ui/CreateProjectForm.test.tsx" test_cases: - "should validate required fields" - "should submit valid form" - "should show error messages" e2e_tests: - file: "e2e/projects/projects.spec.ts" test_cases: - "should create project successfully" - "should edit project successfully" - "should delete project with confirmation" - "should enforce permissions" acceptance_criteria: - id: AC-001 description: "Usuario puede crear proyectos con nombre, fechas y presupuesto" status: Pending test_reference: "test/projects/project.controller.e2e-spec.ts:35" - id: AC-002 description: "Proyecto se vincula automáticamente a cuenta analítica" status: Pending test_reference: "src/modules/projects/services/project.service.spec.ts:72" - id: AC-003 description: "Sistema calcula progreso basado en tareas completadas" status: Pending test_reference: "test/projects/project.controller.e2e-spec.ts:108" business_rules: - id: RN-001 description: "Fecha de fin debe ser posterior a fecha de inicio" implementation: "src/modules/projects/dto/create-project.dto.ts:@IsDateAfter('start_date')" test_reference: "src/modules/projects/services/project.service.spec.ts:95" - id: RN-002 description: "Proyecto crea automáticamente cuenta analítica asociada" implementation: "src/modules/projects/services/project.service.ts:create()" test_reference: "src/modules/projects/services/project.service.spec.ts:122" - id: RN-003 description: "Progreso se calcula como: tareas completadas / total tareas" implementation: "src/modules/projects/services/project.service.ts:calculateProgress()" test_reference: "src/modules/projects/services/project.service.spec.ts:148" dependencies: rf_dependencies: - RF-MGN-008-001 module_dependencies: - MGN-001 - MGN-008 external_dependencies: - name: "@nestjs/common" version: "^10.0.0" - name: "ant-design" version: "^5.0.0" - rf_id: RF-MGN-011-002 rf_title: "Gestión de Tareas (Kanban)" rf_file: "requerimientos-funcionales/mgn-011/RF-MGN-011-002-gestión-de-tareas-kanban.md" priority: P1 story_points: 13 et_backend: file: "especificaciones-tecnicas/backend/mgn-011/ET-BACKEND-MGN-011-002-gestión-de-tareas-kanban.md" endpoints: - method: POST path: /api/v1/projects/tasks description: "Crear nueva tarea" - method: GET path: /api/v1/projects/tasks description: "Listar todas las tareas" - method: GET path: /api/v1/projects/tasks/:id description: "Obtener tarea por ID" - method: PUT path: /api/v1/projects/tasks/:id description: "Actualizar tarea" - method: POST path: /api/v1/projects/tasks/:id/move description: "Mover tarea a otro stage" services: - name: "TaskService" file: "src/modules/projects/services/task.service.ts" methods: - create - findAll - findOne - update - move - validateBusinessRules controllers: - name: "TaskController" file: "src/modules/projects/controllers/task.controller.ts" dtos: - name: "CreateTaskDto" file: "src/modules/projects/dto/create-task.dto.ts" - name: "UpdateTaskDto" file: "src/modules/projects/dto/update-task.dto.ts" - name: "TaskResponseDto" file: "src/modules/projects/dto/task-response.dto.ts" - name: "MoveTaskDto" file: "src/modules/projects/dto/move-task.dto.ts" et_frontend: file: "especificaciones-tecnicas/frontend/mgn-011/ET-FRONTEND-MGN-011-002-gestión-de-tareas-kanban.md" routes: - path: "/projects/:projectId/tasks" component: "ProjectTasksPage" - path: "/projects/:projectId/tasks/kanban" component: "TasksKanbanPage" - path: "/projects/tasks/:id" component: "ViewTaskPage" components: - name: "TasksKanban" file: "src/widgets/tasks-kanban/ui/TasksKanban.tsx" type: widget - name: "CreateTaskForm" file: "src/features/create-task/ui/CreateTaskForm.tsx" type: feature - name: "TaskCard" file: "src/entities/task/ui/TaskCard.tsx" type: entity - name: "TaskPage" file: "src/pages/projects/TaskPage.tsx" type: page api_client: - name: "taskApi" file: "src/entities/task/api/task.api.ts" methods: - getAll - getById - create - update - move state_management: - name: "useTaskStore" file: "src/entities/task/model/task.store.ts" type: zustand - name: "useTasks" file: "src/entities/task/api/task.queries.ts" type: react-query database_tables: - schema: projects table: tasks file: "database-design/schemas/projects-schema-ddl.sql" operations: - SELECT - INSERT - UPDATE - DELETE (soft) indices: - idx_tasks_tenant_id - idx_tasks_project_id - idx_tasks_stage_id - idx_tasks_assigned_to rls_policy: tenant_isolation_tasks - schema: projects table: task_stages file: "database-design/schemas/projects-schema-ddl.sql" operations: - SELECT - INSERT - UPDATE indices: - idx_task_stages_project_id rls_policy: tenant_isolation_task_stages tests: backend: unit_tests: - file: "src/modules/projects/services/task.service.spec.ts" test_cases: - "should create task with valid data" - "should assign task to user" - "should move task between stages" - "should find all tasks for project" - "should update task successfully" integration_tests: - file: "test/projects/task.controller.e2e-spec.ts" test_cases: - "POST /api/v1/projects/tasks should create task" - "GET /api/v1/projects/tasks should return all tasks" - "GET /api/v1/projects/tasks/:id should return task" - "PUT /api/v1/projects/tasks/:id should update task" - "POST /api/v1/projects/tasks/:id/move should move task" - "should enforce tenant isolation" - "should require authentication" - "should check permissions" frontend: component_tests: - file: "src/widgets/tasks-kanban/ui/TasksKanban.test.tsx" test_cases: - "should render kanban board" - "should drag and drop tasks" - "should show task details" - file: "src/features/create-task/ui/CreateTaskForm.test.tsx" test_cases: - "should validate required fields" - "should submit valid form" - "should show error messages" e2e_tests: - file: "e2e/projects/tasks.spec.ts" test_cases: - "should create task successfully" - "should drag task to new stage" - "should assign task to user" - "should enforce permissions" acceptance_criteria: - id: AC-001 description: "Usuario puede crear tareas dentro de proyectos" status: Pending test_reference: "test/projects/task.controller.e2e-spec.ts:42" - id: AC-002 description: "Tareas se visualizan en formato Kanban" status: Pending test_reference: "src/widgets/tasks-kanban/ui/TasksKanban.test.tsx:78" - id: AC-003 description: "Tareas se mueven entre stages con drag & drop" status: Pending test_reference: "e2e/projects/tasks.spec.ts:115" business_rules: - id: RN-001 description: "Tarea debe estar asociada a un proyecto" implementation: "src/modules/projects/services/task.service.ts:validateProject()" test_reference: "src/modules/projects/services/task.service.spec.ts:102" - id: RN-002 description: "Al mover tarea, se registra actividad automáticamente" implementation: "src/modules/projects/services/task.service.ts:move()" test_reference: "src/modules/projects/services/task.service.spec.ts:128" - id: RN-003 description: "Tarea completada actualiza progreso del proyecto" implementation: "src/modules/projects/services/task.service.ts:updateProgress()" test_reference: "src/modules/projects/services/task.service.spec.ts:155" dependencies: rf_dependencies: - RF-MGN-011-001 module_dependencies: - MGN-001 - MGN-014 external_dependencies: - name: "@dnd-kit/core" version: "^6.0.0" - rf_id: RF-MGN-011-003 rf_title: "Milestones (Hitos)" rf_file: "requerimientos-funcionales/mgn-011/RF-MGN-011-003-milestones-hitos.md" priority: P1 story_points: 3 et_backend: file: "especificaciones-tecnicas/backend/mgn-011/ET-BACKEND-MGN-011-003-milestones-hitos.md" endpoints: - method: POST path: /api/v1/projects/milestones description: "Crear milestone" - method: GET path: /api/v1/projects/milestones description: "Listar milestones" - method: GET path: /api/v1/projects/milestones/:id description: "Obtener milestone por ID" - method: PUT path: /api/v1/projects/milestones/:id description: "Actualizar milestone" - method: POST path: /api/v1/projects/milestones/:id/complete description: "Marcar milestone como completado" services: - name: "MilestoneService" file: "src/modules/projects/services/milestone.service.ts" methods: - create - findAll - findOne - update - complete - validateBusinessRules controllers: - name: "MilestoneController" file: "src/modules/projects/controllers/milestone.controller.ts" dtos: - name: "CreateMilestoneDto" file: "src/modules/projects/dto/create-milestone.dto.ts" - name: "UpdateMilestoneDto" file: "src/modules/projects/dto/update-milestone.dto.ts" - name: "MilestoneResponseDto" file: "src/modules/projects/dto/milestone-response.dto.ts" - name: "FilterMilestoneDto" file: "src/modules/projects/dto/filter-milestone.dto.ts" et_frontend: file: "especificaciones-tecnicas/frontend/mgn-011/ET-FRONTEND-MGN-011-003-milestones-hitos.md" routes: - path: "/projects/:projectId/milestones" component: "MilestonesPage" - path: "/projects/milestones/:id" component: "ViewMilestonePage" components: - name: "MilestonesTimeline" file: "src/widgets/milestones-timeline/ui/MilestonesTimeline.tsx" type: widget - name: "CreateMilestoneForm" file: "src/features/create-milestone/ui/CreateMilestoneForm.tsx" type: feature - name: "MilestoneCard" file: "src/entities/milestone/ui/MilestoneCard.tsx" type: entity - name: "MilestonePage" file: "src/pages/projects/MilestonePage.tsx" type: page api_client: - name: "milestoneApi" file: "src/entities/milestone/api/milestone.api.ts" methods: - getAll - getById - create - update - complete state_management: - name: "useMilestoneStore" file: "src/entities/milestone/model/milestone.store.ts" type: zustand - name: "useMilestones" file: "src/entities/milestone/api/milestone.queries.ts" type: react-query database_tables: - schema: projects table: milestones file: "database-design/schemas/projects-schema-ddl.sql" operations: - SELECT - INSERT - UPDATE - DELETE (soft) indices: - idx_milestones_tenant_id - idx_milestones_project_id - idx_milestones_target_date rls_policy: tenant_isolation_milestones tests: backend: unit_tests: - file: "src/modules/projects/services/milestone.service.spec.ts" test_cases: - "should create milestone with valid data" - "should validate target date" - "should complete milestone successfully" - "should find all milestones for project" - "should update milestone successfully" integration_tests: - file: "test/projects/milestone.controller.e2e-spec.ts" test_cases: - "POST /api/v1/projects/milestones should create milestone" - "GET /api/v1/projects/milestones should return all milestones" - "GET /api/v1/projects/milestones/:id should return milestone" - "PUT /api/v1/projects/milestones/:id should update milestone" - "POST /api/v1/projects/milestones/:id/complete should complete" - "should enforce tenant isolation" - "should require authentication" - "should check permissions" frontend: component_tests: - file: "src/widgets/milestones-timeline/ui/MilestonesTimeline.test.tsx" test_cases: - "should render timeline" - "should show completed milestones" - "should highlight overdue milestones" - file: "src/features/create-milestone/ui/CreateMilestoneForm.test.tsx" test_cases: - "should validate required fields" - "should submit valid form" - "should show error messages" e2e_tests: - file: "e2e/projects/milestones.spec.ts" test_cases: - "should create milestone successfully" - "should complete milestone" - "should view milestones timeline" - "should enforce permissions" acceptance_criteria: - id: AC-001 description: "Usuario puede crear milestones con nombre y fecha objetivo" status: Pending test_reference: "test/projects/milestone.controller.e2e-spec.ts:45" - id: AC-002 description: "Milestones se visualizan en timeline del proyecto" status: Pending test_reference: "src/widgets/milestones-timeline/ui/MilestonesTimeline.test.tsx:82" - id: AC-003 description: "Sistema alerta sobre milestones próximos o vencidos" status: Pending test_reference: "e2e/projects/milestones.spec.ts:118" business_rules: - id: RN-001 description: "Milestone debe estar asociado a un proyecto" implementation: "src/modules/projects/services/milestone.service.ts:validateProject()" test_reference: "src/modules/projects/services/milestone.service.spec.ts:108" - id: RN-002 description: "Fecha objetivo debe estar dentro del rango del proyecto" implementation: "src/modules/projects/services/milestone.service.ts:validateDate()" test_reference: "src/modules/projects/services/milestone.service.spec.ts:135" - id: RN-003 description: "Completar milestone actualiza progreso del proyecto" implementation: "src/modules/projects/services/milestone.service.ts:complete()" test_reference: "src/modules/projects/services/milestone.service.spec.ts:162" dependencies: rf_dependencies: - RF-MGN-011-001 module_dependencies: - MGN-001 - MGN-014 external_dependencies: - name: "@nestjs/common" version: "^10.0.0" - rf_id: RF-MGN-011-004 rf_title: "Timesheet de Proyectos" rf_file: "requerimientos-funcionales/mgn-011/RF-MGN-011-004-timesheet-de-proyectos.md" priority: P1 story_points: 8 et_backend: file: "especificaciones-tecnicas/backend/mgn-011/ET-BACKEND-MGN-011-004-timesheet-de-proyectos.md" endpoints: - method: POST path: /api/v1/projects/timesheet-entries description: "Registrar entrada de timesheet" - method: GET path: /api/v1/projects/timesheet-entries description: "Listar entradas de timesheet" - method: GET path: /api/v1/projects/timesheet-entries/:id description: "Obtener entrada por ID" - method: PUT path: /api/v1/projects/timesheet-entries/:id description: "Actualizar entrada" - method: GET path: /api/v1/projects/timesheet-entries/report description: "Reporte de timesheet" services: - name: "TimesheetService" file: "src/modules/projects/services/timesheet.service.ts" methods: - create - findAll - findOne - update - getReport - validateBusinessRules controllers: - name: "TimesheetController" file: "src/modules/projects/controllers/timesheet.controller.ts" dtos: - name: "CreateTimesheetEntryDto" file: "src/modules/projects/dto/create-timesheet-entry.dto.ts" - name: "UpdateTimesheetEntryDto" file: "src/modules/projects/dto/update-timesheet-entry.dto.ts" - name: "TimesheetEntryResponseDto" file: "src/modules/projects/dto/timesheet-entry-response.dto.ts" - name: "TimesheetReportDto" file: "src/modules/projects/dto/timesheet-report.dto.ts" et_frontend: file: "especificaciones-tecnicas/frontend/mgn-011/ET-FRONTEND-MGN-011-004-timesheet-de-proyectos.md" routes: - path: "/projects/timesheet" component: "TimesheetPage" - path: "/projects/timesheet/report" component: "TimesheetReportPage" components: - name: "TimesheetGrid" file: "src/widgets/timesheet-grid/ui/TimesheetGrid.tsx" type: widget - name: "CreateTimesheetEntry" file: "src/features/create-timesheet-entry/ui/CreateTimesheetEntry.tsx" type: feature - name: "TimesheetCard" file: "src/entities/timesheet/ui/TimesheetCard.tsx" type: entity - name: "TimesheetPage" file: "src/pages/projects/TimesheetPage.tsx" type: page api_client: - name: "timesheetApi" file: "src/entities/timesheet/api/timesheet.api.ts" methods: - getAll - getById - create - update - getReport state_management: - name: "useTimesheetStore" file: "src/entities/timesheet/model/timesheet.store.ts" type: zustand - name: "useTimesheet" file: "src/entities/timesheet/api/timesheet.queries.ts" type: react-query database_tables: - schema: projects table: timesheet_entries file: "database-design/schemas/projects-schema-ddl.sql" operations: - SELECT - INSERT - UPDATE - DELETE (soft) indices: - idx_timesheet_entries_tenant_id - idx_timesheet_entries_project_id - idx_timesheet_entries_task_id - idx_timesheet_entries_user_id - idx_timesheet_entries_date rls_policy: tenant_isolation_timesheet_entries tests: backend: unit_tests: - file: "src/modules/projects/services/timesheet.service.spec.ts" test_cases: - "should create timesheet entry" - "should validate hours range" - "should generate timesheet report" - "should find all entries for user" - "should update entry successfully" integration_tests: - file: "test/projects/timesheet.controller.e2e-spec.ts" test_cases: - "POST /api/v1/projects/timesheet-entries should create entry" - "GET /api/v1/projects/timesheet-entries should return entries" - "GET /api/v1/projects/timesheet-entries/:id should return entry" - "PUT /api/v1/projects/timesheet-entries/:id should update entry" - "GET /api/v1/projects/timesheet-entries/report should return report" - "should enforce tenant isolation" - "should require authentication" - "should check permissions" frontend: component_tests: - file: "src/widgets/timesheet-grid/ui/TimesheetGrid.test.tsx" test_cases: - "should render timesheet grid" - "should edit inline hours" - "should calculate weekly totals" - file: "src/features/create-timesheet-entry/ui/CreateTimesheetEntry.test.tsx" test_cases: - "should validate hours" - "should submit valid entry" - "should show error messages" e2e_tests: - file: "e2e/projects/timesheet.spec.ts" test_cases: - "should log hours successfully" - "should view timesheet report" - "should edit timesheet entry" - "should enforce permissions" acceptance_criteria: - id: AC-001 description: "Usuario puede registrar horas trabajadas en proyectos/tareas" status: Pending test_reference: "test/projects/timesheet.controller.e2e-spec.ts:48" - id: AC-002 description: "Timesheet se visualiza en formato grid semanal" status: Pending test_reference: "src/widgets/timesheet-grid/ui/TimesheetGrid.test.tsx:85" - id: AC-003 description: "Reportes muestran horas por proyecto/tarea/usuario" status: Pending test_reference: "e2e/projects/timesheet.spec.ts:122" business_rules: - id: RN-001 description: "Horas registradas deben estar entre 0 y 24" implementation: "src/modules/projects/dto/create-timesheet-entry.dto.ts:@Min(0) @Max(24)" test_reference: "src/modules/projects/services/timesheet.service.spec.ts:112" - id: RN-002 description: "Entrada debe estar asociada a proyecto o tarea" implementation: "src/modules/projects/services/timesheet.service.ts:validateRelation()" test_reference: "src/modules/projects/services/timesheet.service.spec.ts:138" - id: RN-003 description: "Horas facturables generan líneas analíticas automáticamente" implementation: "src/modules/projects/services/timesheet.service.ts:createAnalyticLine()" test_reference: "src/modules/projects/services/timesheet.service.spec.ts:165" dependencies: rf_dependencies: - RF-MGN-011-001 - RF-MGN-011-002 - RF-MGN-008-002 module_dependencies: - MGN-001 - MGN-008 external_dependencies: - name: "@nestjs/common" version: "^10.0.0" - name: "date-fns" version: "^2.30.0" - rf_id: RF-MGN-011-005 rf_title: "Vista Gantt de Proyectos" rf_file: "requerimientos-funcionales/mgn-011/RF-MGN-011-005-vista-gantt-de-proyectos.md" priority: P2 story_points: 8 et_backend: file: "especificaciones-tecnicas/backend/mgn-011/ET-BACKEND-MGN-011-005-vista-gantt-de-proyectos.md" endpoints: - method: GET path: /api/v1/projects/:id/gantt description: "Obtener datos para vista Gantt" - method: PUT path: /api/v1/projects/tasks/:id/reschedule description: "Reprogramar tarea" - method: POST path: /api/v1/projects/tasks/:id/dependencies description: "Crear dependencia entre tareas" - method: GET path: /api/v1/projects/:id/critical-path description: "Calcular ruta crítica" services: - name: "GanttService" file: "src/modules/projects/services/gantt.service.ts" methods: - getGanttData - rescheduleTask - createDependency - calculateCriticalPath controllers: - name: "GanttController" file: "src/modules/projects/controllers/gantt.controller.ts" dtos: - name: "RescheduleTaskDto" file: "src/modules/projects/dto/reschedule-task.dto.ts" - name: "CreateDependencyDto" file: "src/modules/projects/dto/create-dependency.dto.ts" - name: "GanttDataResponseDto" file: "src/modules/projects/dto/gantt-data-response.dto.ts" et_frontend: file: "especificaciones-tecnicas/frontend/mgn-011/ET-FRONTEND-MGN-011-005-vista-gantt-de-proyectos.md" routes: - path: "/projects/:id/gantt" component: "ProjectGanttPage" components: - name: "GanttChart" file: "src/widgets/gantt-chart/ui/GanttChart.tsx" type: widget - name: "GanttControls" file: "src/features/gantt-controls/ui/GanttControls.tsx" type: feature - name: "TaskDependencies" file: "src/entities/task/ui/TaskDependencies.tsx" type: entity - name: "GanttPage" file: "src/pages/projects/GanttPage.tsx" type: page api_client: - name: "ganttApi" file: "src/entities/gantt/api/gantt.api.ts" methods: - getGanttData - rescheduleTask - createDependency - getCriticalPath state_management: - name: "useGanttStore" file: "src/entities/gantt/model/gantt.store.ts" type: zustand database_tables: - schema: projects table: tasks file: "database-design/schemas/projects-schema-ddl.sql" operations: - SELECT - UPDATE indices: - idx_tasks_start_date - idx_tasks_end_date rls_policy: tenant_isolation_tasks - schema: projects table: task_dependencies file: "database-design/schemas/projects-schema-ddl.sql" operations: - SELECT - INSERT - DELETE indices: - idx_task_dependencies_task_id - idx_task_dependencies_depends_on_id rls_policy: tenant_isolation_task_dependencies tests: backend: unit_tests: - file: "src/modules/projects/services/gantt.service.spec.ts" test_cases: - "should generate Gantt data" - "should reschedule task with dependencies" - "should create task dependency" - "should calculate critical path" - "should validate circular dependencies" integration_tests: - file: "test/projects/gantt.controller.e2e-spec.ts" test_cases: - "GET /api/v1/projects/:id/gantt should return Gantt data" - "PUT /api/v1/projects/tasks/:id/reschedule should reschedule" - "POST /api/v1/projects/tasks/:id/dependencies should create dependency" - "GET /api/v1/projects/:id/critical-path should return path" - "should prevent circular dependencies" - "should enforce tenant isolation" - "should require authentication" - "should check permissions" frontend: component_tests: - file: "src/widgets/gantt-chart/ui/GanttChart.test.tsx" test_cases: - "should render Gantt chart" - "should drag to reschedule task" - "should show task dependencies" - file: "src/features/gantt-controls/ui/GanttControls.test.tsx" test_cases: - "should zoom in/out" - "should filter by resource" - "should highlight critical path" e2e_tests: - file: "e2e/projects/gantt.spec.ts" test_cases: - "should display Gantt chart" - "should reschedule task by dragging" - "should create task dependency" - "should enforce permissions" acceptance_criteria: - id: AC-001 description: "Usuario puede visualizar proyecto en vista Gantt" status: Pending test_reference: "test/projects/gantt.controller.e2e-spec.ts:52" - id: AC-002 description: "Tareas pueden reprogramarse con drag & drop" status: Pending test_reference: "src/widgets/gantt-chart/ui/GanttChart.test.tsx:88" - id: AC-003 description: "Sistema calcula y muestra ruta crítica" status: Pending test_reference: "e2e/projects/gantt.spec.ts:125" business_rules: - id: RN-001 description: "Dependencias no deben formar ciclos" implementation: "src/modules/projects/services/gantt.service.ts:validateNoCycles()" test_reference: "src/modules/projects/services/gantt.service.spec.ts:115" - id: RN-002 description: "Reprogramar tarea ajusta automáticamente dependientes" implementation: "src/modules/projects/services/gantt.service.ts:rescheduleTask()" test_reference: "src/modules/projects/services/gantt.service.spec.ts:142" - id: RN-003 description: "Ruta crítica identifica secuencia de tareas sin holgura" implementation: "src/modules/projects/services/gantt.service.ts:calculateCriticalPath()" test_reference: "src/modules/projects/services/gantt.service.spec.ts:168" dependencies: rf_dependencies: - RF-MGN-011-001 - RF-MGN-011-002 module_dependencies: - MGN-001 external_dependencies: - name: "dhtmlx-gantt" version: "^8.0.0" coverage: rf_to_et_backend: 100% rf_to_et_frontend: 100% rf_to_database: 100% rf_to_tests: 100% backend_tests: 100% frontend_tests: 100% statistics: total_endpoints: 25 total_components: 20 total_tables: 5 total_test_cases: 100 estimated_duration_sprints: 2