erp-core/orchestration/02-planeacion/PLAN-EJECUCION-COMPLETO-2026-01-10.md
rckrdmrd 0086695b4c
Some checks failed
ERP Core CI / Backend Lint (push) Has been cancelled
ERP Core CI / Backend Unit Tests (push) Has been cancelled
ERP Core CI / Backend Integration Tests (push) Has been cancelled
ERP Core CI / Frontend Lint (push) Has been cancelled
ERP Core CI / Frontend Unit Tests (push) Has been cancelled
ERP Core CI / Frontend E2E Tests (push) Has been cancelled
ERP Core CI / Database DDL Validation (push) Has been cancelled
ERP Core CI / Backend Build (push) Has been cancelled
ERP Core CI / Frontend Build (push) Has been cancelled
ERP Core CI / CI Success (push) Has been cancelled
Performance Tests / Lighthouse CI (push) Has been cancelled
Performance Tests / Bundle Size Analysis (push) Has been cancelled
Performance Tests / k6 Load Tests (push) Has been cancelled
Performance Tests / Performance Summary (push) Has been cancelled
[SIMCO-V38] feat: Actualizar a SIMCO v3.8.0 + cambios backend
- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8
- Actualizaciones en modulos CRM y OpenAPI

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 08:53:05 -06:00

30 KiB

PLAN DE EJECUCION COMPLETO - CIERRE DE GAPS

ID: PLAN-EXEC-COMPLETO-2026-01-10 Fecha: 2026-01-10 Version: 1.0 Sistema: SIMCO v3.5 + CAPVED Orquestador: Claude Code - Opus 4.5 Fase: P (Planeacion) - FASE 3


1. CONTEXTO

1.1 Vinculacion

Campo Valor
Proyecto erp-core
Documento Base ANALISIS-COMPLETO-PROYECTO-2026-01-10.md
Epic EPIC-CIERRE-GAPS-2026-01
Total GAPS 33
Story Points 220 SP

1.2 Principios SIMCO Aplicables

  • @OP_BACKEND - Operaciones de backend
  • @OP_FRONTEND - Operaciones de frontend
  • @OP_DATABASE - Operaciones de base de datos
  • @VALIDAR - Validacion obligatoria
  • @DOC-PRIMERO - Documentacion primero
  • @TAREA - Gestion de tareas

2. ESTRUCTURA DEL PLAN

2.1 Fases de Ejecucion

SPRINT 1 (GAPS CRITICOS)     -> 45 SP  -> Prioridad: CRITICA
SPRINT 2 (GAPS ALTOS)        -> 47 SP  -> Prioridad: ALTA
SPRINT 3 (GAPS MEDIOS - P1)  -> 45 SP  -> Prioridad: MEDIA
SPRINT 4 (GAPS MEDIOS - P2)  -> 40 SP  -> Prioridad: MEDIA
SPRINT 5 (GAPS BAJOS + E2E)  -> 43 SP  -> Prioridad: BAJA

2.2 Orden de Ejecucion por Sprint

Siempre: DATABASE -> BACKEND -> FRONTEND -> TESTS -> VALIDACION

3. SPRINT 1: GAPS CRITICOS (45 SP)

3.1 Objetivos

  • Desbloquear funcionalidad core del ERP
  • Seeds de datos maestros criticos
  • Corregir calculo de impuestos
  • Habilitar API services criticos en frontend

3.2 Tareas en Orden de Ejecucion

3.2.1 DATABASE - Seeds Criticos (24 SP)

ID Tarea Archivo Dependencias SP
S1-DB-01 Crear seed de secuencias seeds/05-sequences.sql 04-users.sql 5
S1-DB-02 Crear seed de categorias producto seeds/06-product-categories.sql 05-sequences.sql 3
S1-DB-03 Crear seed financiero (COA, journals, taxes) seeds/07-financial-setup.sql 05-sequences.sql 8
S1-DB-04 Crear seed de inventario (warehouses, locations) seeds/08-inventory-setup.sql 06-product-categories.sql 3
S1-DB-05 Crear seed de productos seeds/09-products.sql 08-inventory-setup.sql 5

Detalle S1-DB-01: Secuencias

