# PROMPT DE DESARROLLO — Sistema de Stock, Consignación y Ferias · Vitrofusión

## 0. Rol y encargo

Actúa como **ingeniero de software senior full-stack** (diseño de datos + backend + frontend + seguridad). Tu cliente es el taller artesanal **Vitrofusión de Don Carlos Guerrero** (Olmué, Chile), que hoy controla todo con páginas HTML sueltas que guardan datos en el navegador (localStorage).

Encargo: **desarrollar una aplicación web con inicio de sesión multiusuario (administrador y usuarios con roles distintos)** que centralice el **stock**, la **consignación** y las **ferias** en una base de datos única, manteniendo la simpleza de uso de las páginas actuales.

---

## 1. Material de partida (esto ya existe y hay que respetarlo)

| Página | Archivo / clave | Qué aporta |
|---|---|---|
| Producción Taller v2 | `produccion-taller-v2.html`, clave `produccion_taller_v2` | Códigos de producto: colores C01–C08, formas F01–F10, ganchos G01–G15. Ventas y plan de horno. |
| Vitrina (selección en celular) | `vitrina-seleccion.html`, clave `vitrina_vitrofusion_v1` | Captura rápida de venta: color → forma → gancho → cantidad. Exporta CSV. |
| Consignación de aros | `consignaciones-verano.html`, clave `consignaciones_v1` | Feriantes, entrega/venta/pago/devolución/ajuste, saldos, acta de entrega, acuerdo. |
| Base de Ferias | `base-ferias.html`, clave `ferias_vitro_2026` | Postulaciones, temporadas, estados, costo de stand, adjuntos. |
| Hoja diaria de producción | `hoja-produccion-diaria.html` | Conteo en papel: 3 marcas en una columna = 1 par. |
| Pronóstico taller | `pronostico-taller.html` | Proyección de producción (ABC, media móvil, Holt, stock de seguridad). |

**Modelo de códigos (obligatorio, no cambiar):** colores `C01…C08`, formas `F01…F10`, ganchos `G01…G15`. Las altas nuevas siguen la serie (`C09`, `F11`, `G16`…). Un **par** de aros = **2 piezas**; el conteo del negocio se hace en pares, salvo el stock de piezas de vidrio, que se cuenta por unidad.

---

## 2. Objetivo del sistema

1. Una sola fuente de verdad: hoy los datos viven en 6 navegadores distintos y no se cruzan.
2. Que cada persona use solo lo suyo: el dueño ve todo, cada feriante ve únicamente su cuenta.
3. Saber en todo momento **cuántos pares hay, dónde están** (taller, bodega, stand, manos del feriante) y **cuánto se le debe o se le pagó**.
4. Registrar ventas en la feria desde el celular, incluso **sin señal**, y sincronizar al volver.
5. Cerrar la temporada con números reales: ingresos, IVA, utilidad, stock devuelto, gastos de ferias.

---

## 3. Usuarios, roles y permisos

| Rol | Quién es | Puede hacer | No puede |
|---|---|---|---|
| **admin** (dueño) | Don Carlos | Todo: usuarios, precios, códigos, stock, consignaciones, pagos, ferias, reportes, cierres | — |
| **taller** (producción) | ayudante | Ingresar producción al horno, mover stock entre ubicaciones, ajustes por rotura/pérdida | Ver precios de venta ni cuentas de feriantes |
| **feriante / consignatario** | los 2 amigos con stand | Ver **su** stock en poder, registrar **sus** ventas, ver su saldo y sus pagos, descargar su acta | Ver otros feriantes, costos, utilidades ni precios de compra |
| **vendedor feria propia** | temporal por feria | Registrar ventas de la feria asignada y anotar quiebres de stock | Ver consignaciones ajenas |
| **contador** (opcional) | externo | Ver y exportar libros (ventas, pagos, IVA, gastos) | Editar o borrar |

Reglas de acceso: sesión por usuario y contraseña (hash, nunca en texto claro), token con expiración, cierre de sesión por inactividad, y **un registro de auditoría** de quién hizo cada cambio. El admin crea, desactiva y cambia el rol de los usuarios; un feriante **no** puede crearse solo ni cambiar sus datos de precio.

---

## 4. Modelo de datos (base central)

