diff --git a/docs/README.md b/docs/README.md index 44363527..3b2bfc6a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,32 +2,52 @@ Este directorio reúne la documentación operativa y arquitectónica del ERP. -## Estructura actual +## Documentación vigente -```txt -docs/ - README.md - architecture/ - frontend/ - dev/ -``` - -## Documentos clave +### Arquitectura general - [Arquitectura de identity y companies](./architecture/identity-and-companies.md) - [Contexto tenant y `X-Company-Id`](./architecture/tenant-context.md) - [API de autenticación identity](./architecture/identity-auth-api.md) - [Estado de migración a identity](./architecture/identity-migration-status.md) - [Flujo frontend de auth y selección de empresa](./frontend/auth-and-company-selection.md) -- [Seed local de admin](./dev/seed-local-admin.sql) -- [SQL histórico de `customer_invoice_series`](./dev/customer-invoice-series.sql) -- [Migración desde `customer_invoice_series` a `document_series`](./document-series/migration-from-customer-invoice-series.md) + +### Document series + +- [README de `document-series`](./document-series/README.md) +- [Diseño de `document-series`](./document-series/document-series-design.md) +- [Validación manual de `document-series`](./document-series/manual-validation.md) + +### Customer-invoices / proformas + - [Contrato de series de proformas](./customer-invoices/proforma-series-contract.md) +- [Contrato de create de proformas](./customer-invoices/proforma-create-contract.md) +- [Tax config persistido en proformas](./customer-invoices/proforma-tax-config.md) + +### SQL operativos / runbooks vigentes + +- [DDL de series documentales en proformas](./customer-invoices/sql/add-proforma-document-series-columns.sql) +- [DDL de `tax_config` en proformas](./customer-invoices/sql/add-proforma-tax-config-columns.sql) +- [Validación de migración a `document_series`](./document-series/sql/validate-document-series-migration.sql) +- [Validación de `tax_config` en proformas](./customer-invoices/sql/validate-proforma-tax-config.sql) + +### Referencias de módulos + - [README de `modules/auth`](../modules/auth/README.md) - [README de `modules/identity`](../modules/identity/README.md) - [README de `modules/companies`](../modules/companies/README.md) - [README de `apps/web`](../apps/web/README.md) +## Histórico / migraciones transicionales + +- [Migración desde `customer_invoice_series` a `document_series`](./document-series/migration-from-customer-invoice-series.md) +- [Split histórico Proforma / IssuedInvoice](./customer-invoices/split-proformas-issued-invoices-migration.md) +- [InvoiceSeries legacy](./customer-invoices/invoice-series.md) +- [Drop manual de `customer_invoice_series`](./document-series/sql/drop-customer-invoice-series-legacy.sql) +- [SQL histórico de `customer_invoice_series`](./dev/customer-invoice-series.sql) +- [Runbooks SQL históricos de `customer-invoices`](./customer-invoices/sql/README.md) +- [Seed local de admin](./dev/seed-local-admin.sql) + ## Estado actual resumido - El backend nuevo usa `modules/identity` para autenticación, sesión y control de acceso a companies. @@ -42,3 +62,5 @@ docs/ - `GET /identity/companies` no es un endpoint válido del diseño actual. - `GET /account/companies` tampoco es un endpoint válido del diseño actual. - Las rutas tenant-scoped deben usar `Authorization` + `X-Company-Id`. +- `/document-series` es la API canónica de series documentales. +- `/catalogs/invoice-series` no es un endpoint activo. diff --git a/docs/customer-invoices/invoice-series.md b/docs/customer-invoices/invoice-series.md index c498ed21..29b090ef 100644 --- a/docs/customer-invoices/invoice-series.md +++ b/docs/customer-invoices/invoice-series.md @@ -19,6 +19,8 @@ customer_invoice_series Este contenido ya no describe el runtime activo del ERP. +No usar este documento para desarrollo nuevo. La referencia vigente es `docs/document-series/*`. + ## Alcance funcional `InvoiceSeries` representa la serie usada para numerar facturas emitidas de cliente. @@ -161,6 +163,9 @@ Por eso el SQL manual asociado a `customer_invoice_series` vive en: Ese archivo debe integrarse en el pipeline real de despliegue DB cuando exista. -## Frontend +## Sustitución vigente -No se ha tocado frontend como parte de esta decisión. +- API canónica: `/document-series` +- tabla canónica: `document_series` +- proformas: `proforma_series_code` y `target_invoice_series_code` +- SQL histórico de apoyo: `docs/dev/customer-invoice-series.sql` diff --git a/docs/customer-invoices/proforma-create-contract.md b/docs/customer-invoices/proforma-create-contract.md index 2e490c3f..008677cc 100644 --- a/docs/customer-invoices/proforma-create-contract.md +++ b/docs/customer-invoices/proforma-create-contract.md @@ -14,6 +14,7 @@ En create: - `tax_config` representa la configuracion fiscal persistida de cabecera - `taxes` representa impuestos realmente calculados desde lineas valoradas - `totals` representa importes realmente calculados desde lineas valoradas +- `tax_mode` por defecto es `single` ## Contrato funcional de create @@ -61,6 +62,7 @@ Notas: - `items` es opcional; si existe, puede ir vacio - no se usan defaults ocultos en Zod para disfrazar la intencion del request - si no se informa `tax_config`, el backend resuelve defaults iniciales y los persiste +- si el cliente cambia después, la proforma conserva su `tax_config` persistido ## Response esperada al crear sin lineas @@ -95,6 +97,7 @@ Adaptando nombres exactos al contrato publico actual: - `create` persiste tambien el `tax_config` resuelto - `update` permite anadir o editar lineas - al existir lineas valoradas, `update` recalcula `taxes` y `totals` +- `issue` genera la `issued_invoice` materializada usando `target_invoice_series_code` si existe y, si no, la default activa de `issued_invoice` ## Wording de UI diff --git a/docs/customer-invoices/proforma-series-contract.md b/docs/customer-invoices/proforma-series-contract.md index 1dcfc1a9..704bdb67 100644 --- a/docs/customer-invoices/proforma-series-contract.md +++ b/docs/customer-invoices/proforma-series-contract.md @@ -34,7 +34,9 @@ En proformas: - se permiten cambios comerciales - se permite cambiar `target_invoice_series_code` +- se permite cambiar `tax_config` - no se permite cambiar `proforma_series_code`, `document_series_id`, `proforma_number` ni `proforma_reference` +- la UI hidrata la configuracion fiscal desde `tax_config`, no desde `taxes` ### Editar approved @@ -51,13 +53,15 @@ En proformas: - create acepta `proforma_series_code` - create acepta `target_invoice_series_code` +- create puede aceptar `tax_config` - update acepta `target_invoice_series_code` +- update puede aceptar `tax_config` - el flujo nuevo ya no necesita `series` ### Responses - el backend emite `target_invoice_series_code` como nombre preferente -- `series` puede mantenerse solo como alias legacy de salida mientras existan consumidores antiguos +- `series` puede mantenerse solo como alias legacy/deprecated de salida mientras existan consumidores antiguos - `taxes` representa impuestos calculados a partir de lineas valoradas - `tax_config` representa la configuracion fiscal persistida de cabecera - `totals` representa importes calculados a partir de lineas valoradas diff --git a/docs/customer-invoices/proforma-tax-config.md b/docs/customer-invoices/proforma-tax-config.md index 330c8ead..1e675267 100644 --- a/docs/customer-invoices/proforma-tax-config.md +++ b/docs/customer-invoices/proforma-tax-config.md @@ -57,11 +57,17 @@ Los defaults del cliente solo se usan al crear la proforma y el resultado se per Fallback actual: +- `tax_mode`: `single` - IVA por defecto: `iva_21` - recargo de equivalencia: desactivado salvo indicacion explicita - retencion: desactivada salvo indicacion explicita - codigo de retencion por defecto si `uses_retention = true`: `retention_15` +Si el cliente cambia despues de crear la proforma: + +- no se reconstruye `tax_config` desde el cliente actual +- la proforma conserva su `tax_config` persistido + ## Regla de update `tax_config` se actualiza de forma parcial y se mergea sobre la configuracion persistida actual. diff --git a/docs/customer-invoices/split-proformas-issued-invoices-migration.md b/docs/customer-invoices/split-proformas-issued-invoices-migration.md index 3182f902..b711744b 100644 --- a/docs/customer-invoices/split-proformas-issued-invoices-migration.md +++ b/docs/customer-invoices/split-proformas-issued-invoices-migration.md @@ -1,5 +1,13 @@ # Split Proformas / Issued Invoices +Estado: historico / transicional. +No describe el runtime minimo vigente por si solo; la fuente operativa actual para proformas es la combinación de: + +- `docs/document-series/README.md` +- `docs/customer-invoices/proforma-series-contract.md` +- `docs/customer-invoices/proforma-create-contract.md` +- `docs/customer-invoices/proforma-tax-config.md` + Estado: diseno tecnico / fases 1A-1D + 2A-2B Estado del backend: persistencia V2 activada; integracion con `document-series` activa para numeracion nueva; sin ejecucion confirmada de migracion DB @@ -132,7 +140,7 @@ Preparar el esquema fisico para separar: ## Estado Fase 2D - el contrato publico de proformas ya soporta `target_invoice_series_code` en create y update -- `series` se mantiene como alias legacy temporal en requests +- `series` se mantiene como alias legacy temporal en responses - si `series` y `target_invoice_series_code` llegan a la vez con distinto valor, el request falla por validacion - las responses de proforma prefieren `target_invoice_series_code` - `series` se mantiene temporalmente en responses como alias legacy con el mismo valor @@ -880,15 +888,14 @@ Resultado esperado: ## Siguiente fase recomendada - confirmar `.env`/credenciales de una BD de desarrollo segura -- ejecutar `dev-split-proformas-issued-invoices.sql` -- ejecutar `validate-split-proformas-issued-invoices.sql` +- ejecutar solo los runbooks SQL que sigan siendo necesarios para el entorno real afectado - levantar el backend contra esa BD y validar `create`, `update`, `get`, `list` e `issue proforma` - validar numeracion de proformas V2 y asignacion de serie/numero de factura emitida - revisar la ruta `VerifactuRecord -> issued_invoice_id` ya con persistencia V2 activa ## Nota document-series -`customer-invoices` debe migrar progresivamente desde `CustomerInvoiceSeriesModel` hacia `document-series`. Desde la Fase 2A: +`customer-invoices` ya migró funcionalmente desde `CustomerInvoiceSeriesModel` hacia `document-series`. Como nota histórica de Fase 2A: - `issued_invoice` ya asigna numeración nueva mediante `document-series` - `proforma` ya asigna referencia nueva mediante `document-series` diff --git a/docs/customer-invoices/sql/README.md b/docs/customer-invoices/sql/README.md index 83d9c083..bf7aa9c5 100644 --- a/docs/customer-invoices/sql/README.md +++ b/docs/customer-invoices/sql/README.md @@ -1,21 +1,32 @@ # SQL Customer Invoices -## Fase 1D +## Estado -Archivos de esta fase: +Este directorio mezcla SQL vigentes de soporte con SQL historicos/transicionales. + +## SQL vigentes + +- `add-proforma-document-series-columns.sql` +- `add-proforma-tax-config-columns.sql` +- `fix-proforma-series-semantics.sql` +- `validate-proforma-tax-config.sql` + +## SQL históricos / transicionales - `dev-split-proformas-issued-invoices.sql` - `validate-split-proformas-issued-invoices.sql` -## Orden recomendado en desarrollo +Estos archivos no deben tratarse como el camino normal de entornos nuevos salvo que exista un escenario legacy concreto que los requiera. + +## Orden recomendado en desarrollo para el estado vigente 1. Verificar que la BD objetivo es inequívocamente de desarrollo. 2. Hacer backup o confirmar que los datos son descartables. -3. Ejecutar `dev-split-proformas-issued-invoices.sql`. -4. Ejecutar `validate-split-proformas-issued-invoices.sql`. +3. Ejecutar el DDL vigente que falte para `proformas`. +4. Ejecutar las validaciones SQL vigentes. 5. Levantar backend V2 y validar flujos funcionales. -## Propiedades del script de desarrollo +## Propiedades de los scripts históricos de split - Crea tablas con `CREATE TABLE IF NOT EXISTS`. - Añade `verifactu_records.issued_invoice_id` con `ALTER TABLE ... ADD COLUMN IF NOT EXISTS`. diff --git a/docs/customer-invoices/sql/dev-split-proformas-issued-invoices.sql b/docs/customer-invoices/sql/dev-split-proformas-issued-invoices.sql index eb2f2057..4b9e094b 100644 --- a/docs/customer-invoices/sql/dev-split-proformas-issued-invoices.sql +++ b/docs/customer-invoices/sql/dev-split-proformas-issued-invoices.sql @@ -1,3 +1,6 @@ +-- Estado: HISTORICO / TRANSICIONAL. +-- No ejecutar en entornos nuevos. +-- Sustituido por: DDL/validaciones especificas vigentes en este directorio y por los contratos actuales de proformas. -- Fase 1D -- Script de desarrollo idempotente y conservador para separar Proformas / Issued Invoices. -- Objetivo: @@ -906,4 +909,4 @@ COMMIT; -- -- DROP TABLE proforma_taxes; -- -- DROP TABLE issued_invoices; -- -- DROP TABLE issued_invoice_items; --- -- DROP TABLE issued_invoice_taxes; \ No newline at end of file +-- -- DROP TABLE issued_invoice_taxes; diff --git a/docs/customer-invoices/sql/fix-proforma-target-invoice-series-code.sql b/docs/customer-invoices/sql/fix-proforma-target-invoice-series-code.sql deleted file mode 100644 index bb27be85..00000000 --- a/docs/customer-invoices/sql/fix-proforma-target-invoice-series-code.sql +++ /dev/null @@ -1,15 +0,0 @@ -UPDATE proformas AS p -JOIN document_series AS ds - ON ds.code = p.target_invoice_series_code - AND ds.document_type = 'proforma' -SET - p.target_invoice_series_code = NULL, - p.updated_at = NOW() -WHERE p.target_invoice_series_code IS NOT NULL; - -SELECT p.id, p.proforma_reference, p.target_invoice_series_code -FROM proformas AS p -JOIN document_series AS ds - ON ds.company_id = p.company_id - AND ds.code = p.target_invoice_series_code -WHERE ds.document_type = 'proforma'; diff --git a/docs/customer-invoices/sql/validate-split-proformas-issued-invoices.sql b/docs/customer-invoices/sql/validate-split-proformas-issued-invoices.sql index 0720c62a..52fe8725 100644 --- a/docs/customer-invoices/sql/validate-split-proformas-issued-invoices.sql +++ b/docs/customer-invoices/sql/validate-split-proformas-issued-invoices.sql @@ -1,3 +1,6 @@ +-- Estado: HISTORICO / TRANSICIONAL. +-- No ejecutar en entornos nuevos salvo auditoria de un split legacy ya realizado. +-- Sustituido por: validate-proforma-tax-config.sql y validate-document-series-migration.sql para el estado vigente. -- Fase 1D -- Validaciones SQL tras create/backfill de Proformas / Issued Invoices V2. diff --git a/docs/dev/customer-invoice-series.sql b/docs/dev/customer-invoice-series.sql index 6c820048..2486146a 100644 --- a/docs/dev/customer-invoice-series.sql +++ b/docs/dev/customer-invoice-series.sql @@ -1,4 +1,7 @@ -- Customer Invoices - InvoiceSeries +-- Estado: HISTORICO / TRANSICIONAL. +-- No ejecutar en entornos nuevos. +-- Sustituido por: /document-series como API canónica y document_series como tabla canónica. -- Estado del repo a fecha 2026-07-07: -- - no hay framework de migraciones versionadas localizado; -- - el servidor registra modelos Sequelize y usa database.sync(...) según syncMode. diff --git a/docs/document-series/README.md b/docs/document-series/README.md index 06118693..952c93bc 100644 --- a/docs/document-series/README.md +++ b/docs/document-series/README.md @@ -18,6 +18,8 @@ Centraliza la gestion de series documentales y su numeracion transaccional para - `PATCH /document-series/:id/disable` - `POST /document-series/assign-next` +`POST /document-series/assign-next` es un endpoint operativo para casos de uso backend o integraciones controladas. No es un endpoint para que la UI previsualice numeración. + ## Consumo desde otros módulos `document-series:general` expone: @@ -32,19 +34,24 @@ Centraliza la gestion de series documentales y su numeracion transaccional para - las proformas V2 persisten snapshot explicito de serie con `document_series_id`, `proforma_number` y `proforma_reference` - en create de proformas, `proforma_series_code` permite seleccionar la serie de `document_type = proforma` - en emision de proformas, `target_invoice_series_code` apunta solo a `document_type = issued_invoice` -- el endpoint transicional `/catalogs/invoice-series` queda eliminado antes de produccion -- la UI debe consultar `GET /document-series` filtrando por `document_type` +- el endpoint legacy `/catalogs/invoice-series` esta retirado del runtime +- la UI debe consultar `GET /document-series?document_type=proforma&is_active=true` +- la UI debe consultar `GET /document-series?document_type=issued_invoice&is_active=true` - la UI no debe consumir `POST /document-series/assign-next` para previsualizar numeros - `customer_invoice_series` queda como legado historico a retirar mediante limpieza operativa controlada, no como runtime activo -## SQL de soporte V1 +## SQL vigentes de soporte V1 -- `docs/document-series/sql/migrate-customer-invoice-series-to-document-series.sql` - `docs/document-series/sql/validate-document-series-migration.sql` - `docs/document-series/sql/drop-customer-invoice-series-legacy.sql` - `docs/customer-invoices/sql/add-proforma-document-series-columns.sql` +- `docs/customer-invoices/sql/add-proforma-tax-config-columns.sql` -Estos scripts son conservadores e idempotentes. No se han ejecutado automaticamente en este workspace ni sustituyen una migracion productiva formal. +## SQL históricos / transicionales + +- `docs/document-series/sql/migrate-customer-invoice-series-to-document-series.sql` + +Los scripts vigentes son runbooks manuales y no sustituyen una migracion productiva formal. Los scripts históricos deben usarse solo para auditoría o entornos legacy explícitamente identificados. ## Estado Fase 2C diff --git a/docs/document-series/document-series-design.md b/docs/document-series/document-series-design.md index 1deebe1f..c3a6abe6 100644 --- a/docs/document-series/document-series-design.md +++ b/docs/document-series/document-series-design.md @@ -59,12 +59,14 @@ En V1: - `proformas.proforma_reference` guarda la referencia visible de la proforma - `proforma_series_code` es el input funcional de create para elegir la serie de `document_type = proforma` - `proformas.target_invoice_series_code` es opcional y, cuando existe, apunta a una serie de `issued_invoice`, nunca a una serie de `proforma` -- create de proforma solo usa `document-series` para numerar la cabecera inicial; no calcula impuestos reales por si mismo +- create de proforma solo usa `document-series` para numerar la cabecera inicial +- create de proforma puede persistir `tax_config` sin materializar impuestos - una proforma puede crearse sin lineas y seguir siendo valida como borrador inicial - si no hay lineas valoradas, `proforma_taxes` debe quedar vacia y los totales monetarios a `0` - si `proformas.target_invoice_series_code` es `NULL`, la emision resuelve la serie default activa de `issued_invoice` - en Fase 2E, `series` deja de ser el contrato nuevo para create/update de proformas -- la UI consulta `GET /document-series` con filtro por `document_type` e idealmente `is_active = true` +- la UI consulta `GET /document-series` con filtro por `document_type` y `is_active = true` +- la UI no consume `POST /document-series/assign-next` para previsualizar numeracion - `/catalogs/invoice-series` deja de existir como endpoint runtime - `customer_invoice_series` no participa ya en flujos activos de lectura o numeracion diff --git a/docs/document-series/manual-validation.md b/docs/document-series/manual-validation.md index 41281ba4..69022df1 100644 --- a/docs/document-series/manual-validation.md +++ b/docs/document-series/manual-validation.md @@ -10,7 +10,8 @@ Confirmar que `document-series` es la fuente operativa unica para series y numer - BD de desarrollo con tablas `document_series`, `proformas` e `issued_invoices` - DDL de `docs/customer-invoices/sql/add-proforma-document-series-columns.sql` aplicada si `proformas` aun no tiene las columnas nuevas -- seed o migracion conservadora de `docs/document-series/sql/migrate-customer-invoice-series-to-document-series.sql` aplicada de forma manual si procede +- DDL de `docs/customer-invoices/sql/add-proforma-tax-config-columns.sql` aplicada si `proformas` aun no tiene las columnas nuevas +- seed o migracion conservadora de `docs/document-series/sql/migrate-customer-invoice-series-to-document-series.sql` aplicada solo si el entorno parte de `customer_invoice_series` - backend arrancado con `apps/server/.env.development` o equivalente seguro de desarrollo ## Casos recomendados @@ -38,14 +39,21 @@ Confirmar que `document-series` es la fuente operativa unica para series y numer - comprobar que el caso falla y no incrementa `next_number` 5. API canonica de series documentales - - llamar a `/document-series` filtrando `document_type = proforma` - - llamar a `/document-series` filtrando `document_type = issued_invoice` + - llamar a `/document-series` filtrando `document_type = proforma` e `is_active = true` + - llamar a `/document-series` filtrando `document_type = issued_invoice` e `is_active = true` - comprobar que la respuesta refleja filas activas de `document_series` 6. Endpoint legacy retirado - llamar a `/catalogs/invoice-series` - comprobar `404` o endpoint no registrado +7. Create de proforma sin lineas + - crear una proforma con `items = []` + - comprobar que devuelve `items = []` + - comprobar que devuelve `taxes = []` + - comprobar que los totales monetarios quedan a `0` + - comprobar que `tax_config` queda persistido y se devuelve en `GET /proformas/:id` + ## Pendiente conocido `branchId` aun no se propaga desde `customer-invoices` hasta `assignNextNumber(...)`. Toda la validacion de esta fase debe asumirse en alcance de empresa. diff --git a/docs/document-series/migration-from-customer-invoice-series.md b/docs/document-series/migration-from-customer-invoice-series.md index 3f659d4e..43d0d7cf 100644 --- a/docs/document-series/migration-from-customer-invoice-series.md +++ b/docs/document-series/migration-from-customer-invoice-series.md @@ -1,5 +1,8 @@ # Migration from customer_invoice_series +Estado: historico/transicional. +No representa el runtime actual ni el camino normal de entornos nuevos. + ## Equivalencia conceptual - `customer_invoice_series.code` -> `document_series.code` @@ -83,6 +86,7 @@ En Fase 2B la fuente preferida para este seed pasa a ser `companies`, no `custom - `GET /document-series` es la API canonica - `/catalogs/invoice-series` ha sido retirado del runtime - `CustomerInvoiceSeriesModel` y su repositorio legacy ya no participan en runtime +- la UI no usa este documento ni este flujo para el funcionamiento normal ## Pendiente diff --git a/docs/document-series/sql/drop-customer-invoice-series-legacy.sql b/docs/document-series/sql/drop-customer-invoice-series-legacy.sql index 13c33c42..dfbb7b7b 100644 --- a/docs/document-series/sql/drop-customer-invoice-series-legacy.sql +++ b/docs/document-series/sql/drop-customer-invoice-series-legacy.sql @@ -1,5 +1,7 @@ -- Limpieza operativa V1. -- NO ejecutar automaticamente desde codigo ni pipelines. +-- Estado: RUNBOOK MANUAL. +-- Ejecutar solo cuando el entorno ya no dependa de customer_invoice_series ni de auditoria legacy. -- Ejecutar solo cuando: -- 1) document_series contiene las series migradas necesarias -- 2) /document-series funciona como API canonica diff --git a/docs/document-series/sql/migrate-customer-invoice-series-to-document-series.sql b/docs/document-series/sql/migrate-customer-invoice-series-to-document-series.sql index a39d9b49..8abdb256 100644 --- a/docs/document-series/sql/migrate-customer-invoice-series-to-document-series.sql +++ b/docs/document-series/sql/migrate-customer-invoice-series-to-document-series.sql @@ -1,3 +1,6 @@ +-- Estado: HISTORICO / TRANSICIONAL. +-- No ejecutar en entornos nuevos salvo necesidad legacy explicita. +-- Sustituido por: document_series como runtime activo + validate-document-series-migration.sql como runbook vigente. -- Migracion conservadora e idempotente de customer_invoice_series a document_series. -- No ejecutar automaticamente en produccion. -- Revisar primero nombres de columnas y existencia de tabla document_series en el entorno destino.