-- Archivo: seeds/05-sequences.sql
-- Contenido requerido:
INSERT INTO core.sequences (id, tenant_id, company_id, code, name, prefix, suffix, padding, next_number, step) VALUES
-- Ventas
('seq-so', 'tenant-1', 'company-1', 'SO', 'Sales Order', 'SO', '', 6, 1, 1),
('seq-qt', 'tenant-1', 'company-1', 'QT', 'Quotation', 'QT', '', 6, 1, 1),
-- Compras
('seq-po', 'tenant-1', 'company-1', 'PO', 'Purchase Order', 'PO', '', 6, 1, 1),
('seq-rfq', 'tenant-1', 'company-1', 'RFQ', 'Request for Quotation', 'RFQ', '', 6, 1, 1),
-- Financiero
('seq-inv', 'tenant-1', 'company-1', 'INV', 'Invoice', 'INV', '', 6, 1, 1),
('seq-bill', 'tenant-1', 'company-1', 'BILL', 'Vendor Bill', 'BILL', '', 6, 1, 1),
('seq-pay', 'tenant-1', 'company-1', 'PAY', 'Payment', 'PAY', '', 6, 1, 1),
('seq-je', 'tenant-1', 'company-1', 'JE', 'Journal Entry', 'JE', '', 6, 1, 1),
-- Inventario
('seq-pick', 'tenant-1', 'company-1', 'PICK', 'Picking', 'PICK', '', 6, 1, 1),
('seq-adj', 'tenant-1', 'company-1', 'ADJ', 'Stock Adjustment', 'ADJ', '', 6, 1, 1),
('seq-lot', 'tenant-1', 'company-1', 'LOT', 'Lot/Batch', 'LOT', '', 6, 1, 1),
-- Productos
('seq-prod', 'tenant-1', 'company-1', 'PROD', 'Product', 'PROD', '', 6, 1, 1),
-- Partners
('seq-cust', 'tenant-1', 'company-1', 'CUST', 'Customer', 'CUST', '', 6, 1, 1),
('seq-vend', 'tenant-1', 'company-1', 'VEND', 'Vendor', 'VEND', '', 6, 1, 1),
-- HR
('seq-emp', 'tenant-1', 'company-1', 'EMP', 'Employee', 'EMP', '', 6, 1, 1);

Detalle S1-DB-03: Financial Setup

-- Archivo: seeds/07-financial-setup.sql
-- Contenido requerido:

-- 1. Account Types (10 registros)
INSERT INTO financial.account_types (id, code, name, type, internal_group, balance_type) VALUES
('at-asset', 'ASSET', 'Activos', 'asset', 'asset', 'debit'),
('at-liability', 'LIABILITY', 'Pasivos', 'liability', 'liability', 'credit'),
('at-equity', 'EQUITY', 'Capital', 'equity', 'equity', 'credit'),
('at-revenue', 'REVENUE', 'Ingresos', 'revenue', 'income', 'credit'),
('at-expense', 'EXPENSE', 'Gastos', 'expense', 'expense', 'debit'),
('at-cogs', 'COGS', 'Costo de Ventas', 'expense', 'expense', 'debit'),
('at-bank', 'BANK', 'Bancos', 'asset', 'bank', 'debit'),
('at-cash', 'CASH', 'Efectivo', 'asset', 'cash', 'debit'),
('at-receivable', 'AR', 'Cuentas por Cobrar', 'asset', 'receivable', 'debit'),
('at-payable', 'AP', 'Cuentas por Pagar', 'liability', 'payable', 'credit');

-- 2. Chart of Accounts (50+ registros)
-- Ver detalle en archivo completo

-- 3. Journals (5 registros)
INSERT INTO financial.journals (id, tenant_id, company_id, code, name, type, default_account_id) VALUES
('jnl-sales', 'tenant-1', 'company-1', 'SAL', 'Ventas', 'sale', 'acc-sales'),
('jnl-purchase', 'tenant-1', 'company-1', 'PUR', 'Compras', 'purchase', 'acc-purchases'),
('jnl-bank', 'tenant-1', 'company-1', 'BNK', 'Banco', 'bank', 'acc-bank'),
('jnl-cash', 'tenant-1', 'company-1', 'CSH', 'Caja', 'cash', 'acc-cash'),
('jnl-misc', 'tenant-1', 'company-1', 'MISC', 'Miscelaneos', 'general', null);

-- 4. Fiscal Year (2 registros)
INSERT INTO financial.fiscal_years (id, tenant_id, company_id, name, date_from, date_to, state) VALUES
('fy-2025', 'tenant-1', 'company-1', 'Ejercicio 2025', '2025-01-01', '2025-12-31', 'open'),
('fy-2026', 'tenant-1', 'company-1', 'Ejercicio 2026', '2026-01-01', '2026-12-31', 'open');

-- 5. Fiscal Periods (24 registros - 2 anios x 12 meses)
-- Ver detalle en archivo completo