- **usuario**: id, nombre, email, rol, hash_contrasena, activo, ultimo_acceso, consignatario_id (si aplica).
- **ubicacion**: id, tipo (taller, bodega, stand, feriante), nombre, consignatario_id, activa.
- **atributo**: id, tipo (color, forma, gancho), codigo, nombre, foto_url, activo. (Reemplaza las listas fijas actuales y permite agregar diseños nuevos con foto.)
- **stock**: atributo_id, ubicacion_id, cantidad. (Stock de piezas de vidrio por forma+color y stock de ganchos.)
- **movimiento_stock**: id, fecha, tipo (ingreso_produccion, entrega, venta, devolucion, ajuste, rotura, perdida), atributo_id, cantidad, ubicacion_origen, ubicacion_destino, feria_id, usuario_id, nota.
- **consignatario**: id, nombre, fono, email, stand, modalidad (fijo o comision), precio_base, comision_pct, activo, notas, usuario_id.
- **acuerdo**: id, consignatario_id, vigente_desde, vigente_hasta, precio_publico, mi_parte, iva_pct, costo_produccion, documento_url.
- **venta**: id, fecha, canal (consignacion, feria_propia, mayorista, online), feria_id, consignatario_id, forma_cod, color_cod, gancho_cod, unidades_pares, precio_unitario, monto_total, usuario_id, estado (registrada o pendiente_confirmacion), stockout (quiebre).
- **pago**: id, fecha, consignatario_id, monto, medio, comprobante_url, usuario_id.
- **feria**: id, temporada, nombre, lugar, region, fecha_evento, apertura_postulacion, cierre_postulacion, costo_stand, estado (por_postular, enviada, aceptada, rechazada, confirmada), documentos, link_bases, notas.
- **adjunto**: id, feria_id, nombre, url, es_imagen. (Los archivos van a almacenamiento de objetos; el bucket `donkarlos` ya existe y admite lectura pública por URL directa.)
- **gasto**: id, fecha, categoria, monto, feria_id, nota.
- **auditoria**: id, fecha, usuario_id, entidad, entidad_id, accion, valor_anterior, valor_nuevo.
- **config**: precios vigentes, IVA, costo, temporada activa (con historial de cambios, para no romper el pasado).

---

## 5. Reglas de negocio (invariantes que el sistema debe hacer cumplir)

1. **Stock en poder de un feriante** = entregas − ventas − devoluciones + ajustes. **Nunca puede quedar negativo**: si un registro lo dejaría bajo cero, el sistema bloquea y pide corregir.
2. **Saldo por cobrar** = (pares vendidos × lo que me corresponde por par) − pagos recibidos.
   - Modalidad *precio fijo*: lo mío = precio_base por par.
   - Modalidad *comisión*: lo mío = precio_publico × comision_pct.
3. **IVA 19% incluido** en el precio al público: guardar siempre el neto y el IVA por separado (para el libro de compras y ventas).
4. **Montos en pesos chilenos, enteros** (sin decimales). Zona horaria `America/Santiago`. Fechas en formato AAAA-MM-DD.
5. **Trazabilidad total**: ningún movimiento se borra; se corrige con un contra-movimiento. Todo cambio queda en auditoría con usuario, fecha y valor anterior.
6. **Cierre de feria**: mientras haya pares en poder de un feriante, la feria no se puede dar por cerrada; exige devolución o regularización con acta firmada.
7. **Ventas de consignación registradas por el feriante** quedan como *pendiente de confirmación* hasta que el admin las apruebe. Así el stock y el saldo se ajustan con control.
8. **Un par = 2 aros**; al vender se descuenta del stock de piezas el material del par, y al ingresar producción se carga por pieza.
9. **Precios históricos**: si el admin cambia un precio, las ventas anteriores conservan el precio con que se registraron.
10. **Alta de diseños nuevos**: solo admin; se asigna el siguiente código de la serie y admite foto.

---

## 6. Pantallas y casos de uso por rol

**Admin**
- Tablero: pares en stock por ubicación, pares en consignación, saldo por cobrar, ya recibido, ventas al público, IVA del período, utilidad, stock bajo.
- Gestión de usuarios (crear, rol, activar/desactivar, resetear contraseña).
- Catálogo: colores, formas, ganchos (con foto), ubicaciones y precios.
- Consignaciones: alta de feriante, acuerdo, entrega, venta, pago, devolución, ajuste, acta imprimible, estado de cuenta.
- Ferias: calendario con postulaciones, estados, documentos y adjuntos.
- Reportes: ventas por canal y por diseño, ranking ABC, márgenes, exportación a CSV/Excel y PDF.

