Almacenamiento y relaciones
Una tabla de entidades con JSON y relaciones validadas por el servidor.
Tabla principal: public.app_records
Las entidades comerciales se guardan en una tabla PostgreSQL común. resource indica el tipo y data conserva sus campos propios, listas y objetos anidados. No hay una tabla SQL distinta para cada tipo de factura ni tablas separadas de cuotas e imputaciones.
| Columna SQL | Tipo | Salida JSON |
|---|---|---|
| id | uuid, PK | id |
| resource | text | Determinado por la ruta del recurso |
| data | jsonb, objeto | Campos de negocio en el nivel raíz |
| version | integer > 0 | version |
| created_at | timestamptz | createdAt |
| updated_at | timestamptz | updatedAt |
| voided_at | timestamptz nullable | voidedAt |
Mapa de relaciones
suppliers → invoices → installments / lines
payments / credits → allocations → invoices o expenses
payment-orders → lines / advances → payments
products ← invoices.lines.productId
delivery-notes.lines → products
matches → invoices.id + lines.id
stock-movements → products
customers → sales-invoices
receipts / sales-credits → allocations → sales-invoices
Estas relaciones viven dentro de JSON. No son claves foráneas SQL a tablas de negocio distintas: el servidor y las funciones transaccionales validan identidad, moneda, unidad y consistencia. Los IDs de líneas y cuotas son texto local al comprobante.
Tablas auxiliares
audit_log: historial con id bigint, actor, action, resource, record_id, before_value, after_value, request_id y created_at. El bigint se trata como string en cursores para evitar pérdida de precisión.document_uploads,document_receiptsydocument_receipt_requests: carga, recepción e idempotencia de originales.api_idempotency: respuestas de operaciones repetidas.authorized_usersyagent_tokens: control de acceso y permisos; no forman parte del intercambio comercial.exchange_quote_cache: caché de cotización para estimaciones, no moneda original de los registros.
El sistema interno consume la API HTTPS. No necesita acceso directo a PostgreSQL ni credenciales de Supabase.
Identidad y cambios
Usar (resource, id) como clave de integración y version como control de actualización. El número fiscal, SKU o nombre son identidades de negocio adicionales. Una anulación conserva el registro y su historial: marcarlo como anulado en el destino.
Las modificaciones a listas reemplazan la lista completa, conservando IDs de líneas/cuotas. Los campos calculados pueden cambiar cuando cambia un registro relacionado, sin que aumente la versión de la factura o el producto.