-- 6. Taxes (5 registros)
INSERT INTO financial.taxes (id, tenant_id, company_id, name, type_tax_use, amount_type, amount, tax_group_id, active) VALUES
('tax-iva-16', 'tenant-1', 'company-1', 'IVA 16%', 'sale', 'percent', 16.00, 'tg-iva', true),
('tax-iva-16-purchase', 'tenant-1', 'company-1', 'IVA 16% Compras', 'purchase', 'percent', 16.00, 'tg-iva', true),
('tax-iva-0', 'tenant-1', 'company-1', 'IVA 0%', 'sale', 'percent', 0.00, 'tg-iva', true),
('tax-isr-ret', 'tenant-1', 'company-1', 'Retencion ISR 10%', 'purchase', 'percent', -10.00, 'tg-isr', true),
('tax-iva-ret', 'tenant-1', 'company-1', 'Retencion IVA 2/3', 'purchase', 'percent', -10.67, 'tg-iva', true);

-- 7. Payment Terms (5 registros)
INSERT INTO financial.payment_terms (id, tenant_id, company_id, name, note, line_ids) VALUES
('pt-immediate', 'tenant-1', 'company-1', 'Pago Inmediato', 'Pago al contado', null),
('pt-15d', 'tenant-1', 'company-1', '15 Dias', 'Pago a 15 dias', null),
('pt-30d', 'tenant-1', 'company-1', '30 Dias', 'Pago a 30 dias', null),
('pt-60d', 'tenant-1', 'company-1', '60 Dias', 'Pago a 60 dias', null),
('pt-90d', 'tenant-1', 'company-1', '90 Dias', 'Pago a 90 dias', null);

-- 8. Payment Methods (5 registros)
INSERT INTO financial.payment_methods (id, tenant_id, company_id, name, code, payment_type) VALUES
('pm-cash', 'tenant-1', 'company-1', 'Efectivo', 'CASH', 'inbound'),
('pm-transfer', 'tenant-1', 'company-1', 'Transferencia', 'TRANSFER', 'inbound'),
('pm-check', 'tenant-1', 'company-1', 'Cheque', 'CHECK', 'inbound'),
('pm-card', 'tenant-1', 'company-1', 'Tarjeta', 'CARD', 'inbound'),
('pm-outbound', 'tenant-1', 'company-1', 'Pago a Proveedores', 'OUTBOUND', 'outbound');

3.2.2 BACKEND - Correccion de TODOs Criticos (8 SP)

ID Tarea Archivo Linea Descripcion SP
S1-BE-01 Implementar calculo de impuestos sales/quotations.service.ts 416 Calcular taxes con TaxesService 4
S1-BE-02 Implementar calculo de impuestos sales/orders.service.ts 466 Calcular taxes con TaxesService 4

Detalle S1-BE-01: Implementacion de Calculo de Impuestos

// Archivo: backend/src/modules/sales/quotations.service.ts
// Linea 416 - Reemplazar:
// const amountTax = 0; // TODO: Calculate taxes

// Por:
private async calculateLineTaxes(line: QuotationLine, tenantId: string): Promise<number> {
  if (!line.taxIds || line.taxIds.length === 0) {
    return 0;
  }

  const taxes = await this.taxesService.findByIds(line.taxIds, tenantId);
  let taxAmount = 0;

  for (const tax of taxes) {
    if (tax.amountType === 'percent') {
      taxAmount += (line.priceSubtotal * tax.amount) / 100;
    } else if (tax.amountType === 'fixed') {
      taxAmount += tax.amount * line.productUomQty;
    }
  }

  return taxAmount;
}

// Y actualizar recalculateTotals:
async recalculateTotals(quotationId: string, tenantId: string): Promise<void> {
  const quotation = await this.findById(quotationId, tenantId);

  let amountUntaxed = 0;
  let amountTax = 0;

  for (const line of quotation.lines) {
    amountUntaxed += line.priceSubtotal;
    amountTax += await this.calculateLineTaxes(line, tenantId);
  }

  const amountTotal = amountUntaxed + amountTax;

  await this.quotationRepository.update(quotationId, {
    amountUntaxed,
    amountTax,
    amountTotal,
    updatedAt: new Date(),
  });
}

3.2.3 FRONTEND - API Services Criticos (13 SP)

ID Tarea Archivo Endpoints SP
S1-FE-01 Crear Products API service features/products/api/products.api.ts 8 3
S1-FE-02 Crear Inventory API service features/inventory/api/inventory.api.ts 25 5
S1-FE-03 Crear Sales API service features/sales/api/sales.api.ts 20 5

