Modelo de datos · documento oficial
Modelo vigente y canónico. Cualquier otra página que muestre tablas se subordina a esta.
Cómo se traduce la operación —importar, almacenar, vender y facturar— a tablas. El producto es el concepto comercial; la variante (con su código SKU) es lo que de verdad se compra, se vende y se cuenta en el almacén. El stock no se escribe a mano: se calcula sumando los movimientos (detalle en Cómo se deriva el stock).
El catálogo alimenta todo (línea punteada). La compra suma stock, la venta lo resta y genera el cobro. El equipo es transversal y se omite aquí.
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 1 | Número interno que el sistema asigna solo. Sirve para no confundir productos con el mismo nombre. |
| nombre | Audífonos inalámbricos | El nombre del producto tal como lo conoce el cliente. |
| descripcion | Bluetooth 5.0, 20 h batería | Texto que explica el producto en el catálogo. |
| marca | Sonely | La marca, si la tiene. |
| categoria_id FK | 4 | A qué categoría pertenece. Apunta a categoria. |
| activo | Sí | Si se muestra o no en la tienda. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 12 | Número interno de esta versión exacta del producto. |
| producto_id FK | 1 | De qué producto es esta versión. Apunta a producto. |
| sku | AUD-NEG-001 | Código único de esta versión. Es lo que se rotula y se cuenta físicamente. |
| codigo_barras | 7751234567890 | El código de barras para escanear, si lo trae. |
| atributos | Color: negro | Lo que diferencia esta versión de otras del mismo producto (color, talla, medida). |
| activo | Sí | Si esta versión sigue a la venta. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 4 | Número interno de la categoría. |
| nombre | Audio | Nombre visible de la categoría. |
| slug | audio | El nombre en formato de dirección web (sin tildes ni espacios). |
| padre_id FK | 2 | Si es una subcategoría, de cuál depende. Apunta a categoria. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 30 | Número interno de la imagen. |
| variante_id | 12 | De qué versión del producto es la foto. Referencia lógica a variante (bases distintas, sin FK). |
| sku | AUD-NEG-001 | Copia del SKU, para no depender de un join entre bases al mostrarla. |
| orden | 1 | En qué posición aparece. |
| es_principal | Sí | Calculada por Postgres (orden = 1), no se edita directamente. |
| alt | Audífonos, vista frontal | Texto alternativo de la imagen. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 61 | Número interno del render. |
| imagen_id FK | 30 | De qué imagen es este tamaño. Apunta a imagen_producto. |
| tamano | media | miniatura, media u original. |
| mime / ancho / alto / bytes | image/webp · 800×600 | Metadatos del archivo ya procesado (siempre WebP). |
| contenido | binario | El archivo en sí, guardado en Postgres (modo autónomo, el que se usa hoy). |
| url | null | Solo se usa en modo CDN/S3 (no activo hoy); si está vacía, se sirve contenido. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 1 | Número interno de la zona. |
| nombre | Casa — Sala | Nombre de la zona o estante. |
| tipo | Zona | Si es una zona, un estante, una caja, etc. |
| direccion | Av. Primavera 123, Lima | Dónde queda físicamente. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 500 | Número interno del movimiento. |
| variante_id FK | 12 | Qué versión del producto se movió. Apunta a variante. |
| almacen_id FK | 1 | En qué zona ocurrió. Apunta a almacen. |
| tipo | Entrada | Si suma (entrada/compra), resta (salida/venta), corrige (ajuste/merma) o reserva. Una reserva aparta stock para un pedido a futuro: no altera el stock físico, solo baja el disponible para venta. |
| cantidad | 50 | Cuántas unidades entran o salen. En una reserva es una magnitud positiva (lo apartado). |
| reserva_estado | Activa | Solo en movimientos de tipo reserva (vacío en el resto): activa (aparta stock), consumida (el pedido se pagó y pasó a venta) o liberada (expiró, se anuló o se reeditaron líneas). Solo las activas restan del disponible. |
| linea_pedido_id FK | 140 | Si el movimiento nace de una línea de pedido (reserva o venta), a cuál. Apunta a linea_pedido. |
| referencia | Compra #8 | De dónde viene el movimiento (una compra, una venta, un conteo, una reserva). |
| fecha | 15/06/2026 | Cuándo ocurrió. |
Con reservas, el stock se lee en tres cifras: físico = suma de movimientos no-reserva; reservado = suma de reservas activas; disponible = físico − reservado. Solo se puede vender/reservar hasta el disponible.
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 3 | Número interno del proveedor. |
| nombre | Shenzhen Sonely Co. | Nombre de la fábrica o proveedor. |
| pais | China | De dónde importamos. |
| contacto | WeChat · ventas@… | Cómo se les contacta. |
| moneda | USD | En qué moneda nos cobran. |
| condiciones | MOQ 100 uds | Cantidad mínima de compra y otras condiciones acordadas. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 8 | Número interno del pedido de compra. |
| proveedor_id FK | 3 | A quién le compramos. Apunta a proveedor. |
| fecha | 01/05/2026 | Cuándo se hizo el pedido. |
| estado | En tránsito | En qué punto va (pedido, producción, en tránsito, recibido). |
| moneda | USD | En qué moneda se pactó. |
| tipo_cambio | 3.75 | Cuántos soles vale 1 dólar ese día. Se guarda para calcular el costo real en soles. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 20 | Número interno de la línea. |
| orden_compra_id FK | 8 | De qué pedido es. Apunta a orden_compra. |
| variante_id FK | 12 | Qué versión del producto. Apunta a variante. |
| cantidad | 200 | Cuántas unidades se pidieron. |
| precio_unitario | USD 4.50 | Lo que cuesta cada unidad puesta en fábrica, antes de flete y aduanas. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 5 | Número interno del embarque. |
| orden_compra_id FK | 8 | Qué pedido viaja. Apunta a orden_compra. |
| incoterm | FOB | Hasta qué punto del viaje paga el proveedor el transporte. |
| contenedor | MSC · ABC123 | Naviera y número de contenedor. |
| fecha_salida | 01/05/2026 | Cuándo zarpó de origen. |
| fecha_llegada | 10/06/2026 | Cuándo llegó a puerto. Se guarda aparte para medir cuánto tardó el viaje. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 9 | Número interno del documento. |
| embarque_id FK | 5 | De qué embarque es. Apunta a embarque. |
| tipo | DUA | Qué documento es (DUA, factura comercial, packing list…). |
| numero | 118-2026-001234 | El número oficial del documento. |
| archivo | dua.pdf | El archivo escaneado. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 14 | Número interno del costo. |
| embarque_id FK | 5 | A qué embarque pertenece. Apunta a embarque. |
| tipo | Flete | Si es flete, aduana o seguro. |
| monto | USD 800 | Cuánto se pagó por ese concepto. |
| moneda | USD | En qué moneda se pagó. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 2 | Número interno de la muestra. |
| proveedor_id FK | 3 | Quién la envió. Apunta a proveedor. |
| descripcion | Audífonos v2 | Qué muestra es. |
| link_origen | 1688.com/… | El enlace del producto en 1688/Alibaba de donde salió la muestra. |
| costo | USD 12 | Lo que costó la muestra más su envío. |
| estado | Aprobada | Si pasó la revisión de calidad o no. |
| fecha | 10/04/2026 | Cuándo se recibió. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 40 | Número interno del cliente. |
| nombre | Librería San Marcos | Nombre de la persona o la empresa. |
| tipo | Empresa | Particular o empresa. |
| doc_tipo | RUC | Tipo de documento: DNI para personas, RUC para empresas. |
| doc_numero | 20512345678 | El número del documento. Es obligatorio para emitir el comprobante. |
| direccion_fiscal | Jr. Lampa 200, Lima | El domicilio que figura en el RUC. SUNAT lo exige en la factura. |
| email / telefono | ventas@… · 999… | Cómo se le contacta. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 88 | Número interno del pedido. |
| cliente_id FK | 40 | Quién compra. Apunta a cliente. |
| canal | Por dónde llegó la venta (WhatsApp, Instagram, presencial, correo, web). | |
| fecha | 16/06/2026 | Cuándo se hizo el pedido. |
| estado | Pagado | Pendiente, pagado, enviado, entregado, anulado o expirado (reserva vencida sin pago). |
| es_reserva | Sí | Pedido a futuro: al crearse aparta el stock (reserva) en vez de dejarlo libre. Solo se puede editar mientras está pendiente. |
| fecha_expiracion | 23/06/2026 12:00 | Solo en pedidos a futuro: hasta cuándo se mantiene la reserva. Por defecto 7 días, máximo 7. Si no se paga antes, el sistema libera el stock y marca el pedido Expirado. |
| tipo_comprobante | Factura | Comprobante declarado (Boleta, Factura o Ninguno). Por defecto según el documento del cliente (RUC→Factura, DNI→Boleta); Factura exige RUC. Es solo intención: no emite nada (la emisión es otra fase). |
| notas | Entregar después de las 3pm | Instrucciones especiales del cliente. |
| creado_en | 16/06/2026 10:32 | Cuándo se registró en el sistema. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 120 | Número interno de la línea. |
| pedido_id FK | 88 | De qué pedido es. Apunta a pedido. |
| variante_id FK | 12 | Qué versión del producto se vendió. Apunta a variante. |
| cantidad | 3 | Cuántas unidades. |
| precio_unitario | S/ 60 | El precio al que se vendió en ese momento. Se guarda aunque el precio cambie después. |
| precio_lista_original | S/ 75 | El precio de lista de la variante cuando se creó la línea. Sirve para auditar el descuento si el empleado bajó el precio. |
| precio_modificado | Sí | Marca si el precio unitario se cambió a mano respecto al de lista (un descuento), no un precio arbitrario. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 22 | Número interno del envío. |
| pedido_id FK | 88 | Qué pedido se envía. Apunta a pedido (uno a uno). |
| courier | Olva Courier | Con qué empresa se envía. Texto libre, escrito a mano. |
| tracking | OLV-99812 | El código para rastrear el paquete, si lo hay. Texto libre, no se consulta ninguna API. |
| direccion | Av. Larco 500, Miraflores | La dirección de entrega de este envío en concreto. |
| costo_envio | S/ 15 | Lo que cuesta el despacho. |
| estado | Entregado | Preparando, en camino, entregado o anulado. |
| fecha_estimada / fecha_entrega | 18/06/2026 | Cuándo se prometió entregar y cuándo se entregó de verdad. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 1 | Número interno de la lista. |
| nombre | Mayorista | Nombre de la lista de precios. |
| tipo_cliente | Empresa | A qué tipo de cliente se aplica. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 33 | Número interno. |
| variante_id FK | 12 | Qué versión del producto. Apunta a variante. |
| lista_precios_id FK | 1 | A qué lista pertenece. Apunta a lista_precios. |
| precio | S/ 45 | El precio de venta. |
| moneda | PEN | En qué moneda (soles). |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 60 | Número interno del comprobante. |
| pedido_id FK | 88 | De qué venta es. Apunta a pedido. |
| tipo | Boleta | Factura para empresas, boleta para personas. |
| serie / correlativo | B001-000123 | El número oficial que exige SUNAT. |
| fecha_emision | 16/06/2026 | La fecha legal del comprobante. Puede diferir de la del pedido. |
| igv / total | S/ 68.64 · S/ 450 | El impuesto (18%) y el monto total con IGV incluido. |
| estado_sunat | Aceptado | Pendiente, aceptado o rechazado — hoy siempre simulado (ver Servicios externos). |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 70 | Número interno del pago. |
| pedido_id FK | 88 | Qué pedido se pagó. Apunta a pedido. |
| metodo | Yape | Cómo pagó (Yape, Plin, tarjeta, PagoEfectivo…). |
| monto | S/ 450 | Cuánto pagó. |
| estado | Confirmado | Si el pago se confirmó o no. |
| voucher_url | /vouchers/yape-70.jpg | La captura del Yape/Plin que envía el cliente como prueba. |
| referencia / fecha | Op. 00012 · 16/06 | El código de operación y cuándo se pagó. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 12 | Número interno de la nota de crédito. |
| comprobante_id FK | 60 | Qué boleta o factura corrige. Apunta a comprobante. |
| motivo | Devolución | Por qué se emite (devolución, anulación, descuento, error). |
| serie / correlativo | BC01-000045 | El número oficial de la nota que exige SUNAT. |
| monto | S/ 150 | Cuánto se devuelve o descuenta. |
| estado_sunat | Aceptado | Si SUNAT la aceptó, la rechazó o está pendiente. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 1 | Número interno del usuario. |
| nombre | Franitza León | Nombre de la persona. |
| franitza@… | Con qué correo entra al sistema. | |
| rol | Abastecimiento | Qué puede hacer en el sistema (abastecimiento, ventas, marketing, sistemas, admin). |
| activo | Sí | Si su acceso está habilitado. Se apaga sola al crear la cuenta hasta que se aprueba (ver aprobado). |
| aprobado | Sí | Si un admin ya revisó la cuenta. Las que crea un admin desde Equipo nacen aprobadas; las que llegan por autoregistro (/auth/registro) nacen en No y quedan bloqueadas hasta que un admin las aprueba. |
| tema | claro | Preferencia de tema claro/oscuro de la intranet. Sigue a la persona entre dispositivos. |
| creado_en | 01/01/2026 | Cuándo se creó la cuenta. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 60 | Número interno del documento. |
| comprobante_id | 60 | Referencia lógica a comprobante (leon_principal). |
| documento | JSON | El comprobante completo en JSON, estilo UBL simplificado. |
| xml_firmado / cdr_xml | stub | Hoy son un simulacro: no hay firma digital real ni CDR devuelto por SUNAT (ver Servicios externos). |
| estado_sunat | aceptado | Se marca "aceptado" automáticamente; no hay validación real. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 200 | Número interno del evento. |
| factura_id FK | 60 | A qué documento pertenece. Apunta a factura_documento. |
| evento | aceptado | generado, enviado, aceptado, rechazado o anulado. |
| Campo | Ejemplo | Descripción |
|---|---|---|
| id PK | 900 | Número interno del registro. |
| usuario_id | 1 | Quién hizo la acción. Referencia a usuario sin FK forzada (se aplica antes de que exista auth_user). |
| accion | crear | crear, editar, eliminar, activar, desactivar, login o logout. |
| modelo_afectado / objeto_repr | Producto · "Cuaderno A4" | Qué tipo de dato y cuál en concreto. |
| descripcion | Andrei ha creado el producto… | La frase legible que se muestra en pantalla. |
| timestamp | 16/06/2026 10:32 | Cuándo ocurrió. Indexado para consultar rápido por fecha. |
Las listas de precios por tipo de cliente siguen marcadas "Fase posterior": todavía no existen, hoy el precio es el mismo para todos. Tres ideas sostienen el modelo: el código SKU vive en la variante, el stock se calcula sumando los movimientos (nunca es una columna), y son 3 bases separadas (principal, fotos, facturas) sin FK entre ellas.