# Gustito Xpress — Contexto del proyecto

Sistema operativo para negocios de comida en Venezuela: el pedido nace en el
teléfono del cliente o en la mano del mesero, suena en cocina, se acumula en la
mesa, se cobra (junto o por partes), sale en la moto con GPS en vivo y termina
en una factura fiscal sellada. Multi-negocio: cada uno con su marca, su menú y
su delivery.

- Tienda del cliente: `pedir.gustitoxpress.app` · Panel: `gustitoxpress.app`
- Repartidor: `repartidor.gustitoxpress.app` · Imprenta digital: `sello.gustitoxpress.app`
- El detalle de features vive en `README.md`. Este archivo es solo **reglas
  operativas** y **cómo navegar**.

## Stack

- Monorepo npm workspaces (`packages/*`, `apps/*`), Node ≥ 20.
- Apps web: Vite + React 18 + TS + Tailwind. Sin SSR. Escalan por CDN (Cloudflare Pages).
- Backend: Supabase (Postgres + RLS + Edge Functions). **La regla de negocio vive en la base.**
- Pata fiscal instalable: Node/TS empaquetado a exe (Estación Fiscal, cerebrito), C# (instaladores), Cloudflare (validador, worker de respaldo).
- Mapas: MapLibre + OpenStreetMap (cliente) y Leaflet (repartidor). Sin API key de pago.

## Estructura

```
apps/
  cliente/          Tienda PWA del comensal: menú, carrito, checkout, mesa, mapa
  restaurante/      Panel del negocio: pedidos, cocina, mesas, POS, caja
  repartidor/       Motorizado PWA: pedido asignado, GPS en vivo
  fiscal/           Estación Fiscal (exe Windows): libro sellado, IVA, transmisión
  cerebrito/        Puente de impresión local + POS de tablets (exe Windows)
  validador/        Imprenta digital "Gustito Sello" (Cloudflare Pages)
  instalador/       Instaladores nativos (C#)
  respaldo-imprenta/ Worker que respalda cifrado el esquema fiscal a R2
packages/shared/    Cliente Supabase tipado, dominio, dinero, changelog/versión
supabase/
  migrations/       Esquema, RLS y funciones — la fuente de verdad del backend
  functions/        Edge Functions (push, tasa BCV, cerebros con IA, equipo)
scripts/            Verificaciones end-to-end contra la base viva
```

## Cómo navegar la documentación

Hay un `CLAUDE.md` **path-scoped** por área: Claude Code lo carga solo cuando
trabajas en esos archivos, sin gastar contexto en las demás sesiones.

| Al tocar… | Se carga | Cubre |
|---|---|---|
| `apps/fiscal/**` | `apps/fiscal/CLAUDE.md` | Libro sellado, cola, respaldo, la frontera fiscal |
| `apps/restaurante/src/**` | `apps/restaurante/src/CLAUDE.md` | Panel: tabs, roles, tiempo real, dinero |
| `apps/cliente/src/**` | `apps/cliente/src/CLAUDE.md` | Tienda: carrito, checkout, QR de mesa, PWA |
| `apps/cerebrito/**` | `apps/cerebrito/CLAUDE.md` | POS local, impresión, idempotencia, atómico |
| `packages/shared/**` | `packages/shared/CLAUDE.md` | Dominio, dinero, canales, **changelog** |
| `supabase/migrations/**` | `supabase/migrations/CLAUDE.md` | RLS, RPCs, candados, flujo de migración |

Documentación larga (no se carga en cada sesión): `README.md` (visión general),
`apps/fiscal/MEMORIA_TECNICA.md` / `MANUAL_USUARIO.md` / `GUIA_INTEGRACION.md` /
`COTEJO_ART7.md` (la pata fiscal, requisito por requisito), `PLAN_INFRAESTRUCTURA.md`
(riesgos y escala), y las auditorías `AUDITORIA_*.md`.

## Arquitectura no obvia (las dos fronteras que sostienen el diseño)

1. **La regla de negocio vive en Postgres, no en la pantalla.** Precios desde la
   BD, anti-duplicado por firma, una sola cuenta activa por mesa, un pedido se
   cobra una vez, referencia de pago obligatoria: todo son candados en la base.
   La identidad se estampa server-side (`auth.uid()` dentro de la función), no
   desde lo que mande la app. El frontend es la cara amable. Ver
   `supabase/migrations/CLAUDE.md`.