Detalle S1-FE-01: Products API Service

// Archivo: frontend/src/features/products/api/products.api.ts
import { axiosInstance } from '@/services/api/axios-instance';
import { API_ENDPOINTS } from '@/shared/constants/api-endpoints';
import { Product, CreateProductDto, UpdateProductDto, PaginatedResponse } from '../types';

export const productsApi = {
  getAll: async (params?: Record<string, any>): Promise<PaginatedResponse<Product>> => {
    const response = await axiosInstance.get(API_ENDPOINTS.INVENTORY.PRODUCTS, { params });
    return response.data;
  },

  getById: async (id: string): Promise<Product> => {
    const response = await axiosInstance.get(`${API_ENDPOINTS.INVENTORY.PRODUCTS}/${id}`);
    return response.data;
  },

  getStock: async (id: string): Promise<any> => {
    const response = await axiosInstance.get(`${API_ENDPOINTS.INVENTORY.PRODUCTS}/${id}/stock`);
    return response.data;
  },

  create: async (data: CreateProductDto): Promise<Product> => {
    const response = await axiosInstance.post(API_ENDPOINTS.INVENTORY.PRODUCTS, data);
    return response.data;
  },

  update: async (id: string, data: UpdateProductDto): Promise<Product> => {
    const response = await axiosInstance.put(`${API_ENDPOINTS.INVENTORY.PRODUCTS}/${id}`, data);
    return response.data;
  },

  delete: async (id: string): Promise<void> => {
    await axiosInstance.delete(`${API_ENDPOINTS.INVENTORY.PRODUCTS}/${id}`);
  },

  getByCategory: async (categoryId: string): Promise<Product[]> => {
    const response = await axiosInstance.get(API_ENDPOINTS.INVENTORY.PRODUCTS, {
      params: { categoryId }
    });
    return response.data.data;
  },

  search: async (query: string): Promise<Product[]> => {
    const response = await axiosInstance.get(API_ENDPOINTS.INVENTORY.PRODUCTS, {
      params: { search: query }
    });
    return response.data.data;
  },
};

Detalle S1-FE-02: Inventory API Service

// Archivo: frontend/src/features/inventory/api/inventory.api.ts
import { axiosInstance } from '@/services/api/axios-instance';
import { API_ENDPOINTS } from '@/shared/constants/api-endpoints';

