# FASE 6: PLAN REFINADO FINAL DE IMPLEMENTACION **Fecha:** 2026-01-10 **Objetivo:** Plan final de implementacion para cerrar GAPS identificados **Estado:** COMPLETADO **Basado en:** FASE1-5 documentos de analisis --- ## 1. RESUMEN EJECUTIVO ### 1.1 Estado Actual del Proyecto | Categoria | Estado | Porcentaje | |-----------|--------|------------| | Seeds de Base de Datos | COMPLETO | 100% | | Backend TODOs (Tax Calc) | COMPLETO | 100% | | Backend Tests | COMPLETO | 55 archivos | | Email Service | COMPLETO | 100% | | Frontend API Services | PARCIAL | 43% (3/7) | ### 1.2 GAPS a Resolver | Gap ID | Descripcion | Prioridad | Esfuerzo | |--------|-------------|-----------|----------| | GAP-FE-01 | purchases.api.ts | CRITICA | ~200 lineas | | GAP-FE-02 | projects.api.ts | ALTA | ~180 lineas | | GAP-FE-03 | crm.api.ts | ALTA | ~250 lineas | | GAP-FE-04 | hr.api.ts | ALTA | ~400 lineas | **Total a implementar:** ~1,030 lineas de codigo TypeScript --- ## 2. PLAN DE EJECUCION DETALLADO ### 2.1 GAP-FE-01: purchases.api.ts **Archivo:** `frontend/src/features/purchases/api/purchases.api.ts` **Endpoints:** 23 **Sub-APIs:** 2 (purchaseOrdersApi, rfqsApi) #### Contenido a Implementar: ```typescript /** * Purchases API Module * * Provides API functions for: * - Purchase Orders: CRUD + confirm, cancel * - RFQs: CRUD + lines + workflow (send, responded, accept, reject, cancel) */ import { apiClient } from '@/lib/api-client'; // ========== PURCHASE ORDERS ========== export const purchaseOrdersApi = { getAll: (params?: { page?: number; limit?: number; status?: string }) => apiClient.get('/api/purchases', { params }), getById: (id: string) => apiClient.get(`/api/purchases/${id}`), create: (data: CreatePurchaseOrderDto) => apiClient.post('/api/purchases', data), update: (id: string, data: UpdatePurchaseOrderDto) => apiClient.put(`/api/purchases/${id}`, data), delete: (id: string) => apiClient.delete(`/api/purchases/${id}`), confirm: (id: string) => apiClient.post(`/api/purchases/${id}/confirm`), cancel: (id: string) => apiClient.post(`/api/purchases/${id}/cancel`), }; // ========== RFQs (Request for Quotation) ========== export const rfqsApi = { getAll: (params?: { page?: number; limit?: number; status?: string }) => apiClient.get('/api/purchases/rfqs', { params }), getById: (id: string) => apiClient.get(`/api/purchases/rfqs/${id}`), create: (data: CreateRfqDto) => apiClient.post('/api/purchases/rfqs', data), update: (id: string, data: UpdateRfqDto) => apiClient.put(`/api/purchases/rfqs/${id}`, data), delete: (id: string) => apiClient.delete(`/api/purchases/rfqs/${id}`), // Lines addLine: (id: string, data: CreateRfqLineDto) => apiClient.post(`/api/purchases/rfqs/${id}/lines`, data), updateLine: (id: string, lineId: string, data: UpdateRfqLineDto) => apiClient.put(`/api/purchases/rfqs/${id}/lines/${lineId}`, data), removeLine: (id: string, lineId: string) => apiClient.delete(`/api/purchases/rfqs/${id}/lines/${lineId}`), // Workflow send: (id: string) => apiClient.post(`/api/purchases/rfqs/${id}/send`), markResponded: (id: string) => apiClient.post(`/api/purchases/rfqs/${id}/responded`), accept: (id: string) => apiClient.post(`/api/purchases/rfqs/${id}/accept`), reject: (id: string) => apiClient.post(`/api/purchases/rfqs/${id}/reject`), cancel: (id: string) => apiClient.post(`/api/purchases/rfqs/${id}/cancel`), }; // Types (para referencia) interface CreatePurchaseOrderDto { partner_id: string; company_id: string; order_date: string; lines?: CreatePurchaseOrderLineDto[]; } interface CreateRfqDto { partner_id: string; company_id: string; validity_date?: string; } ``` --- ### 2.2 GAP-FE-02: projects.api.ts **Archivo:** `frontend/src/features/projects/api/projects.api.ts` **Endpoints:** 24 **Sub-APIs:** 3 (projectsApi, tasksApi, timesheetsApi) #### Contenido a Implementar: ```typescript /** * Projects API Module * * Provides API functions for: * - Projects: CRUD + stats, tasks, timesheets * - Tasks: CRUD + move, assign * - Timesheets: CRUD + submit, approve, reject */ import { apiClient } from '@/lib/api-client'; // ========== PROJECTS ========== export const projectsApi = { getAll: (params?: { page?: number; limit?: number; status?: string }) => apiClient.get('/api/projects', { params }), getById: (id: string) => apiClient.get(`/api/projects/${id}`), create: (data: CreateProjectDto) => apiClient.post('/api/projects', data), update: (id: string, data: UpdateProjectDto) => apiClient.put(`/api/projects/${id}`, data), delete: (id: string) => apiClient.delete(`/api/projects/${id}`), getStats: (id: string) => apiClient.get(`/api/projects/${id}/stats`), getTasks: (id: string) => apiClient.get(`/api/projects/${id}/tasks`), getTimesheets: (id: string) => apiClient.get(`/api/projects/${id}/timesheets`), }; // ========== TASKS ========== export const tasksApi = { getAll: (params?: { page?: number; limit?: number; project_id?: string }) => apiClient.get('/api/projects/tasks/all', { params }), getById: (id: string) => apiClient.get(`/api/projects/tasks/${id}`), create: (data: CreateTaskDto) => apiClient.post('/api/projects/tasks', data), update: (id: string, data: UpdateTaskDto) => apiClient.put(`/api/projects/tasks/${id}`, data), delete: (id: string) => apiClient.delete(`/api/projects/tasks/${id}`), move: (id: string, data: { stage_id: string }) => apiClient.post(`/api/projects/tasks/${id}/move`, data), assign: (id: string, data: { user_id: string }) => apiClient.post(`/api/projects/tasks/${id}/assign`, data), }; // ========== TIMESHEETS ========== export const timesheetsApi = { getAll: (params?: { page?: number; limit?: number }) => apiClient.get('/api/projects/timesheets/all', { params }), getMine: (params?: { page?: number; limit?: number }) => apiClient.get('/api/projects/timesheets/me', { params }), getPending: (params?: { page?: number; limit?: number }) => apiClient.get('/api/projects/timesheets/pending', { params }), getById: (id: string) => apiClient.get(`/api/projects/timesheets/${id}`), create: (data: CreateTimesheetDto) => apiClient.post('/api/projects/timesheets', data), update: (id: string, data: UpdateTimesheetDto) => apiClient.put(`/api/projects/timesheets/${id}`, data), delete: (id: string) => apiClient.delete(`/api/projects/timesheets/${id}`), submit: (id: string) => apiClient.post(`/api/projects/timesheets/${id}/submit`), approve: (id: string) => apiClient.post(`/api/projects/timesheets/${id}/approve`), reject: (id: string, data?: { reason?: string }) => apiClient.post(`/api/projects/timesheets/${id}/reject`, data), }; ``` --- ### 2.3 GAP-FE-03: crm.api.ts **Archivo:** `frontend/src/features/crm/api/crm.api.ts` **Endpoints:** 32 **Sub-APIs:** 7 (leadsApi, opportunitiesApi, pipelineApi, leadStagesApi, opportunityStagesApi, lostReasonsApi, tagsApi) #### Contenido a Implementar (extracto): ```typescript /** * CRM API Module * * Provides API functions for: * - Leads: CRUD + move, convert, lost * - Opportunities: CRUD + move, won, lost, quote * - Pipeline, Stages, Lost Reasons, Tags */ import { apiClient } from '@/lib/api-client'; export const leadsApi = { /* 8 metodos */ }; export const opportunitiesApi = { /* 9 metodos */ }; export const pipelineApi = { /* 1 metodo */ }; export const leadStagesApi = { /* 4 metodos */ }; export const opportunityStagesApi = { /* 4 metodos */ }; export const lostReasonsApi = { /* 4 metodos */ }; export const tagsApi = { /* 5 metodos */ }; ``` --- ### 2.4 GAP-FE-04: hr.api.ts **Archivo:** `frontend/src/features/hr/api/hr.api.ts` **Endpoints:** 62 **Sub-APIs:** 14 (employeesApi, departmentsApi, positionsApi, contractsApi, leaveTypesApi, leavesApi, skillTypesApi, skillsApi, skillLevelsApi, employeeSkillsApi, expenseSheetsApi, expensesApi, payslipStructuresApi, payslipsApi) #### Contenido a Implementar (extracto): ```typescript /** * HR API Module * * Provides API functions for: * - Employees, Departments, Positions, Contracts * - Leave Types, Leaves * - Skills (Types, Skills, Levels, Employee Skills) * - Expenses (Sheets, Expenses) * - Payslips (Structures, Payslips, Lines) */ import { apiClient } from '@/lib/api-client'; export const employeesApi = { /* 9 metodos */ }; export const departmentsApi = { /* 5 metodos */ }; export const positionsApi = { /* 4 metodos */ }; export const contractsApi = { /* 8 metodos */ }; export const leaveTypesApi = { /* 4 metodos */ }; export const leavesApi = { /* 9 metodos */ }; export const skillTypesApi = { /* 5 metodos */ }; export const skillsApi = { /* 5 metodos */ }; export const skillLevelsApi = { /* 4 metodos */ }; export const employeeSkillsApi = { /* 4 metodos */ }; export const expenseSheetsApi = { /* 8 metodos */ }; export const expensesApi = { /* 5 metodos */ }; export const payslipStructuresApi = { /* 5 metodos */ }; export const payslipsApi = { /* 12 metodos */ }; ``` --- ## 3. ESTRUCTURA DE CARPETAS A CREAR ### 3.1 Carpetas Nuevas Requeridas ``` frontend/src/features/ ├── purchases/ # CREAR │ └── api/ │ └── purchases.api.ts ├── projects/ # CREAR │ └── api/ │ └── projects.api.ts ├── crm/ # CREAR │ └── api/ │ └── crm.api.ts └── hr/ # CREAR └── api/ └── hr.api.ts ``` --- ## 4. ORDEN DE EJECUCION ### 4.1 Secuencia de Implementacion | Paso | Archivo | Dependencias | Verificacion | |------|---------|--------------|--------------| | 1 | Crear carpeta purchases/api/ | - | ls -la | | 2 | Crear purchases.api.ts | apiClient | tsc --noEmit | | 3 | Crear carpeta projects/api/ | - | ls -la | | 4 | Crear projects.api.ts | apiClient | tsc --noEmit | | 5 | Crear carpeta crm/api/ | - | ls -la | | 6 | Crear crm.api.ts | apiClient | tsc --noEmit | | 7 | Crear carpeta hr/api/ | - | ls -la | | 8 | Crear hr.api.ts | apiClient | tsc --noEmit | | 9 | Verificar build | - | npm run build | --- ## 5. CRITERIOS DE ACEPTACION ### 5.1 Por Cada Archivo API: - [ ] Archivo creado en ubicacion correcta - [ ] Import de apiClient correcto - [ ] Todos los endpoints mapeados - [ ] Metodos CRUD implementados - [ ] Metodos de workflow implementados - [ ] Tipos basicos definidos (o importados) - [ ] Sin errores de TypeScript - [ ] Export nombrado de todas las sub-APIs ### 5.2 Validacion Final: - [ ] npm run build sin errores - [ ] Todas las APIs exportadas correctamente - [ ] Documentacion generada (opcional) --- ## 6. ROLLBACK PLAN En caso de errores: 1. Los archivos son nuevos, no modifican codigo existente 2. Si build falla, revisar imports y tipos 3. Cada archivo es independiente, se puede revertir individualmente --- ## 7. METRICAS DE EXITO | Metrica | Antes | Despues | Cambio | |---------|-------|---------|--------| | Frontend API Services | 3/7 (43%) | 7/7 (100%) | +57% | | Lineas de codigo API | ~800 | ~1,830 | +1,030 | | Endpoints cubiertos | ~50 | ~191 | +141 | --- ## 8. APROBACION PARA EJECUCION **Este plan esta listo para ejecucion.** Todos los analisis previos confirman: - Backend modules existen y tienen todos los endpoints - Patron de implementacion validado contra codigo existente - Dependencias identificadas y disponibles - Estructura de carpetas definida - Orden de ejecucion establecido --- **Generado por:** Claude Code - Opus 4.5 **Fase CAPVED:** Refinamiento **Documento:** FASE6-PLAN-REFINADO-FINAL.md