2. **La frontera fiscal es unidireccional.** Gustito manda la venta y recibe el
   número; **nunca** escribe, edita ni borra el libro fiscal. La nube jamás llama
   a la Estación: la Estación *hala*. El interruptor de facturación lo maneja la
   imprenta, no el dueño. Ver `apps/fiscal/CLAUDE.md`.

Roles con RLS estricto: el dueño administra; el encargado opera sin ver la plata;
el mesero (`staff`) opera solo su sala; el repartidor solo ve lo suyo.

## Versionado y changelog

La versión de la plataforma (SemVer) y el historial de cambios viven en una sola
fuente: `packages/shared/src/changelog.ts`. Se muestran en el panel del negocio
(sección **Mejoras**, con el número de versión siempre visible en el menú
lateral). `CURRENT_VERSION` se deriva de la primera entrada — imposible
desincronizar. **La regla de cuándo y cómo agregar una entrada está en
`packages/shared/CLAUDE.md`.**

## Despliegue

Manual con `wrangler` a Cloudflare Pages (no hay auto-deploy). Las apps con Pages
Functions se despliegan desde la carpeta de la app. Las migraciones se aplican
por el SQL endpoint de la Management API (no `db push`), y después se regenera
`packages/shared/src/database.types.ts` con `npm run db:types`. Los exe (fiscal,
cerebrito) se empaquetan aparte (`npm run empaquetar`).

---

## Cambios recientes con regla operativa vigente

> Solo cambios que instauran una regla que aplica a trabajos futuros. Máximo 5
> entradas; el resto es historia en el git log y en `CHANGELOG_ENTRIES`.

### 2026-08-02 — Modelo de versiones + documentación path-scoped
Se integró el changelog/versión en `packages/shared/src/changelog.ts` con
sección **Mejoras** en el panel, y este CLAUDE.md raíz + los path-scoped por
área. **Regla:** cuando algo visible al negocio llega a producción, agregar una
entrada al changelog (ver `packages/shared/CLAUDE.md`); si renombras/eliminas un
helper documentado en un CLAUDE.md, actualízalo en el mismo commit.

### 2026-08-02 — Revisión de código (7 correcciones)
Detalle en `AUDITORIA_2026_08_02.md`. **Reglas que dejó:** el escritor de la
frase de respaldo y todo estado del fiscal se escribe atómico (tmp+rename); las
operaciones de creación del POS del cerebrito llevan idempotencia por `opId`;
la referencia de pago electrónico se exige en la base (no solo en la pantalla),
en las tres puertas de cobro de mesa.

### 2026-07-30 — La regla fiscal/dinero vive en la base
`fn_exigir_referencia` demostró el principio: una validación que solo está en el
navegador se la salta cualquiera llamando la RPC directo. Todo lo que sea
registro fiscal o dinero se valida en la migración, no en el frontend.

---

## Reglas operativas globales

- **CLAUDE.md raíz ≤ 300 líneas** (objetivo ~200). Cualquier subdirectorio con
  5+ archivos de reglas comunes merece su propio path-scoped.
- **Una regla vive en UN solo lugar.** Si es de un área, va en su path-scoped;
  si es transversal, va aquí. No duplicar.
- **Si renombras/eliminas un helper documentado**, corrige la doc en el mismo commit.
- **Español (Venezuela)** en código, tablas, columnas e interfaz. En lo fiscal,
  lenguaje de expediente. Minimizar emojis; tono humano.
- **Verificar en navegador** (headless) antes de desplegar apps web, no con curl.
- **Antes de agregar una entrada a "Cambios recientes" de arriba**, comprobar que
  instaura una regla vigente; si solo describe qué cambió, va al git log.

## Validar

```bash
npm run typecheck                          # todos los paquetes
npm run build                              # build de las apps web
npm run prueba --workspace apps/fiscal     # suite de la Estación (24 suites, offline)
node scripts/test_cuentas_separadas.mjs    # cobro por partes (contra base viva)
```

> `apps/cliente` arrastra 4 errores de typecheck preexistentes (imports/null vs
> undefined en tipos generados) — no introducidos por trabajo reciente; conviene
> limpiarlos aparte.