export const inventoryApi = {
  // Warehouses
  warehouses: {
    getAll: async (params?: Record<string, any>) => {
      const response = await axiosInstance.get(API_ENDPOINTS.INVENTORY.WAREHOUSES, { params });
      return response.data;
    },
    getById: async (id: string) => {
      const response = await axiosInstance.get(`${API_ENDPOINTS.INVENTORY.WAREHOUSES}/${id}`);
      return response.data;
    },
    getStock: async (id: string) => {
      const response = await axiosInstance.get(`${API_ENDPOINTS.INVENTORY.WAREHOUSES}/${id}/stock`);
      return response.data;
    },
    create: async (data: any) => {
      const response = await axiosInstance.post(API_ENDPOINTS.INVENTORY.WAREHOUSES, data);
      return response.data;
    },
    update: async (id: string, data: any) => {
      const response = await axiosInstance.put(`${API_ENDPOINTS.INVENTORY.WAREHOUSES}/${id}`, data);
      return response.data;
    },
    delete: async (id: string) => {
      await axiosInstance.delete(`${API_ENDPOINTS.INVENTORY.WAREHOUSES}/${id}`);
    },
  },

  // Locations
  locations: {
    getAll: async (params?: Record<string, any>) => {
      const response = await axiosInstance.get(API_ENDPOINTS.INVENTORY.LOCATIONS, { params });
      return response.data;
    },
    getById: async (id: string) => {
      const response = await axiosInstance.get(`${API_ENDPOINTS.INVENTORY.LOCATIONS}/${id}`);
      return response.data;
    },
    getStock: async (id: string) => {
      const response = await axiosInstance.get(`${API_ENDPOINTS.INVENTORY.LOCATIONS}/${id}/stock`);
      return response.data;
    },
    create: async (data: any) => {
      const response = await axiosInstance.post(API_ENDPOINTS.INVENTORY.LOCATIONS, data);
      return response.data;
    },
    update: async (id: string, data: any) => {
      const response = await axiosInstance.put(`${API_ENDPOINTS.INVENTORY.LOCATIONS}/${id}`, data);
      return response.data;
    },
  },

  // Stock Moves
  stockMoves: {
    getAll: async (params?: Record<string, any>) => {
      const response = await axiosInstance.get(API_ENDPOINTS.INVENTORY.STOCK_MOVES, { params });
      return response.data;
    },
    getById: async (id: string) => {
      const response = await axiosInstance.get(`${API_ENDPOINTS.INVENTORY.STOCK_MOVES}/${id}`);
      return response.data;
    },
  },

  // Pickings
  pickings: {
    getAll: async (params?: Record<string, any>) => {
      const response = await axiosInstance.get(API_ENDPOINTS.INVENTORY.PICKINGS, { params });
      return response.data;
    },
    getById: async (id: string) => {
      const response = await axiosInstance.get(`${API_ENDPOINTS.INVENTORY.PICKINGS}/${id}`);
      return response.data;
    },
    create: async (data: any) => {
      const response = await axiosInstance.post(API_ENDPOINTS.INVENTORY.PICKINGS, data);
      return response.data;
    },
    confirm: async (id: string) => {
      const response = await axiosInstance.post(`${API_ENDPOINTS.INVENTORY.PICKINGS}/${id}/confirm`);
      return response.data;
    },
    validate: async (id: string) => {
      const response = await axiosInstance.post(`${API_ENDPOINTS.INVENTORY.PICKINGS}/${id}/validate`);
      return response.data;
    },
    cancel: async (id: string) => {
      const response = await axiosInstance.post(`${API_ENDPOINTS.INVENTORY.PICKINGS}/${id}/cancel`);
      return response.data;
    },
  },

  // Lots
  lots: {
    getAll: async (params?: Record<string, any>) => {
      const response = await axiosInstance.get(API_ENDPOINTS.INVENTORY.LOTS, { params });
      return response.data;
    },
    getById: async (id: string) => {
      const response = await axiosInstance.get(`${API_ENDPOINTS.INVENTORY.LOTS}/${id}`);
      return response.data;
    },
    create: async (data: any) => {
      const response = await axiosInstance.post(API_ENDPOINTS.INVENTORY.LOTS, data);
      return response.data;
    },
    getMovements: async (id: string) => {
      const response = await axiosInstance.get(`${API_ENDPOINTS.INVENTORY.LOTS}/${id}/movements`);
      return response.data;
    },
  },

  // Adjustments
  adjustments: {
    getAll: async (params?: Record<string, any>) => {
      const response = await axiosInstance.get(API_ENDPOINTS.INVENTORY.ADJUSTMENTS, { params });
      return response.data;
    },
    getById: async (id: string) => {
      const response = await axiosInstance.get(`${API_ENDPOINTS.INVENTORY.ADJUSTMENTS}/${id}`);
      return response.data;
    },
    create: async (data: any) => {
      const response = await axiosInstance.post(API_ENDPOINTS.INVENTORY.ADJUSTMENTS, data);
      return response.data;
    },
    confirm: async (id: string) => {
      const response = await axiosInstance.post(`${API_ENDPOINTS.INVENTORY.ADJUSTMENTS}/${id}/confirm`);
      return response.data;
    },
    validate: async (id: string) => {
      const response = await axiosInstance.post(`${API_ENDPOINTS.INVENTORY.ADJUSTMENTS}/${id}/validate`);
      return response.data;
    },
    cancel: async (id: string) => {
      const response = await axiosInstance.post(`${API_ENDPOINTS.INVENTORY.ADJUSTMENTS}/${id}/cancel`);
      return response.data;
    },
  },
};

3.3 Validacion Sprint 1

Tipo Comando Criterio Exito
Seeds ./scripts/recreate-database.sh --force 0 errores
Build Backend npm run build 0 errores
Lint Backend npm run lint 0 errores
Tests Backend npm test PASS all
Build Frontend npm run build 0 errores

4. SPRINT 2: GAPS ALTOS (47 SP)

4.1 Objetivos

  • Implementar email service productivo
  • Completar permission middleware
  • Tests para Sales y Purchases
  • Tests para Audit (compliance)
  • Seeds de listas de precio

4.2 Tareas en Orden de Ejecucion

4.2.1 DATABASE - Seeds Adicionales (6 SP)

ID Tarea Archivo SP
S2-DB-01 Crear seed de listas de precio seeds/10-pricelists.sql 3
S2-DB-02 Actualizar seed de partners con direcciones seeds/11-sample-partners.sql 3

4.2.2 BACKEND - Correccion de TODOs Altos (15 SP)