**Feriante**
- Mi cuenta: cuántos pares tengo, cuántos vendí, cuánto me corresponde, si estoy al día o debo.
- Registrar venta (rápido, con botones grandes: color → forma → gancho → cantidad).
- Ver mis movimientos y descargar mi acta / mi estado de cuenta.

**Taller / vendedor de feria**
- Cargar producción del día al stock.
- Mover o entregar pares.
- Registrar venta de feria propia con marca de quiebre de stock.
- Todo funciona **offline** en el celular y sincroniza al recuperar señal.

---

## 7. Requisitos técnicos

- **Backend**: Python con FastAPI, base de datos **PostgreSQL**, migraciones versionadas (Alembic), API REST documentada (OpenAPI).
- **Seguridad**: contraseñas con hash (argon2 o bcrypt), JWT con expiración y renovación, permisos por rol verificados en el servidor (no solo en el front), límite de intentos de login, HTTPS.
- **Frontend**: aplicación web responsiva tipo PWA, pensada para celular con una mano, botones grandes, modo offline con almacenamiento local y cola de sincronización. Reutilizar la paleta y el estilo de las páginas actuales (azul #1F4E79, KPI en tarjetas).
- **Multiusuario**: cada feriante ve solo su información; el filtro se aplica en el servidor.
- **Respaldos**: exportación completa a archivo y respaldo automático diario de la base de datos.
- **Despliegue**: contenedor Docker con `docker-compose`, publicado detrás del servidor web en un subdominio propio, sin exponer la base de datos a internet.
- **Migración de datos existentes**: importador que reciba el JSON de las claves `consignaciones_v1`, `ferias_vitro_2026`, `produccion_taller_v2` y el CSV que exporta la Vitrina (columnas: fecha, forma, color, gancho, canal, unidades, precio, stockout). Se debe poder correr dos veces sin duplicar registros.

**Endpoints mínimos**: autenticación (login, logout, recuperar clave, yo), usuarios, atributos, ubicaciones, stock y movimientos, consignatarios y acuerdos, ventas, pagos, ferias y adjuntos, gastos, reportes y exportaciones (CSV/PDF), auditoría.

---

## 8. Criterios de aceptación

- [ ] El admin crea un usuario feriante y ese usuario entra y ve **solo** su cuenta.
- [ ] Un usuario sin permiso recibe error al intentar una acción prohibida (probado por API, no solo por pantalla).
- [ ] La entrega de 100 pares descuenta el stock del taller y lo deja "en poder" del feriante.
- [ ] Registrar ventas baja el stock, sube el saldo por cobrar y calcula neto e IVA.
- [ ] El sistema **impide** un stock negativo y explica por qué.
- [ ] Un pago baja el saldo; el estado de cuenta cuadra al peso.
- [ ] La venta registrada offline en la feria sincroniza sin duplicarse al recuperar señal.
- [ ] El acta de entrega y el acuerdo se imprimen en PDF con las firmas.
- [ ] El CSV exportado tiene el mismo formato que las páginas actuales y se importa sin errores.
- [ ] La auditoría muestra quién cambió qué y cuándo.
- [ ] Pruebas automatizadas de las fórmulas de stock, saldo, IVA y comisión.

---

## 9. Entregables

1. Modelo de datos definitivo (diagrama y migraciones).
2. Backend con la API y las reglas de negocio implementadas.
3. Frontend PWA con las pantallas por rol.
4. Script de migración de los datos actuales, con datos de ejemplo (2 feriantes, 100 pares cada uno, precios $10.000 público / $5.000 mi parte).
5. `docker-compose`, variables de entorno de ejemplo y README con el paso a paso de instalación.
6. Pruebas automatizadas y un informe corto con lo que quedó pendiente.

**Forma de trabajo**: entrega por etapas, avisando al terminar cada una — (1) modelo de datos + login y roles, (2) stock y movimientos, (3) consignación y pagos, (4) ferias y reportes. Pregunta antes de inventar cualquier dato del negocio: precios, costos, comisiones y nombres de personas los define el dueño.