ID Tarea Archivo Linea SP
S2-BE-01 Implementar email service productivo shared/services/email.service.ts 66 5
S2-BE-02 Implementar envio de email cotizacion sales/quotations.service.ts 478 3
S2-BE-03 Completar permission middleware shared/middleware/auth.middleware.ts 81 5
S2-BE-04 Integrar notifications con scheduler reports/scheduler.service.ts 360 2

Detalle S2-BE-01: Email Service Productivo

// Archivo: backend/src/shared/services/email.service.ts
// Linea 66 - Implementar SendGrid/Nodemailer/AWS SES

import { Injectable } from '@nestjs/common';
import * as nodemailer from 'nodemailer';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class EmailService {
  private transporter: nodemailer.Transporter;

  constructor(private configService: ConfigService) {
    const emailProvider = this.configService.get<string>('EMAIL_PROVIDER');

    if (emailProvider === 'smtp') {
      this.transporter = nodemailer.createTransport({
        host: this.configService.get<string>('SMTP_HOST'),
        port: this.configService.get<number>('SMTP_PORT'),
        secure: this.configService.get<boolean>('SMTP_SECURE'),
        auth: {
          user: this.configService.get<string>('SMTP_USER'),
          pass: this.configService.get<string>('SMTP_PASSWORD'),
        },
      });
    } else if (emailProvider === 'sendgrid') {
      // SendGrid implementation
      this.transporter = nodemailer.createTransport({
        service: 'SendGrid',
        auth: {
          user: 'apikey',
          pass: this.configService.get<string>('SENDGRID_API_KEY'),
        },
      });
    }
  }

  async sendEmail(options: {
    to: string;
    subject: string;
    html: string;
    attachments?: any[];
  }): Promise<void> {
    const from = this.configService.get<string>('EMAIL_FROM');

    if (this.configService.get<string>('NODE_ENV') === 'development') {
      console.log('[EMAIL-DEV] Would send:', { to: options.to, subject: options.subject });
      return;
    }

    await this.transporter.sendMail({
      from,
      to: options.to,
      subject: options.subject,
      html: options.html,
      attachments: options.attachments,
    });
  }

  async sendQuotationEmail(quotation: any, recipientEmail: string): Promise<void> {
    const html = this.generateQuotationHtml(quotation);
    await this.sendEmail({
      to: recipientEmail,
      subject: `Cotizacion ${quotation.name} - ${quotation.companyName}`,
      html,
    });
  }

  private generateQuotationHtml(quotation: any): string {
    return `
      <h1>Cotizacion ${quotation.name}</h1>
      <p>Estimado ${quotation.partnerName},</p>
      <p>Adjunto encontrara nuestra cotizacion por un monto de ${quotation.currencySymbol}${quotation.amountTotal.toFixed(2)}.</p>
      <p>Quedo a sus ordenes.</p>
    `;
  }
}

4.2.3 BACKEND - Tests Criticos (26 SP)

ID Tarea Archivo Tests Estimados SP
S2-BE-05 Tests orders.service sales/__tests__/orders.service.spec.ts 35 5
S2-BE-06 Tests quotations.service sales/__tests__/quotations.service.spec.ts 35 5
S2-BE-07 Tests pricelists.service sales/__tests__/pricelists.service.spec.ts 20 3
S2-BE-08 Tests purchases.service purchases/__tests__/purchases.service.spec.ts 30 5
S2-BE-09 Tests audit.service audit/__tests__/audit.service.spec.ts 25 3
S2-BE-10 Tests access-logs.service audit/__tests__/access-logs.service.spec.ts 20 3
S2-BE-11 Tests security-events.service audit/__tests__/security-events.service.spec.ts 15 2

4.3 Validacion Sprint 2

Tipo Comando Criterio Exito
Seeds ./scripts/recreate-database.sh --force 0 errores
Tests Backend npm test -- --coverage >50% coverage
Email Test Manual verification Email received

5. SPRINT 3: GAPS MEDIOS - Parte 1 (45 SP)

5.1 Objetivos

  • Tests para HR, Reports, Projects
  • Frontend API services para Projects, CRM

5.2 Tareas

5.2.1 BACKEND - Tests (35 SP)

ID Tarea Archivo Tests SP
S3-BE-01 Tests employees.service hr/__tests__/employees.service.spec.ts 30 5
S3-BE-02 Tests contracts.service hr/__tests__/contracts.service.spec.ts 25 3
S3-BE-03 Tests leaves.service hr/__tests__/leaves.service.spec.ts 25 3
S3-BE-04 Tests payslips.service hr/__tests__/payslips.service.spec.ts 35 5
S3-BE-05 Tests departments.service hr/__tests__/departments.service.spec.ts 15 2
S3-BE-06 Tests reports.service reports/__tests__/reports.service.spec.ts 20 3
S3-BE-07 Tests dashboards.service reports/__tests__/dashboards.service.spec.ts 20 3
S3-BE-08 Tests report-builder.service reports/__tests__/report-builder.service.spec.ts 20 3
S3-BE-09 Tests projects.service projects/__tests__/projects.service.spec.ts 25 3
S3-BE-10 Tests tasks.service projects/__tests__/tasks.service.spec.ts 25 3
S3-BE-11 Tests timesheets.service projects/__tests__/timesheets.service.spec.ts 20 2

5.2.2 FRONTEND - API Services (10 SP)

ID Tarea Archivo SP
S3-FE-01 Crear Projects API service features/projects/api/projects.api.ts 5
S3-FE-02 Crear CRM API service features/crm/api/crm.api.ts 5

6. SPRINT 4: GAPS MEDIOS - Parte 2 (40 SP)

6.1 Objetivos

  • Tests para Financial, Inventory, CRM
  • Frontend API services para HR, Purchases

6.2 Tareas

6.2.1 BACKEND - Tests (30 SP)

ID Tarea Archivo Tests SP
S4-BE-01 Tests taxes.service financial/__tests__/taxes.service.spec.ts 25 3
S4-BE-02 Tests journals.service financial/__tests__/journals.service.spec.ts 20 3
S4-BE-03 Tests fiscalPeriods.service financial/__tests__/fiscalPeriods.service.spec.ts 20 3
S4-BE-04 Tests reconcile-models.service financial/__tests__/reconcile-models.service.spec.ts 25 5
S4-BE-05 Tests warehouses.service inventory/__tests__/warehouses.service.spec.ts 20 3
S4-BE-06 Tests locations.service inventory/__tests__/locations.service.spec.ts 20 3
S4-BE-07 Tests pickings.service inventory/__tests__/pickings.service.spec.ts 30 5
S4-BE-08 Tests leads.service crm/__tests__/leads.service.spec.ts 25 3
S4-BE-09 Tests opportunities.service crm/__tests__/opportunities.service.spec.ts 25 2

6.2.2 FRONTEND - API Services (10 SP)

ID Tarea Archivo SP
S4-FE-01 Crear HR API service features/hr/api/hr.api.ts 5
S4-FE-02 Crear Purchases API service features/purchases/api/purchases.api.ts 5

7. SPRINT 5: GAPS BAJOS + E2E (43 SP)

7.1 Objetivos

  • Tests restantes (System, Shared, minor services)
  • Tests E2E con Playwright
  • Seeds opcionales (HR, CRM, Projects)

7.2 Tareas

7.2.1 BACKEND - Tests Restantes (14 SP)

ID Tarea Archivo Tests SP
S5-BE-01 Tests token.service auth/__tests__/token.service.spec.ts 20 3
S5-BE-02 Tests base.service shared/__tests__/base.service.spec.ts 15 2
S5-BE-03 Tests email.service shared/__tests__/email.service.spec.ts 15 2
S5-BE-04 Tests cache.service shared/__tests__/cache.service.spec.ts 15 2
S5-BE-05 Tests notifications.service system/__tests__/notifications.service.spec.ts 15 2
S5-BE-06 Tests companies.service companies/__tests__/companies.service.spec.ts 15 3

7.2.2 E2E TESTS (21 SP)

ID Tarea Archivo Flujos SP
S5-E2E-01 Setup Playwright e2e/playwright.config.ts - 3
S5-E2E-02 Auth E2E tests e2e/tests/auth.spec.ts Login, Register, MFA 5
S5-E2E-03 Sales E2E tests e2e/tests/sales.spec.ts Quote to Order 5
S5-E2E-04 Inventory E2E tests e2e/tests/inventory.spec.ts Stock movement 5
S5-E2E-05 Financial E2E tests e2e/tests/financial.spec.ts Invoice to Payment 3

7.2.3 DATABASE - Seeds Opcionales (8 SP)

ID Tarea Archivo SP
S5-DB-01 Seeds HR demo seeds/demo/hr-demo.sql 3
S5-DB-02 Seeds CRM demo seeds/demo/crm-demo.sql 2
S5-DB-03 Seeds Projects demo seeds/demo/projects-demo.sql 3

8. RESUMEN DEL PLAN

8.1 Por Sprint

Sprint Foco Story Points Archivos
Sprint 1 GAPS Criticos 45 SP 11 archivos
Sprint 2 GAPS Altos 47 SP 13 archivos
Sprint 3 GAPS Medios P1 45 SP 13 archivos
Sprint 4 GAPS Medios P2 40 SP 11 archivos
Sprint 5 GAPS Bajos + E2E 43 SP 14 archivos
TOTAL - 220 SP 62 archivos

8.2 Por Tipo de Trabajo

Tipo Story Points % Total
Database Seeds 38 SP 17%
Backend TODOs 23 SP 10%
Backend Tests 96 SP 44%
Frontend APIs 41 SP 19%
E2E Tests 21 SP 10%

8.3 Cobertura Final Esperada

Metrica Actual Esperado Post-Plan
Servicios con tests 39.5% 95%+
Tablas con seeds 14.1% 80%+
Frontend API coverage 60% 100%
E2E flows 0 4 flujos criticos

9. DEPENDENCIAS CRITICAS

9.1 Dependencias entre Tareas

S1-DB-01 (sequences)
    └── S1-DB-02 (categories)
    └── S1-DB-03 (financial)
         └── S1-BE-01 (tax calculation)
         └── S1-BE-02 (tax calculation)
    └── S1-DB-04 (inventory)
         └── S1-DB-05 (products)
              └── S1-FE-01 (products api)
              └── S1-FE-02 (inventory api)

S2-BE-01 (email service)
    └── S2-BE-02 (quotation email)

S2-BE-03 (permission middleware)
    └── Depends on: roles/permissions seeds (existentes)

9.2 Archivos con Multiples Dependencias

Archivo Dependencias Impacto si Falla
seeds/05-sequences.sql Todos los documentos CRITICO
seeds/07-financial-setup.sql Invoices, Payments, Taxes CRITICO
sales/quotations.service.ts Taxes, Email, Partners ALTO
shared/services/email.service.ts Quotations, Reports, Notifications ALTO

10. CRITERIOS DE ACEPTACION POR SPRINT

Sprint 1

  • Seeds ejecutan sin errores en recreate-database.sh
  • COA tiene 50+ cuentas correctamente jerarquizadas
  • Impuestos calculan correctamente en quotations y orders
  • Frontend Products API consume endpoint correctamente
  • Frontend Inventory API consume endpoints correctamente
  • Frontend Sales API consume endpoints correctamente

Sprint 2

  • Email service envia correos en produccion
  • Permission middleware valida permisos desde DB
  • Tests Sales tienen >80% coverage
  • Tests Purchases tienen >80% coverage
  • Tests Audit tienen >80% coverage

Sprint 3

  • Tests HR tienen >80% coverage
  • Tests Reports tienen >80% coverage
  • Tests Projects tienen >80% coverage
  • Frontend Projects API funcional
  • Frontend CRM API funcional

Sprint 4

  • Tests Financial adicionales >80% coverage
  • Tests Inventory adicionales >80% coverage
  • Tests CRM tienen >80% coverage
  • Frontend HR API funcional
  • Frontend Purchases API funcional

Sprint 5

  • Cobertura total backend >90%
  • E2E Auth flow pasa
  • E2E Sales flow pasa
  • E2E Inventory flow pasa
  • E2E Financial flow pasa

11. RIESGOS Y MITIGACION

Riesgo Probabilidad Impacto Mitigacion
Tax calculation compleja MEDIA ALTO Usar TaxesService existente, solo integrar
Email provider config BAJA MEDIO Usar nodemailer con SMTP generico
Tests E2E inestables ALTA MEDIO Usar fixtures, evitar datos dinamicos
Seeds conflicto IDs MEDIA ALTO Usar UUIDs generados, no hardcoded
Dependencias circulares BAJA ALTO Revisar imports antes de implementar

12. DOCUMENTACION REQUERIDA

Por Sprint

Sprint Documentos a Actualizar
Sprint 1 MASTER_INVENTORY.yml, REPORTE-EJECUCION-S1.md
Sprint 2 MASTER_INVENTORY.yml, REPORTE-EJECUCION-S2.md
Sprint 3 MASTER_INVENTORY.yml, REPORTE-EJECUCION-S3.md
Sprint 4 MASTER_INVENTORY.yml, REPORTE-EJECUCION-S4.md
Sprint 5 MASTER_INVENTORY.yml, REPORTE-FINAL.md

Documento generado por: ORQUESTADOR (Claude Code Opus 4.5) Sistema: SIMCO v3.5 + CAPVED Fase: P (Planeacion) - COMPLETADA Siguiente fase: V (Validacion de Plan)