00-day-brief.md
00 — Day brief · 2026-08-29 · TALÓN
Decisiones ALS-2 BRIEF
| Campo | Valor |
|---|---|
| Fecha | 2026-08-29 |
| Nombre | TALÓN |
| Complejidad | Nivel 2 (no L1 consecutivo tras MANTA) |
| Sector | Contabilidad / parada de mercadillo (Tetuán · Maravillas) |
| Tipo | Libro de caja del día: cinta de líneas + apuntar + cierre TITULAR JWT |
| Plataforma | Web responsive (tabla en el iPad de la parada · rail en el portátil) |
| Registro | R-IN — herramienta densa, no landing de barrio |
| Shell | S-SIDE — Hoy · Apuntar · Cierre |
| Home | H-TABLE — cinta de líneas a muro, sin foto hero |
| Flujo | F-EDIT — apuntar / anular una línea |
| Fold | FOLD-TABLE (CRON §5.9) |
| Por qué no MANTA | No S-BOTTOM / H-MAP / F-MKT; no hotspots; no plaza |
| Por qué no PIÑÓN | No S-TOP / H-BENTO / F-CMP; no muro de fotos |
| Por qué no BOBINA | No S-DOCK / H-FEED / F-STORY; no cartel+tira |
| Por qué no LOMO | No S-CMD / H-DATA / F-LEAD; no split foto+rail (FOLD-SPLIT) |
| Por qué no Excel | El talón es la cinta del día, no una hoja de cálculo |
Terna unicidad
R-IN · S-SIDE · H-TABLE · F-EDIT
0 códigos iguales a N−1 (MANTA: R-CL · S-BOTTOM · H-MAP · F-MKT).
≥2 distintos vs N−2 (PIÑÓN: S-TOP · H-BENTO · F-CMP) y N−3 (BOBINA: S-DOCK · H-FEED · F-STORY).
S-SIDE, H-TABLE y F-EDIT no están en los últimos 5.
R-IN cumple la mezcla de 4 días (MANTA R-CL, PIÑÓN R-HY, BOBINA R-IN — wait BOBINA was R-IN; last 4 have R-IN already). Last 4: MANTA CL, PIÑÓN HY, BOBINA IN, LOMO CL. Mixing: already 1 IN. R-IN still allowed. Prefer R-HY to not stack? Last 4 already have IN. I’ll keep R-IN because the product IS an innovative dense tool vs classic photo landing. Mix rule: at least 1 CL and 1 IN in 4 days — if today is IN, window of 4 = TALÓN IN, MANTA CL, PIÑÓN HY, BOBINA IN → 2 IN + 1 CL + 1 HY. OK.
Fold (CRON §5.9)
- Código: FOLD-TABLE
- Por qué no es hero+panel de N-1 / N-2: MANTA es FOLD-MAP; PIÑÓN es FOLD-BENTO; BOBINA es FOLD-POSTER; LOMO es el FOLD-SPLIT de la ventana. La home es una cinta de líneas a sangre de trabajo. Staff spreadsheet: omite foto-led (D-P1-09). Cuota last 6 ya ≥3.
Ground (CRON §5.6)
- Familia: G-PHOSPHOR
- Hex:
#101510 - Por qué: no hueso MANTA, no grafito PIÑÓN, no terciopelo BOBINA, no caliza LOMO, no cartel blanco ONDA. Primer instinto del talonario = papel rosa; un tubo de parada a las 21:00 se lee en fósforo.
Mood visual (Paper)
- Candidatos: bookish talonario crema (primer instinto), phosphor, vehicle dashboard, rusted, signage
- Elegido: phosphor — no el papel carbón. La caja de Maravillas bajo el fluorescente.
- Paleta:
#101510tubo apagado (ground)#D8F0C8fósforo de lectura (ink)#161C16tecla (card)#8FD36Afósforo (mark)#7E9174mute#E24B4BLED anulado (poco)
- Tipo: IBM Plex Mono importes/códigos · Karla UI
Home foto-led (D-P1-09)
No. H-TABLE staff. La cuota last 6 ya está cubierta. UI-01 = cinta densa, no split DERIVA.
Alcance L2 must
- Home tabla: 4 líneas + 3 métricas (cobrado / pendiente / anulado)
- Apuntar una línea (concepto, importe, forma)
- Anular una línea pendiente (F-EDIT)
- Success con código TAL-XXXX
- Login JWT TITULAR
- Cierre del día (mesa) — no kanban
- Empty / error / loading / mobile
- ≥12 UX + ≥10 UI
Microcopy duro
- Apuntar ≠ hacer la cuenta en el móvil. No hay Excel en la caja.
- Talón ≠ factura. No es un modelo fiscal.
- Cerrar el día ≠ Hacienda. No se declara cumplimiento.
- TALÓN no es Excel.
Supuestos
- S1: La parada atiende 4–12 líneas/mañana en el slice; demo 4. [SUPUESTO]
- S2: Cualquiera en la parada apunta sin cuenta. JWT solo TITULAR. [SUPUESTO]
- S3: Sin pagos online, sin AEAT, sin TicketBAI, sin SKU, sin stock. [DECISIÓN]
- S4: Tetuán / Maravillas es atrezzo, no una parada real. [SUPUESTO de parada]
Hipótesis
| ID | Señal |
|---|---|
| H1 | Una cinta de líneas reduce «¿cuánto llevamos?» en el móvil de notas |
| H2 | Anular en el talón evita tachar a bolígrafo y perder el recuento |
| H3 | Cuatro líneas bastan para el iPad de la parada; no hace falta Excel |
Seed demo
| Código | Concepto | Importe | Forma | Estado |
|---|---|---|---|---|
| TAL-2901 | Ramo mixto | 12,00 € | efectivo | COBRADO |
| TAL-2902 | Planta crasa | 8,00 € | bizum | COBRADO |
| TAL-2903 | Corona blanca | 35,00 € | efectivo | PENDIENTE |
| TAL-2904 | Maceta devuelta | -6,00 € | efectivo | ANULADO |
Objetos son catálogo demo. No es una parada real. [SUPUESTO de parada]
Métricas: cobrado 2 · pendiente 1 · anulado 1. Suma cobrada demo: 20,00 €. [SUPUESTO]
JWT
remedios@talon.parada / password123 · rol TITULAR · API :3029
00-paper-reference.md
Paper reference · TALÓN
| URL | https://app.paper.design/file/01M165CVX37R8QSKBG37N0QRS4 |
| File ID | 01M165CVX37R8QSKBG37N0QRS4 |
UX-count: 12 UI-count: 12
UX process (prefijo UX- · mínimo 12)
| ID | Nombre | Contenido |
|---|---|---|
| UX-00 | Cover | Identidad phosphor, terna, parada Tetuán · Maravillas |
| UX-01 | Stakeholders | Remedios TITULAR, ayudante de parada |
| UX-02 | Personas | Remedios Gil / ayudante / a11y |
| UX-03 | JTBD | Funcional / emocional / social |
| UX-04 | Stories | Must hoy / apuntar / anular / cierre |
| UX-05 | Journey | Apuntar → cinta → anular → cerrar el día |
| UX-06 | Blueprint | Frontstage / caja / Neon / 409 |
| UX-07 | Site map | S-SIDE Hoy · Apuntar · Cierre |
| UX-08 | Flujos | POST lineas + anular + JWT |
| UX-09 | Datos + permisos | Linea / User TITULAR |
| UX-10 | Métricas | North star «¿cuánto llevamos?» sin móvil de notas |
| UX-11 | Research notes | COMPROBADO / SUPUESTO / HIPÓTESIS / DECISIÓN |
UI producto (prefijo UI- · mínimo 10)
| ID | Nombre | Flujo |
|---|---|---|
| UI-01 | Hoy | Home H-TABLE cinta · FOLD-TABLE |
| UI-02 | Apuntar | F-EDIT apuntar línea |
| UI-03 | Success | TAL-XXXX copy duro |
| UI-04 | Login | JWT TITULAR |
| UI-05 | Cierre | Mesa del día · no kanban |
| UI-06 | Empty | Sin líneas aún |
| UI-07 | Error | 409 / red |
| UI-08 | Loading | Skeletons |
| UI-09 | Tokens | G-PHOSPHOR |
| UI-10 | Anular | F-EDIT anular pendiente |
| UI-11 | Mobile hoy | Core 390 |
| UI-12 | Mobile apuntar | Form 390 |
01-project-definition.md
01 — Definición de proyecto — TALÓN
1. Identidad
| Campo | Valor |
|---|---|
| Nombre | TALÓN |
| Significado | El talón es la cinta del día en la caja de la parada: se apunta, se anula, se cierra. No es una hoja de cálculo ni una factura. |
| Eslogan | «El talón, no Excel.» |
| Una frase | Cinta de líneas del día + apuntar / anular + cierre TITULAR JWT. |
| Sector | Contabilidad / parada de mercadillo (Tetuán · Maravillas, Madrid) |
| Tipo | Web L2 — home H-TABLE FOLD-TABLE + chrome S-SIDE + flujo F-EDIT + cierre JWT — Nivel 2, vertical slice de libro de caja |
| Plataforma | Web responsive (tabla en el iPad de la parada · rail en el portátil) |
| Mercado demo | España · Madrid · Tetuán / Maravillas (una parada, no un ERP) |
| Idioma | es-ES |
| Fecha caso | 2026-08-29 |
| Terna | R-IN · S-SIDE · H-TABLE · F-EDIT |
| Fold | FOLD-TABLE |
[COMPROBADO] Nombre, terna, nivel, sector, ground y paleta salen de docs/00-day-brief.md.
[SUPUESTO de parada] Tetuán / Maravillas / ramo / planta / corona / maceta son atrezzo de mercado, no una parada real ni un acuerdo municipal.
Tras MANTA (L1 merendero, 2026-08-28) el día elige L2 libro de caja, no otro L1 consecutivo. N−1 es MANTA. [DECISIÓN]
2. Problema
Principal (hipótesis de diseño)
[HIPÓTESIS] Quien atiende la parada no necesita un ERP ni un Excel compartido: necesita apuntar lo cobrado y lo pendiente y saber cuánto lleva el día sin abrir el móvil de notas. Hoy eso vive en un talonario de papel, un WhatsApp o una hoja que se pierde al cerrar. Apuntar se lee como «hacer la cuenta en el móvil»; el talón se lee como factura; cerrar el día se lee como declarar a Hacienda; el producto se lee como Excel. [SUPUESTO] Una parada de mercadillo atiende 4–12 líneas/mañana; no opera un SKU ni un TicketBAI.
Secundarios
| Problema | Quién lo sufre | Efecto |
|---|---|---|
| «¿Cuánto llevamos?» en notas del móvil | Ayudante + TITULAR | Recuento a ojo; errores al cierre |
| Apuntar se lee como cuenta en el móvil | Ayudante | Esperan calculadora / Excel / app bancaria |
| Anular se lee como borrar sin rastro | TITULAR | Tachan a bolígrafo y pierden el recuento |
| Cerrar el día se lee como Hacienda | TITULAR | Esperan AEAT, TicketBAI, modelo fiscal |
| El cierre se lee como kanban | TITULAR | Esperan Recibido / En curso / Cerrado |
| El dueño pide pagos online y stock el día 1 | Parada | El L2 se vuelve TPV + inventario |
Supuestos (no investigación primaria propia)
- S1: La parada atiende 4–12 líneas/mañana en el slice; demo 4. [SUPUESTO]
- S2: Cualquiera en la parada apunta sin cuenta. JWT solo TITULAR. [SUPUESTO]
- S3: Sin pagos online, sin AEAT, sin TicketBAI, sin SKU, sin stock. [DECISIÓN]
- S4: Tetuán / Maravillas es atrezzo, no una parada real. [SUPUESTO de parada]
Hipótesis de producto
| ID | Hipótesis | Señal de validación (futura) |
|---|---|---|
| H1 | Una cinta de líneas reduce «¿cuánto llevamos?» en el móvil de notas | % de visitas a / que consultan cobrado/pendiente sin abrir notas |
| H2 | Anular en el talón evita tachar a bolígrafo y perder el recuento | POST /api/lineas/anular sobre PENDIENTE; métricas coherentes |
| H3 | Cuatro líneas bastan para el iPad de la parada; no hace falta Excel | 0 hoja de cálculo; Remedios opera 4 líneas |
No se afirman estadísticas de mercadillo inventadas. Todo lo anterior es razonamiento de diseño etiquetado.
3. Propuesta de valor
| Para | Valor |
|---|---|
| AYUDANTE (quien apunta) | Ve la cinta del día, apunta una línea (concepto, importe, forma), ve el código. Nadie le pide cuenta ni le abre Excel. |
| TITULAR (Remedios Gil) | Ve el cierre del día (cobrado / pendiente / anulado). No mueve columnas. No declara a Hacienda. |
| LECTORA MAYOR (a11y) | Fuera del login forzado; la documentación y a11y la contemplan (contraste fósforo/tubo, targets, copy legible). |
| Parada TALÓN | Una superficie mínima: hoy + apuntar + anular + cierre, sin Excel y sin AEAT. |
No es TALÓN
| Excluido | Por qué |
|---|---|
| Excel / hoja de cálculo / pivot | TALÓN no es Excel |
| Factura / modelo fiscal | Talón ≠ factura |
| Declaración AEAT / TicketBAI | Cerrar el día ≠ Hacienda |
| Cuenta en el móvil / calculadora bancaria | Apuntar ≠ hacer la cuenta en el móvil |
| Pagos online / TPV cloud / Bizum gateway | S3 · forma de pago es etiqueta, no pasarela |
| Stock / SKU / catálogo | S3 · H3 |
| Kanban de caja | ≠ PREGÓN |
| Merendero / trastos / REGIDORA | ≠ MANTA |
| Taller de bicis / ganchos / MECANICO | ≠ PIÑÓN |
| Hero 2-col + panel foto (AP-25 / FOLD-SPLIT) | Staff spreadsheet omite foto-led (D-P1-09); FOLD-TABLE |
| App de contabilidad multi-empresa | L2 compacto, no ERP |
4. Objetivos
Negocio / caso de estudio
- Demostrar vertical slice L2 libro de caja de parada con Linea + JWT TITULAR.
- Portfolio coherente: Paper (12 UX + 12 UI) + docs + app runnable (contrato).
- Terna R-IN · S-SIDE · H-TABLE · F-EDIT frente a MANTA (bottom/map/mkt), PIÑÓN (top/bento/cmp) y BOBINA (dock/feed/story).
- No encadenar otro L1 tras MANTA. [DECISIÓN]
Usuario
| Rol | Objetivo medible en demo |
|---|---|
| AYUDANTE | Ver 4 líneas, apuntar una y ver el success en < 90 s, sin cuenta |
| TITULAR | Entrar a cierre, ver cobrado / pendiente / anulado en < 45 s |
| LECTORA MAYOR | No encuentra login forzado en Hoy/Apuntar; a11y y docs la contemplan; no es rol de sistema |
No objetivos v1 (explícitos)
- Pagos online, pasarela, escrow, TPV
- AEAT, TicketBAI, factura electrónica, IVA automático
- Stock, SKU, inventario, códigos de barras
- Excel export, pivot, multi-hoja
- Cuenta de ayudante, socio, newsletter
- Multi-parada, multi-titular
- App nativa ni notificaciones push
- Rol cliente autenticado
- Trastos, REGIDORA,
manta-api(MANTA es otro día) - Bicis, ganchos, MECANICO,
pinon-api(PIÑÓN es otro día)
5. Roles y permisos (resumen)
| Acción | Anónimo (ayudante) | TITULAR | LECTORA MAYOR |
|---|---|---|---|
Ver Hoy / | Sí | Sí | Sin cuenta; usa la pública |
Ver Apuntar /apuntar | Sí | Sí | — |
| POST apuntar línea | Sí | Sí | Sí (mismo form público) |
| POST anular pendiente | Sí si PENDIENTE | Sí | Sí |
Ver success /ok/:code | Sí (código en URL) | Sí | — |
Ver cierre /cierre | No (401 / redirect) | Sí | No |
GET /api/mesa | 401 | Sí | — |
| Ver detalle de cierre | No | Sí (mesa) | — |
| Cobrar online / AEAT | No (no existe) | No | Fuera |
| Stock / SKU | Copy: fuera | Copy: fuera | Oficio fuera de app |
[DECISIÓN] Un solo rol autenticado: TITULAR. Quien apunta no es un usuario del sistema: es autora de una linea. La lectora mayor no es un rol de sistema el día 1.
6. Métricas (modelo, no instrumentadas en v1 salvo base)
| Tipo | Métrica | Definición |
|---|---|---|
| North Star | % de consultas «¿cuánto llevamos?» resueltas en la cinta sin móvil de notas | Oficio de talón, no pageviews |
| Activación | 1.er POST /api/lineas exitoso | H1 |
| Integridad de anulación | POST anular sobre no-PENDIENTE → 409 | H2 |
| Integridad de auth | GET /api/mesa sin token → 401; POST lineas sin token → 201 | Cinta pública + cierre TITULAR cerrado |
| Integridad de importe | Suma cobrada coherente con estados COBRADO | Seed demo 20,00 € |
| Salud | Error rate API lineas | 4xx/5xx |
7. Alcance funcional v1 (L2)
| Módulo | Incluido |
|---|---|
| Home cinta | GET /api/lineas · tabla a muro + 3 métricas (cobrado / pendiente / anulado) + 4 líneas |
| Apuntar | /apuntar · concepto, importe, forma · POST /api/lineas |
| Anular | F-EDIT sobre Hoy · una línea PENDIENTE · POST /api/lineas/anular · 409 si no PENDIENTE |
| Success | /ok/:code · código + 4 oposiciones |
| Auth | POST /api/auth/login → JWT TITULAR |
| Cierre TITULAR | GET /api/mesa JWT · cobrado / pendiente / anulado, no kanban |
| Estados UI | Empty (0 líneas), loading skeleton, error de red, 409 |
| Mobile | Hoy ~390px · S-SIDE Hoy · Apuntar · Cierre · targets ≥44px |
| Seed | 1 TITULAR, 4 líneas (2 COBRADO, 1 PENDIENTE, 1 ANULADO) |
| Salud | GET /api/health → { ok: true, service: "talon-api" } |
8. Criterios de aceptación de producto
/es la cinta H-TABLE (tabla a muro + 3 métricas + 4 líneas). No pide cuenta. No es un hero+panel split (AP-25). No es un feed. No es un plano foto-led. No es un bento.- Quien apunta puede ver 4 líneas, apuntar una y obtener success en
/ok/TAL-XXXX, o anular una PENDIENTE. /ok/:codedice explícitamente que apuntar no es hacer la cuenta en el móvil y que talón no es factura.- La UI dice explícitamente que cerrar el día no es Hacienda y que TALÓN no es Excel.
- Sin token, GET
/api/mesaresponde 401. POST/api/lineas, POST/api/lineas/anulary GET/api/lineasson públicos. - Un POST de apuntar no crea user, no cobra online, no abre factura, no mueve kanban, no declara a AEAT.
- Un POST de anular sobre no-PENDIENTE responde 409. Una línea. Sin bulk.
- Una TITULAR inicia sesión y ve 4 líneas (2 COBRADO, 1 PENDIENTE, 1 ANULADO) en el seed.
- El tablero autenticado es un cierre del día. No es un kanban de 3 columnas. No es un split lista | ficha foto.
- Chrome S-SIDE: Hoy · Apuntar · Cierre. Home sin bottom de merendero y sin top de taller.
- Rutas solo las del doc 03. No existen
/excel,/factura,/aeat,/stock. GET /api/healthdevuelveservice: "talon-api"(nomanta-api, nopinon-api).- TAL-2901 y TAL-2902 aparecen COBRADO; TAL-2903 PENDIENTE; TAL-2904 ANULADO; suma cobrada demo 20,00 €.
- Staff FOLD-TABLE omite foto-led (D-P1-09). No se diseña hero+panel (AP-25).
9. Stack y artefactos
| Capa | Detalle |
|---|---|
| Frontend | Angular + Tailwind · puerto 4200 |
| Backend | NestJS · puerto 3029 |
| DB | Neon PostgreSQL · project cool-cloud-04708830 (DATABASE_URL) |
| Auth | JWT (TITULAR) |
| Diseño | Paper 01M165CVX37R8QSKBG37N0QRS4 |
| Repo app | /Users/cristian/orca/talon-app/ · GH Criscode2022/talon-app |
| Package | pnpm |
[COMPROBADO] Puerto, Paper file ID, path de app, Neon y GH constan en el encargo.
El código vive (o vivirá) en talon-app con este contrato. Este doc es la fuente de verdad del slice L2. La app puede no existir aún; el contrato no se finge como runtime verde. [DECISIÓN]
10. Riesgos y mitigaciones
| Riesgo | Impacto | Mitigación v1 |
|---|---|---|
| Expectativa de Excel | «¿Dónde exporto?» | Copy «TALÓN no es Excel» |
| Expectativa de factura | Modelo fiscal | Copy «Talón ≠ factura» |
| Expectativa de Hacienda | AEAT, TicketBAI | Copy «Cerrar el día ≠ Hacienda» |
| Expectativa de cuenta móvil | Calculadora / Bizum app | Copy «Apuntar ≠ hacer la cuenta en el móvil» |
| Expectativa de kanban | Recibido / En curso | Cierre del día, no columnas de flujo |
| Leftover MANTA | trastos, REGIDORA, manta-api, plaza | Contrato TALÓN; health talon-api; 0 copy de merendero |
| Leftover PIÑÓN | bicis, MECANICO, ganchos | Dominio lineas + TITULAR |
| Pagos online el día 1 | Alcance L3 disfrazado | S3; H3: cuatro líneas |
| Stock el día 1 | Alcance inventario | S3 |
| Cuenta de ayudante | Rompe S2 | Sin signup; POST público |
| Home percibida como landing | Pérdida de H-TABLE / AP-25 | Cinta densa FOLD-TABLE, no hero+panel |
| Home percibida como plano MANTA | Confundir con N−1 | Tabla, no H-MAP |
| Home percibida como bento | Confundir con PIÑÓN | Cinta, no H-BENTO |
| Anular COBRADO | Rompe H2 | 409 si no PENDIENTE |
| 0 líneas | Cinta vacía sin oficio | Empty «Aún no hay líneas.» |
| Notas del móvil en paralelo | H1 no se mide | North star etiquetada como modelo |
| Sello como texto de párrafo | Contraste WCAG | Sello #E24B4B pinta ANULADO/error; ink escribe |
11. Glosario
| Término | Definición en TALÓN |
|---|---|
| Talón | Cinta del día; el producto, no la factura |
| Línea | Entrada de caja (lineas); código TAL-XXXX |
| Código | TAL-XXXX; identifica la línea |
| Apuntar | POST /api/lineas; no es hacer la cuenta en el móvil |
| Anular | POST /api/lineas/anular; marca ANULADO si estaba PENDIENTE |
| Hoy | Superficie H-TABLE pública de líneas; cinta a muro |
| Cierre | Superficie JWT de Remedios (métricas del día, no kanban ni Hacienda) |
| Cobrado | Estado COBRADO |
| Pendiente | Estado PENDIENTE; se puede anular |
| Anulado | Estado ANULADO; LED sello |
| Success | Código (TAL-XXXX); no es una factura |
| S-SIDE | Chrome: Hoy · Apuntar · Cierre |
| TITULAR | Usuario autenticado que opera el cierre |
| AYUDANTE | Quien apunta; no tiene fila en users |
| Forma | efectivo / bizum (etiqueta; no pasarela) |
| Excel | Hoja de cálculo; fuera. TALÓN no es Excel |
| Factura | Modelo fiscal; fuera. Talón ≠ factura |
| Hacienda | AEAT / TicketBAI; fuera. Cerrar ≠ Hacienda |
| Phosphor | Mood: tubo, fluorescente de parada a las 21:00; no papel rosa carbón |
| Ground | Tubo apagado #101510 |
| Ink | Fósforo de lectura #D8F0C8 |
| Card | Tecla #161C16 |
| Mark | Fósforo #8FD36A |
| Mute | #7E9174 |
| Sello | #E24B4B, poco |
| FOLD-TABLE | Home tabla densa; omite foto-led |
12. Decisiones de diseño (cierre de brief)
| ID | Decisión | Alternativa descartada |
|---|---|---|
| D1 | Home = cinta H-TABLE FOLD-TABLE | Hero+panel (AP-25) · plano MANTA · bento PIÑÓN · feed BOBINA |
| D2 | Shell side Hoy · Apuntar · Cierre (S-SIDE) | Bottom de merendero · top de taller · dock de cineclub |
| D3 | Registro innovador denso: herramienta de caja, no landing (R-IN) | Papel rosa talonario (primer instinto) · botanical MANTA |
| D4 | Flujo F-EDIT (apuntar / anular una línea) | F-MKT, F-CMP, F-LEAD, carrito checkout |
| D5 | Mood phosphor | Bookish talonario crema (primer instinto), vehicle dashboard, rusted, signage |
| D6 | Un rol autenticado TITULAR | Multi-rol ayudante / cliente / contable |
| D7 | Status COBRADO / PENDIENTE / ANULADO | Kanban; «facturado»; «enviado a AEAT» |
| D8 | Ayudante sin cuenta | Signup, socio, usuario de caja |
| D9 | Cinta pública sin PII sensible de cierre | Tablero público enumerable de Hacienda |
| D10 | POST público de apuntar con concepto + importe + forma | Formulario de NIF + factura + stock |
| D11 | Ground G-PHOSPHOR #101510 | G-BONE, G-GRAPHITE, G-VELVET, G-STONE, papel rosa |
| D12 | Success en /ok/:code | Toast único sin pantalla |
| D13 | Apuntar en /apuntar; anular sheet sobre / (sin quinta ruta Must) | /anular/:code; wizard fiscal |
| D14 | Cierre TITULAR = métricas + líneas del día, no kanban ni split foto | Recibido / En curso / Cerrado; lista | ficha |
| D15 | Cinta pública + cierre JWT (no auth-first total) | Todo cerrado (rompería S2) · todo abierto (rompería cierre) |
| D16 | Sin pagos online / AEAT / stock | Pasarela + TicketBAI + inventario |
| D17 | Leftover MANTA/PIÑÓN no es el producto | Mantener trastos / REGIDORA / manta-api / bicis |
| D18 | Health talon-api · puerto 3029 | leftover manta-api · :3028 |
| D19 | Anular = solo PENDIENTE; 409 si no | Soft-delete libre; anular COBRADO |
| D20 | Staff omite foto-led (D-P1-09); FOLD-TABLE | FOLD-SPLIT / hero+panel AP-25 |
13. Relación con el día anterior
| Case | Terna | Por qué TALÓN no lo copia |
|---|---|---|
| MANTA (N−1) | R-CL · S-BOTTOM · H-MAP · F-MKT | No merendero, no plano, no bottom, no trastos, no REGIDORA |
| PIÑÓN (N−2) | R-HY · S-TOP · H-BENTO · F-CMP | No taller, no ganchos, no bento, no configurador, no MECANICO |
| BOBINA (N−3) | R-IN · S-DOCK · H-FEED · F-STORY | Comparte R-IN; no cineclub, no feed, no dock, no butaca |
| LOMO (N−4) | R-CL · S-CMD · H-DATA · F-LEAD | No archivo, no ejemplares, no comando; H-TABLE de caja ≠ mesa de datos de biblioteca |
| CESTA | R-CL · S-RAIL · H-TABLE · F-LEAD | Comparte H-TABLE; aquí F-EDIT de caja, no despensa ONG |
| MATIZ | R-HY · S-BOTTOM · H-BENTO · F-EDIT | Comparte F-EDIT; aquí S-SIDE + H-TABLE phosphor, no editor de gramos |
[COMPROBADO] El brief fija terna R-IN · S-SIDE · H-TABLE · F-EDIT. 0 códigos iguales a N−1 (MANTA). ≥2 distintos vs N−2 (PIÑÓN) y N−3 (BOBINA). S-SIDE, H-TABLE y F-EDIT no están en los últimos 5. Ground G-PHOSPHOR #101510, no G-BONE ni papel rosa carbón.
02-ux-research-strategy.md
02 — Estrategia de investigación UX — TALÓN
Importante: este documento contiene artefactos de diseño y razonamiento secundario.
No hay entrevistas de campo primarias ni estadísticas inventadas presentadas como dato medido.
Etiquetas: [COMPROBADO] en producto, [SUPUESTO], [HIPÓTESIS], [DECISIÓN].
1. Objetivos de investigación (del caso)
| Objetivo | Método en este caso | Salida |
|---|---|---|
| Entender actores de la parada de mercadillo | Modelado de stakeholders + personas | §3–4 |
| Definir job «apuntar y saber cuánto llevamos sin notas del móvil» | JTBD + stories Must | §5–6 |
| Mapear fricción Excel / factura / Hacienda / notas → cinta + F-EDIT | Journey + service blueprint | §7–8 |
| Traducir a requisitos L2 hoy + apuntar + anular + cierre | Matriz hallazgo → requisito → feature | §9 |
2. Fuentes y límites
Fuentes admisibles (secundarias / operativas)
- Conocimiento general de paradas de mercadillo (talonario, efectivo/bizum, cierre de mañana, 4–12 líneas, iPad o móvil en la caja).
- Analogía operativa con superficie pública + panel JWT de la serie daily.
- Restricciones ALS-2: no Excel, no factura, no Hacienda, no merendero, no taller de bicis, no foto-led staff (D-P1-09).
Límites éticos de verdad
| Prohibido | Permitido |
|---|---|
| «El 58% de paradas de Tetuán pierde el recuento» sin fuente | «[SUPUESTO] Remedios abre Hoy en el iPad» |
| Citas de entrevistas ficticias como campo real | Quotes de persona etiquetadas como constructo de diseño |
| Volumen medido «22 ramos/semana» como KPI de mercado | Líneas de seed de producto, etiquetadas como demo |
| Parada municipal oficial en Maravillas 2026 | Parada de atrezzo; Remedios y el ayudante son personas de diseño |
| «Remedios existe y nos dijo…» | Remedios Gil es persona de diseño + cuenta demo |
3. Stakeholders
| Stakeholder | Influencia | Interés | Necesidad principal |
|---|---|---|---|
| TITULAR (Remedios) | Alta | Muy alta | Ver cobrado / pendiente / anulado sin Hacienda ni Excel |
| AYUDANTE (quien apunta) | Alta en el gesto | Muy alta | Apuntar una línea y ver el código, sin cuenta |
| LECTORA MAYOR (a11y) | Media formal, baja en producto día 1 | Alta | Leer la cinta con contraste y targets; sin login forzado |
| Parada / caja | Alta formal | Alta | Que se vea el día; que no se confunda con Excel ni factura |
| Excel / hojas | Competencia / analogía falsa | — | Fuera de alcance; no clonar pivot |
| Factura / AEAT | Analogía falsa de cierre | — | Fuera; Cerrar el día ≠ Hacienda |
| Cuenta móvil / calculadora | Analogía falsa de apuntar | — | Fuera; Apuntar ≠ cuenta en el móvil |
| MANTA / merendero | Anti-patrón N−1 | — | Fuera; no trastos, no REGIDORA, no manta-api |
| PIÑÓN / taller | Anti-patrón N−2 | — | Fuera; no bicis, no ganchos, no MECANICO |
| Notas del móvil / WhatsApp | Canal paralelo | — | No es el backoffice; H1 apunta a reducirlo |
| Contable externo | Fuera | — | Fuera del JWT |
Mapa de poder (resumen)
- Decisor de adopción: la titular de la parada (Remedios) y, en uso diario, quien mira el cierre.
- Usuario frecuente de apuntar/anular: AYUDANTE (cinta + form, sin cuenta).
- Usuario frecuente de oficio: TITULAR (cierre
/cierre). - Riesgo de rechazo: si el success parece una factura; si la cinta parece Excel; si hay que crear cuenta; si el cierre parece Hacienda o kanban; si anular borra sin rastro.
4. Personas
P1 — Remedios Gil · TITULAR
| Campo | Detalle |
|---|---|
| Edad / contexto | 52 años; titular de la parada TALÓN en Tetuán · Maravillas; cierre del día, no de Hacienda. Edad = constructo. |
| Digital | Fluida en el iPad / portátil de la caja; la cinta pública también la mira |
| Goals | Ver qué está cobrado, pendiente y anulado; cerrar el día sin Excel |
| Pains | Notas del móvil a deshora; «¿esto es una factura?»; un kanban que no es su oficio; AEAT el día 1 |
| Quote de diseño | «Quiero ver el talón del día. No una hoja de cálculo y no Hacienda.» |
| Email demo | remedios@talon.parada / password123 |
Escenario: Entra a /login, abre /cierre, lee TAL-2901 Ramo COBRADO, ve métricas. El copy dice que cerrar el día no es Hacienda.
[COMPROBADO] Nombre de cuenta, email demo y rol salen del encargo. Edad es constructo de diseño. [DECISIÓN]
P2 — Ayudante de parada · AYUDANTE
| Campo | Detalle |
|---|---|
| Edad / contexto | 28 años; ayuda en la parada; apunta ventas y pendientes; no quiere «otra cuenta de Excel». Edad = constructo. |
| Digital | iPad de la caja o móvil; no se registra si puede evitarlo |
| Goals | Ver la cinta; apuntar concepto + importe + forma; anular un pendiente; llevarse un código |
| Pains | El móvil de notas dice «creo que eran 12»; abre Excel; cree que emite factura |
| Quote de diseño | «Solo quiero apuntar la línea. No me hagas una factura.» |
| Nombre demo | Lucia Ayala (constructo; sin fila en users) |
Escenario: Abre / en el iPad, ve 4 líneas, toca Apuntar, escribe concepto e importe, lee «apuntar ≠ cuenta en el móvil» y el código TAL-XXXX.
[COMPROBADO] El gesto (apuntar sin cuenta) sale del encargo. Nombre del ayudante es constructo. Edad es constructo. [DECISIÓN]
Lucia no tiene fila en users. [DECISIÓN]
P3 — Lectora mayor · a11y (docs)
| Campo | Detalle |
|---|---|
| Edad / contexto | 68 años; puede mirar la cinta en la caja; contraste y tamaño importan. Edad = constructo de la serie a11y. |
| Digital | No tiene login en el slice L2; usa la superficie pública si el contraste y los targets aguantan |
| Goals | Entender cobrado / pendiente / anulado, sin mistificarse con Excel ni con Hacienda |
| Pains | Texto mute sobre tubo; botones pequeños; copy de ERP |
| Quote de diseño | «Si no leo el fósforo, no apunto. No me lo hagáis Excel.» |
[DECISIÓN] no hay cuenta de lectora mayor en v1; a11y la contempla en docs 10. Edad = constructo de diseño.
5. JTBD
Job principal (ayudante)
Cuando entra un cobro o un pendiente en la parada, quiero apuntarlo en la cinta sin abrir el móvil de notas, para que Remedios lo vea al cierre sin que eso signifique factura, Excel, cuenta ni Hacienda.
Job principal (titular)
Cuando hay líneas nuevas y hay que cerrar, quiero ver cobrado / pendiente / anulado, para cerrar el día sin un kanban ni un modelo fiscal.
Jobs que TALÓN no hace
| Job | Por qué no |
|---|---|
| Hacer la cuenta en el móvil | Apuntar ≠ cuenta en el móvil · S3 |
| Emitir factura | Talón ≠ factura |
| Declarar a Hacienda / TicketBAI | Cerrar el día ≠ Hacienda |
| Sustituir a Excel | TALÓN no es Excel |
| Cobrar online / TPV | S3 |
| Gestionar stock / SKU | S3 · H3 |
| Dejar un trasto en la manta | ≠ MANTA |
| Dejar una bici / configurar arreglo | ≠ PIÑÓN |
| Pedir butaca de cineclub | ≠ BOBINA |
6. Stories Must (v1)
| ID | Como | Quiero | Para |
|---|---|---|---|
| US-01 | Ayudante | Ver cinta H-TABLE de 4 líneas + 3 métricas | Distinguir talón de Excel / feed / plano / bento |
| US-02 | Ayudante | Apuntar una línea (concepto, importe, forma) y ver success TAL-XXXX | Dejar constancia, no facturar |
| US-03 | Ayudante | Anular una línea PENDIENTE (F-EDIT) | Evitar tachar a bolígrafo |
| US-04 | Ayudante | Recibir 409 si la línea no está PENDIENTE | No anular lo ya cobrado / ya anulado |
| US-05 | Titular | Entrar con JWT | Abrir el cierre del día |
| US-06 | Titular | Ver cobrado / pendiente / anulado | Oficio sin kanban ni Hacienda |
| US-07 | Ambos | Ver empty / error / loading | No quedarse en blanco |
| US-08 | Ayudante | Usar S-SIDE en 390 | Hoy · Apuntar · Cierre sin hamburger |
Could (fuera de L2 Must, solo L3/otro brief): pagos online, AEAT, login de lectora, export Excel, stock.
7. Journey (resumen)
- Lucia abre
/. Ve cinta a muro + 3 datos (cobrado / pendiente / anulado) + 4 líneas. TAL-2901 COBRADO; TAL-2903 PENDIENTE. [H1] - Toca Apuntar →
/apuntar. Concepto, importe, forma. POST/api/lineas→/ok/TAL-2905. Lee las cuatro oposiciones. [H3] - Alternativa: toca anular sobre TAL-2903 → sheet anular (UI-10). POST
/api/lineas/anular→ ANULADO. [H2] - Intento de anular TAL-2901 COBRADO → 409 «Esa línea no se puede anular.»
- Remedios entra a
/login→/cierre. Líneas por estado + métricas. - Lee suma cobrada y copy: cerrar el día ≠ Hacienda.
Backstage: Nest + Neon + JWT. Contable y AEAT no entran. No hay Excel. No hay factura.
8. Blueprint (resumen)
| Capa | Qué pasa |
|---|---|
| Frontstage (caja / iPad) | Cinta FOLD-TABLE. Form apuntar. Sheet anular. Success. S-SIDE. |
| Backstage (titular) | Remedios mira /cierre. El cierre físico es oficio, no un modelo fiscal. Hacienda y stock están fuera de app. |
| Soporte | Nest · Neon cool-cloud-04708830 · JWT TITULAR · Paper phosphor |
9. Matriz hallazgo → requisito → feature
| Hallazgo (etiquetado) | Requisito | Feature v1 |
|---|---|---|
| [HIPÓTESIS H1] Cinta reduce notas del móvil | 4 líneas + 3 métricas en fold tabla | / H-TABLE FOLD-TABLE |
| [HIPÓTESIS H2] Anular evita tachar a bolígrafo | POST anular de un código PENDIENTE; 409 si no | UI-10 · POST /api/lineas/anular |
| [HIPÓTESIS H3] Cuatro líneas bastan | Sin Excel | Seed 4 · no hoja |
| [SUPUESTO S2] Sin cuenta de ayudante | POST público | POST /api/lineas + anular |
| [SUPUESTO S1] 4–12 / mañana | Demo 4 | Seed TAL-2901…2904 |
| [DECISIÓN S3] Sin pagos online / AEAT / stock | No pasarela, no TicketBAI, no SKU | Fuera de alcance · L3 |
10. Preguntas que este case no responde
- ¿Cuántas líneas reales se apuntan en Maravillas en 2026?
- ¿Qué asociación de mercadillo opera un talón oficial?
- ¿Lucia preferiría el móvil de notas?
- ¿Remedios cerraría antes de las 14:00 de verdad?
- ¿Hace falta export a Excel para el contable?
Esas preguntas piden campo. Aquí hay un vertical slice de diseño, no un estudio.
11. Cierre
Investigación = modelado etiquetado + restricciones ALS-2.
No hay entrevistas inventadas.
Paper UX-00…11 documenta el mismo arco. [COMPROBADO] inventario en 00-paper-reference.md.
03-information-architecture.md
03 — Arquitectura de información — TALÓN
1. Principios de IA
| Principio | Aplicación |
|---|---|
| Cinta first | La home es tabla a muro + 3 datos + 4 líneas. No hay landing de marca por delante. No hay feed. No hay plano foto-led. No hay bento. |
| Público / cierre | Lucia apunta o anula sin cuenta; Remedios entra con JWT |
| Apuntar | anular → success | Profundidad 1–2 desde la cinta hasta el código (F-EDIT) |
| El núcleo es una línea | F-EDIT: una línea a la vez, sin bulk Excel |
| Cierre TITULAR = día | Cobrado / pendiente / anulado; no kanban, no split lista | ficha foto |
| Lenguaje de dominio | Línea, talón, hoy, cierre, apuntar, anular — no «SKU», «factura», «trasto», «gancho» |
| Apuntar no es cuenta móvil | El success no tiene calculadora ni extracto bancario |
| Talón no es Excel | No hay pivot, no hay hojas, no hay export Must |
| Chrome de caja | S-SIDE Hoy · Apuntar · Cierre; cinta sin bottom de merendero |
2. Sitemap
/ Hoy cinta pública (FOLD-TABLE) H-TABLE
+ sheet anular (UI-10) F-EDIT · público
/apuntar Apuntar una línea público
/ok/:code Success post-apuntar o post-anular público
/login Login JWT TITULAR público
/cierre Cobrado / pendiente / anulado auth
/** → redirect /
Árbol por audiencia
| Audiencia | Nodos relevantes |
|---|---|
| AYUDANTE | Hoy → Apuntar o Anular (sheet) → Ok. No ve /cierre |
| TITULAR | Login → Cierre · (puede leer Hoy y apuntar) |
| LECTORA MAYOR | Hoy / Apuntar públicos; sin login |
[COMPROBADO] Cinco rutas del encargo L2. No se inventan /excel, /factura, /aeat, /stock, /buscar.
Anular no es ruta extra Must: es el sheet UI-10 sobre / (tap línea PENDIENTE). L2 compacto. [DECISIÓN]
/ok/:code usa el código de línea (TAL-2903 en anular, TAL-2905 en apuntar nuevo). [DECISIÓN]
No hay /buscar: no hay S-CMD. El hallazgo es la cinta. [DECISIÓN]
No hay /linea/:code de ficha pública permanente: el oficio de estado vive en Hoy y en el cierre. Could L3. [DECISIÓN]
3. Navegación
Side (S-SIDE · superficies salvo login/ok pueden mostrarlo)
| Slot | Destino | Visibilidad | Notas |
|---|---|---|---|
| Hoy | / | Todos | Vuelve a la cinta. No es hero de marca |
| Apuntar | /apuntar | Todos | Entra al form de apuntar |
| Cierre | /cierre | TITULAR; si guest → /login?next=/cierre | Oficio JWT |
[DECISIÓN] El side es la navegación primaria. No hay bottom de merendero (MANTA), no hay top de taller (PIÑÓN), no hay dock (BOBINA), no hay comando (LOMO).
Desktop ≥960px: rail izquierdo fósforo; wordmark TALÓN arriba; slots Hoy · Apuntar · Cierre.
Mobile ~390px: rail colapsado a bottom/side compacto Hoy · Apuntar · Cierre; no hamburger. [DECISIÓN] En 390 el chrome no se esconde detrás de un menú. Padding del contenido ≥ altura/ancho del chrome.
Hoy pública (H-TABLE FOLD-TABLE)
| Elemento | Destino | Notas |
|---|---|---|
| Tabla a muro | — | Cinta densa; sin foto hero (D-P1-09) |
| Wordmark TALÓN | / | Sello mark sobre ground |
| Eslogan | — | «El talón, no Excel.» |
| 3 datos | — | Cobrado / Pendiente / Anulado (números del seed) |
| Fila de línea | sheet anular si PENDIENTE | 4 líneas; código, concepto, importe, forma, estado |
| Tap PENDIENTE | UI-10 sheet | Arranque de anular F-EDIT |
| Tap COBRADO / ANULADO | sello + copy; no POST anular | 409 si se fuerza |
| CTA Apuntar | /apuntar | S-SIDE o lead |
| Slot Cierre (mute) | /login o /cierre si hay token | Oficio, no CTA de marca |
[DECISIÓN] Hoy no tiene tabs de marketing, no tiene «Factura / Hacienda / Excel». La cinta basta para hallar.
Chrome de apuntar (/apuntar)
| Slot | Destino | Notas |
|---|---|---|
| ← Hoy | / | Un paso atrás, no stepper fiscal |
| Form | /apuntar | Concepto, importe, forma |
| Enviar | POST → /ok/:code | Una acción |
[DECISIÓN] Apuntar no es un modal efímero sin URL. No hay wizard de AEAT.
Chrome de anular (sheet sobre /)
| Slot | Destino | Notas |
|---|---|---|
| Cerrar | / | Conserva la cinta |
| Confirmación | mismo path | Código + concepto en solo lectura |
| Enviar | POST /api/lineas/anular → feedback / /ok/:code | Una línea |
| No PENDIENTE | 409 / disabled | «Esa línea no se puede anular.» |
Chrome de cierre (/cierre autenticado)
| Slot | Destino | Visibilidad | Notas |
|---|---|---|---|
| Cierre | /cierre | Auth | Titular de oficio |
| Métricas | — | Auth | Cobrado / pendiente / anulado + suma |
| Líneas | — | Auth | Agrupadas o listadas por estado |
| Hoy | / | Auth | Secundario vía S-SIDE |
| Salir | limpia token → / | Auth | Cabecera de cierre, no cuarto slot del side |
[DECISIÓN] No hay S-SPLIT foto+rail (AP-25 / LOMO FOLD-SPLIT). No hay kanban (PREGÓN). No hay /cierre/:code: L2 lee el día.
4. Etiquetas de IA (UI)
| Concepto | Label |
|---|---|
| Home | Hoy (no «Inicio», no «Plaza», no «Taller», no «Excel») |
| Flujo apuntar | Apuntar (no «facturar», no «cobrar online», no «exportar») |
| Flujo editar | Anular (no «borrar», no «eliminar fila Excel») |
| Success | Apuntado / Anulado / código |
| Staff | Cierre (no «Backoffice», no «Kanban», no «Hacienda») |
| Auth | Titular (no «Área cliente», no «Regidora», no «Mecánica») |
| CTA apuntar | Apuntar (no «Facturar», no «Guardar en Excel») |
| CTA anular | Anular (no «Borrar», no «Eliminar») |
En docs puede decirse «cinta Hoy» para H-TABLE y «cierre TITULAR» / «mesa» para el oficio JWT (/api/mesa). En UI pública el titular es Hoy. En UI autenticada el titular es Cierre. [DECISIÓN]
5. Contenido de cada nodo de IA
| Ruta | Qué hay | Qué no hay |
|---|---|---|
/ | Cinta, eslogan, 3 métricas, 4 líneas, S-SIDE, sheet anular | Precios de catálogo, login de ayudante, Excel, AEAT, trastos |
/apuntar | Concepto, importe, forma, disclaimer | NIF, email, pasarela, stock, socio |
/ok/:code | Código + 4 oposiciones | Factura, ticket fiscal, «ya está en Hacienda», QR de TPV |
/login | Email / clave TITULAR | Signup de ayudante |
/cierre | Métricas + líneas del día | Columnas Recibido / En curso; split foto; mapa |
6. Error / empty / loading (sitio)
Viven en las mismas rutas, no en URLs extra. Artboards: UI-06 empty · UI-07 error · UI-08 loading.
| Estado | Superficie |
|---|---|
| Loading | Skeletons de cinta + 3 datos + 4 filas / form apuntar / lista de cierre |
| Empty Hoy | «Aún no hay líneas.» |
| Empty cierre | «No hay líneas en el cierre.» (puede coexistir con empty Hoy) |
| Error red | «La red no responde» + Reintentar |
| 404 código | «Esa línea no está» en success |
| 409 anular | «Esa línea no se puede anular.» |
| Apuntar incompleto | CTA disabled · «Escribe el concepto.» / «Indica el importe.» |
7. Profundidad y hallazgo
No hay búsqueda Must: el hallazgo es la cinta de 4 líneas. Introducir /buscar copiaría LOMO y rompería la terna. [DECISIÓN]
Remedios no filtra el cierre con chips en v1: ve el día. Could L3: filtro; no se cuela como deuda del L2.
8. Códigos y URLs
| Pieza | Forma |
|---|---|
| Línea | TAL-2901 … TAL-2904 (TAL versales, guion, 4 dígitos) |
| Apuntar nuevo | TAL-2905+ secuencial al POST /api/lineas |
| Anular | mismo code de la línea PENDIENTE |
| Success | /ok/TAL-2903 o /ok/TAL-2905 |
9. Mapa Paper → rutas
| Artboard | Ruta | Componente |
|---|---|---|
| UI-01 Hoy | / | HoyPage |
| UI-11 Mobile hoy | / @390 | HoyPage |
| UI-02 Apuntar | /apuntar | ApuntarPage |
| UI-12 Mobile apuntar | /apuntar @390 | ApuntarPage |
| UI-10 Anular | / sheet | AnularSheet en HoyPage |
| UI-03 Success | /ok/:code | OkPage |
| UI-04 Login | /login | LoginPage |
| UI-05 Cierre | /cierre | CierrePage |
| UI-06 Empty | mismas rutas | estados |
| UI-07 Error | mismas rutas | estados |
| UI-08 Loading | mismas rutas | estados |
| UI-09 Tokens | theme | Tailwind |
[COMPROBADO] Mapeo alineado a docs/00-paper-reference.md.
04-user-flows.md
04 — Flujos de usuario — TALÓN
1. Convenciones
| Token | Significado |
|---|---|
| F-EDIT | Apuntar o anular una línea; la home es la cinta, no un wizard fiscal |
| Cierre / mesa | Oficio TITULAR, JWT · GET /api/mesa |
| 201 | Línea apuntada (nuevo) o anulada (PENDIENTE → ANULADO) |
| 400 | Concepto / importe / forma inválidos |
| 401 | Cierre sin token |
| 404 | Código inexistente |
| 409 | Anular una línea que no está PENDIENTE |
2. F1 — Ayudante apunta una línea (Must · F-EDIT)
/apuntar → escribe concepto «Ramo pequeño», importe 10,00, forma efectivo
→ POST /api/lineas { concepto, importe, forma }
→ 201 { code: TAL-2905, status: COBRADO|PENDIENTE, apuntado: true }
→ /ok/TAL-2905
Entrada: form público, sin cuenta.
Salida: código visible + copy «apuntar ≠ cuenta en el móvil».
Errores: red (reintentar), 400 validación, 0 líneas previas (empty de Hoy no bloquea apuntar).
AC
- El form no pide NIF, email, pasarela ni signup.
- POST no cobra online, no crea user, no abre factura, no mueve kanban, no declara AEAT.
- Una línea. Cero bulk. Cero segunda fila en el mismo POST.
/ok/TAL-2905muestra las cuatro oposiciones.- Status inicial demo por defecto: COBRADO si se marca cobrado en form, o PENDIENTE si queda a deber — en v1 el form incluye estado implícito por forma/cobro; seed usa ambos. [DECISIÓN] Form v1: concepto + importe + forma; status por defecto COBRADO salvo toggle «Pendiente de cobro». [DECISIÓN]
3. F2 — Ayudante anula una línea PENDIENTE (Must · F-EDIT)
/ → GET /api/lineas
→ ve 3 métricas + 4 líneas
→ tap TAL-2903 Corona PENDIENTE
→ sheet anular (UI-10)
→ confirma
→ POST /api/lineas/anular { code: "TAL-2903" }
→ 201 { code: TAL-2903, status: ANULADO, anulado: true }
→ /ok/TAL-2903 (o feedback en cinta + refresh)
AC
- Solo PENDIENTE. Cero anular COBRADO o ANULADO.
- POST no borra la fila: marca
ANULADOy conserva el rastro. [DECISIÓN] - Copy: no «eliminado» tipo Excel. No «borrado fiscal».
4. F3 — Ayudante intenta anular no-PENDIENTE (Must · 409)
/ → tap TAL-2901 Ramo COBRADO (o fuerza POST)
→ CTA Anular disabled o POST /api/lineas/anular
→ 409
→ copy «Esa línea no se puede anular.»
Mismo resultado si TAL-2904 ANULADO, o si se reintenta TAL-2903 tras un 201.
AC
- 409 si
status ≠ PENDIENTE. - Copy: no «agotado» retail. No «añadir a lista de espera».
- Lucia puede elegir otra PENDIENTE si existe, o apuntar nueva.
5. F4 — Titular entra a cierre (Must)
/login → POST /api/auth/login
→ JWT TITULAR
→ /cierre
→ GET /api/mesa
AC
- Sin token,
/cierreredirige a/login?next=/cierre. - GET
/api/mesasin Bearer → 401. - Día: 4 filas + métricas cobrado / pendiente / anulado + suma. No columnas Recibido / En curso.
- Desktop: rail + panel de cierre. 390: apilado sobre el chrome S-SIDE.
- ANULADO sí aparece (oficio de rastro). [DECISIÓN]
6. F5 — Estados de sistema
| Estado | Trigger | UI |
|---|---|---|
| Loading Hoy | GET lineas en vuelo | Skeletons de cinta + 3 datos + 4 filas (UI-08) |
| Empty Hoy | 200 { lineas: [] } | «Aún no hay líneas.» (UI-06) |
| Error Hoy | 5xx / red | Reintentar (UI-07) |
| Loading apuntar | — | Form listo; submit pending (UI-08) |
| Loading anular | POST en vuelo | pending en CTA |
| 409 | no PENDIENTE | «Esa línea no se puede anular.» (UI-07) |
| Loading cierre | GET mesa en vuelo | Skeletons de métricas + líneas |
| Empty cierre | 200 sin líneas | «No hay líneas en el cierre.» |
| Login 401 | credenciales | «Email o contraseña no valen.» |
| 404 success | código inexistente | «Esa línea no está.» |
7. Flujos que no existen
| Flujo | Por qué |
|---|---|
| Signup ayudante | S2 · Apuntar ≠ socio |
| Facturar / AEAT / TicketBAI | S3 · Talón ≠ factura · Cerrar ≠ Hacienda |
| Export Excel / pivot | TALÓN no es Excel |
| Cobrar online / TPV / pasarela | Forma = etiqueta · S3 |
| Stock / SKU / inventario | S3 · H3 |
| Chat | ≠ PREGÓN |
| Dejar trasto / llevarse | ≠ MANTA |
| Configurar arreglo / dejar bici | ≠ PIÑÓN |
| Pedir butaca | ≠ BOBINA |
| Login lectora mayor | Slice L2 · docs / a11y |
| PATCH libre de estado a Hacienda | Remedios lee el día; no declara |
Búsqueda ?q= | Sin S-CMD |
| Bulk anular / multi-línea | Rompe F-EDIT de una línea |
8. Tiempos de demo (modelo)
| Actor | Recorrido | Techo |
|---|---|---|
| Lucia (apuntar) | Apuntar → form → código | < 90 s |
| Lucia (anular) | Hoy → sheet → anulado | < 60 s |
| Lucia (409) | COBRADO → bloqueo → PENDIENTE | < 60 s |
| Remedios | Login → cierre → leer métricas | < 45 s |
No son KPIs medidos. Son techos de diseño para el guión. [HIPÓTESIS]
9. Guión de demo canónico
/— cinta a muro + 3 datos (2 cobrado / 1 pendiente / 1 anulado) + 4 líneas. Eslogan. S-SIDE.- Lectura rápida: TAL-2901 Ramo mixto 12,00 € efectivo COBRADO; TAL-2902 Planta crasa 8,00 € bizum COBRADO; TAL-2903 Corona blanca 35,00 € efectivo PENDIENTE; TAL-2904 Maceta devuelta -6,00 € efectivo ANULADO.
- Apuntar —
/apuntar· Ramo pequeño · 10,00 · efectivo ·/ok/TAL-2905. Copy ×4. - Anular — tap corona PENDIENTE · confirma · ANULADO.
- Reintento corona → 409.
/login—remedios@talon.parada/password123./cierre— métricas + líneas; suma cobrada demo 20,00 € (+ nuevos cobrados si se apuntó).- 390: cinta + S-SIDE; no carousel; targets ≥44px.
- API down: error + Reintentar.
10. Contratos de error de API (flujo)
| Caso | HTTP | UI |
|---|---|---|
| POST apuntar, concepto vacío | 400 | «Escribe el concepto.» |
| POST apuntar, importe inválido | 400 | «Indica el importe.» |
| POST apuntar, forma vacía | 400 | «Elige la forma.» |
| POST anular, code ausente | 400 | «Elige una línea.» |
| POST anular, no PENDIENTE | 409 | «Esa línea no se puede anular.» |
| POST, red | — | mark + Reintentar; no navega a ok |
| GET mesa sin JWT | 401 | redirect login |
| Login malo | 401 | copy de login |
GET /ok code 404 | 404 | «Esa línea no está.» |
11. S-SIDE en flujo
| Desde | Slot | Comportamiento |
|---|---|---|
/ | Hoy | aria-current |
/ | Apuntar | /apuntar |
/apuntar | Apuntar | aria-current |
/ok/:code | Hoy | Vuelve a la cinta |
/ guest | Cierre | /login?next=/cierre |
/ con token | Cierre | /cierre |
[DECISIÓN] El slot Apuntar no abre el sheet de anular; abre el form de apuntar. Anular arranca en la cinta sobre PENDIENTE.
05-data-model.md
05 — Modelo de datos — TALÓN
1. Visión general
Dominio L2 de libro de caja de parada + apuntar + anular autenticable:
| Entidad | Tabla SQL | Propósito |
|---|---|---|
| User | users | Identidad de oficio (rol TITULAR) |
| Session | sessions | Sesión JWT / token persistido |
| Linea | lineas | Entrada de caja (código TAL-XXXX, concepto, importe, forma, estado) |
Base: PostgreSQL (Neon project cool-cloud-04708830 · DATABASE_URL) · IDs: serial + texto estable (TAL-2901).
[DECISIÓN] ensureSchema es válido si el contrato de tablas se cumple; el brief de stack no exige Prisma.
Contrato de producto: lineas + JWT TITULAR.
No trastos / tratos / bicis / requests / sesiones / ejemplares.
2. Enums (aplicación; persistidos como TEXT + check)
Role
| Valor | Descripción |
|---|---|
TITULAR | Titular del cierre; único rol autenticado v1 |
LineaStatus
| Valor | Descripción |
|---|---|
COBRADO | Cobrado en el día |
PENDIENTE | Pendiente de cobro; se puede anular |
ANULADO | Anulado; rastro conservado |
Un POST de apuntar crea la línea en COBRADO (default) o PENDIENTE (toggle). [DECISIÓN]
Un POST de anular sobre PENDIENTE pasa la línea a ANULADO. [DECISIÓN]
Si status ≠ PENDIENTE → 409. [DECISIÓN]
Remedios no hace PATCH libre a AEAT en v1: el cierre es lectura del día. [DECISIÓN]
FormaPago (etiqueta)
| Valor | Descripción |
|---|---|
efectivo | Efectivo en caja |
bizum | Etiqueta bizum; no es pasarela |
[DECISIÓN] Forma es texto controlado; no integra TPV ni API bancaria.
3. Diagrama ER (texto)
users
id, email, password_hash, name, role(TITULAR)
created_at
1 ──< sessions
sessions
id, user_id → users
expires_at, revoked_at
created_at
lineas
id
code (unique, TAL-XXXX)
concepto
importe (numeric; puede ser negativo en devolución seed)
forma (efectivo|bizum)
status (COBRADO|PENDIENTE|ANULADO)
sort_order
created_at, updated_at
v1: una sola TITULAR opera sobre el conjunto global del día demo.
No hay FK de ayudante-usuario: quien apunta no se loguea.
4. Tablas
users
| Columna | Tipo | Notas |
|---|---|---|
| id | BIGSERIAL PK | |
| TEXT UNIQUE | remedios@talon.parada | |
| password_hash | TEXT | bcrypt 12 |
| name | TEXT | Remedios Gil |
| role | TEXT | TITULAR |
| created_at | TIMESTAMPTZ |
sessions
| Columna | Tipo | Notas |
|---|---|---|
| id | UUID PK | sid del JWT |
| user_id | BIGINT FK | |
| expires_at | TIMESTAMPTZ | |
| revoked_at | TIMESTAMPTZ | logout |
| created_at | TIMESTAMPTZ |
lineas
| Columna | Tipo | Notas |
|---|---|---|
| id | BIGSERIAL PK | |
| code | TEXT UNIQUE | TAL-2901 |
| concepto | TEXT | Ramo mixto · Planta crasa · Corona blanca · Maceta devuelta · o el del form |
| importe | NUMERIC(12,2) | 12.00 / 8.00 / 35.00 / -6.00 |
| forma | TEXT | efectivo | bizum |
| status | TEXT | COBRADO | PENDIENTE | ANULADO |
| sort_order | INTEGER | 1 = primera fila de la cinta |
| created_at / updated_at | TIMESTAMPTZ |
Sin NIF, sin email de cliente, sin pasarela, sin SKU, sin stock. Talón ≠ factura. [DECISIÓN]
Índices: lineas(code), lineas(status), lineas(sort_order), users(email), lineas(created_at DESC).
5. Seed
TITULAR
remedios@talon.parada / password123 · Remedios Gil · TITULAR
Hash bcrypt: el de implementación (mismo patrón serie; documentar en seed al build). [DECISIÓN]
Líneas
| code | concepto | importe | forma | status |
|---|---|---|---|---|
| TAL-2901 | Ramo mixto | 12,00 | efectivo | COBRADO |
| TAL-2902 | Planta crasa | 8,00 | bizum | COBRADO |
| TAL-2903 | Corona blanca | 35,00 | efectivo | PENDIENTE |
| TAL-2904 | Maceta devuelta | -6,00 | efectivo | ANULADO |
Métricas derivadas del seed: cobrado 2 · pendiente 1 · anulado 1.
Suma cobrada demo (solo COBRADO): 20,00 €. [SUPUESTO]
[SUPUESTO de parada] Conceptos e importes son atrezzo. No es una parada real.
[DECISIÓN] sort_order 1…4 = TAL-2901…2904.
Seed idempotente
El seed idempotente restaura las 4 líneas de catálogo (estados) para que el demo sea repetible. [DECISIÓN]
Re-seed no borra TAL-2905+ salvo flag explícito de demo. [DECISIÓN]
6. JSON (camelCase)
API: sortOrder, createdAt, cobrado, pendiente, anulado, sumaCobrada, status, concepto, importe, forma, code.
SQL: sort_order, created_at.
GET /api/lineas
{
"metrics": { "cobrado": 2, "pendiente": 1, "anulado": 1, "sumaCobrada": 20.00 },
"lineas": [
{
"code": "TAL-2901",
"concepto": "Ramo mixto",
"importe": 12.00,
"forma": "efectivo",
"status": "COBRADO",
"sortOrder": 1
}
]
}
Lista pública: métricas + líneas del día. [DECISIÓN]
Métricas cuentan los tres estados; sumaCobrada suma importes con status COBRADO. [DECISIÓN]
GET /api/lineas/:code [DECISIÓN] soporte de success
Mismo shape de item; 404 si no existe.
POST /api/lineas (apuntar)
Request:
{ "concepto": "Ramo pequeño", "importe": 10.00, "forma": "efectivo", "status": "COBRADO" }
concepto obligatorio, trim, min 2. importe number (permite negativo en devoluciones). forma ∈ {efectivo, bizum}. status opcional ∈ {COBRADO, PENDIENTE}; default COBRADO. [DECISIÓN]
Response 201:
{
"code": "TAL-2905",
"concepto": "Ramo pequeño",
"importe": 10.00,
"forma": "efectivo",
"status": "COBRADO",
"apuntado": true
}
Algoritmo: INSERT linea (code siguiente). Transacción única. [DECISIÓN]
POST /api/lineas/anular (anular)
Request:
{ "code": "TAL-2903" }
Response 201:
{
"code": "TAL-2903",
"concepto": "Corona blanca",
"importe": 35.00,
"forma": "efectivo",
"status": "ANULADO",
"anulado": true
}
Algoritmo: SELECT FOR UPDATE por code; si no existe → 404; si status ≠ PENDIENTE → 409; UPDATE status ANULADO. Transacción única. [DECISIÓN]
GET /api/mesa (JWT)
{
"metrics": { "cobrado": 2, "pendiente": 1, "anulado": 1, "sumaCobrada": 20.00 },
"lineas": {
"COBRADO": [ /* … */ ],
"PENDIENTE": [ /* … */ ],
"ANULADO": [ /* … */ ]
},
"titular": { "name": "Remedios Gil", "email": "remedios@talon.parada" }
}
7. Reglas de integridad
| Regla | Detalle |
|---|---|
| Unicidad de código | lineas.code UNIQUE |
| Anular solo PENDIENTE | Si status ≠ PENDIENTE → 409 |
| Apuntar no escribe ANULADO | POST lineas no crea ANULADO directo |
| Sin user en línea | No FK a users desde lineas |
| Cierre privado | GET /api/mesa exige JWT role TITULAR |
| Cinta pública | GET /api/lineas sin auth |
| Una línea | Body de anular = un code; no array |
8. Fuera del modelo v1
| Concepto | Por qué fuera |
|---|---|
| NIF / factura / IVA | Talón ≠ factura · Cerrar ≠ Hacienda |
| Email del cliente | Minimización; S2 |
| Pasarela / TPV | Forma = etiqueta · S3 |
| Stock / SKU | S3 · H3 |
Tabla trastos / tratos | Leftover MANTA |
Tabla bicis / requests | Leftover PIÑÓN |
| PATCH a AEAT | Cierre de lectura |
| Bulk / Excel rows | H3 · F-EDIT |
| Multi-tenant parada | L2 compacto |
9. Naming vs leftover
| Prohibido (leftover) | Contrato TALÓN |
|---|---|
trastos / tratos / mantas | lineas / talón / hoy |
| REGIDORA | TITULAR |
manta-api / pinon-api | talon-api |
| MNT-XXXX / PIN-XXXX | TAL-XXXX |
| LIBRE / PEDIDO / ENTREGADO | COBRADO / PENDIENTE / ANULADO |
| puerto 3028 / 3027 | 3029 |
/dejar / /encargo | /apuntar + sheet anular |
06-tech-stack.md
06 — Stack técnico — TALÓN
1. Resumen
| Capa | Elección | Notas |
|---|---|---|
| Frontend | Angular (standalone) + Tailwind | Puerto 4200 |
| Backend | NestJS | Puerto 3029 · prefijo /api |
| DB | Neon PostgreSQL | Project cool-cloud-04708830 · DATABASE_URL |
| Auth | JWT Bearer | Rol TITULAR |
| Package | pnpm | Apps independientes (pnpm --filter) |
| Diseño | Paper | File 01M165CVX37R8QSKBG37N0QRS4 |
| Repo | /Users/cristian/orca/talon-app | GH Criscode2022/talon-app |
[COMPROBADO] Angular + NestJS + Neon + Tailwind, puerto API 3029, Paper file ID, Neon y path de app salen del encargo.
La app puede no existir aún; este doc fija el contrato, no un runtime fingido. [DECISIÓN]
2. Por qué este stack
| Decisión | Razón | Alternativa descartada |
|---|---|---|
| Angular standalone | Coherencia serie ALS-2 daily | Next/React (rompería espejo de cases) |
| NestJS | Mismo contrato API que MANTA/PIÑÓN | Express suelto sin módulos |
| Neon | Postgres managed; project dedicado TALÓN | SQLite local (no portfolio cloud) |
| Tailwind | Tokens phosphor rápidos | CSS modules sin design tokens |
| JWT | Cierre cerrado; cinta abierta | Session cookie-only sin Bearer documentado |
| pnpm filter | Monorepo ligero sin npm workspaces | Turborepo pesado para L2 |
3. Puertos y health
| Servicio | Puerto | Health |
|---|---|---|
| API | 3029 | GET /api/health → { ok: true, service: "talon-api" } |
| Web | 4200 | Angular dev server |
Leftover manta-api / puerto 3028 / pinon-api no son el producto. [DECISIÓN]
4. Estructura de repo (contrato)
talon-app/
apps/
api/ NestJS · PORT=3029
web/ Angular · 4200
package.json pnpm workspaces o filter
Proxy web → API en dev (/api → http://localhost:3029). [DECISIÓN]
5. Variables de entorno (API)
| Variable | Uso |
|---|---|
DATABASE_URL | Neon connection string (project cool-cloud-04708830) |
JWT_SECRET | Firma HS256 |
PORT | 3029 |
NODE_ENV | development / production |
No commitear secretos. .env local; ejemplo en .env.example sin credenciales reales. [DECISIÓN]
6. Auth
| Pieza | Detalle |
|---|---|
| Login | POST /api/auth/login { email, password } |
| Hash | bcrypt 12 |
| Token | JWT · claims sub, email, role: TITULAR |
| Guard | Bearer en GET /api/mesa |
| Público | health, lineas, lineas/:code, POST lineas, POST lineas/anular, login |
| Storage web | localStorage o memory + interceptor; logout limpia |
[COMPROBADO] Credenciales demo: remedios@talon.parada / password123.
7. Endpoints (contrato)
| Método | Ruta | Auth | Respuesta clave |
|---|---|---|---|
| GET | /api/health | No | talon-api |
| GET | /api/lineas | No | metrics + array 4 |
| GET | /api/lineas/:code | No | item · soporte success [DECISIÓN] |
| POST | /api/lineas | No | 201 / 400 · apuntar |
| POST | /api/lineas/anular | No | 201 / 400 / 409 · anular |
| POST | /api/auth/login | No | { accessToken } |
| GET | /api/mesa | JWT | métricas + líneas agrupadas |
CORS: origen http://localhost:4200 en dev. [DECISIÓN]
8. Frontend — rutas y componentes
| Ruta | Componente | Guard |
|---|---|---|
/ | HoyPage (+ AnularSheet) | — |
/apuntar | ApuntarPage | — |
/ok/:code | OkPage | — |
/login | LoginPage | — |
/cierre | CierrePage | authGuard TITULAR |
Chrome: SideNavComponent (S-SIDE). Tokens Tailwind: ground, ink, card, mark, mute, sello.
9. Assets
| Origen case | Destino app |
|---|---|
2026-08-29-talon/assets/ | Cover UX / tokens si aplica |
Staff FOLD-TABLE omite foto-led; no hay obligación de covers de producto tipo MANTA. [DECISIÓN D-P1-09]
10. Calidad y toolchains
| Herramienta | Uso v1 |
|---|---|
| TypeScript | Strict en api y web |
| ESLint / Prettier | Serie daily |
| Vitest / Jest | Smoke API del slice |
| Playwright | Smoke S01–S12 del plan QA (doc 13) cuando exista runtime |
11. Anti-stack (no introducir)
| Tecnología | Por qué no |
|---|---|
| Prisma obligatorio | Brief no lo exige; ensureSchema + pg válido |
| Stripe / pago | Forma = etiqueta |
| TicketBAI / AEAT SDK | Cerrar ≠ Hacienda |
| Firebase Auth | JWT propio TITULAR |
| GraphQL | REST L2 |
| Socket.io / chat | ≠ PREGÓN |
| Mapbox / GPS | Fuera |
| Excel export Must | TALÓN no es Excel |
Leftover Nest modules trastos / bicis | ≠ MANTA / PIÑÓN |
12. Criterios de aceptación técnicos
GET /api/health→service: "talon-api".- Seed idempotente: 1 TITULAR + 4 líneas.
- POST apuntar crea línea y devuelve
TAL-XXXX. - POST anular sobre PENDIENTE → 201 ANULADO; sobre no-PENDIENTE → 409.
- GET mesa sin token → 401.
- Web en 4200 consume API 3029 sin mixed-content local.
- 0 referencias de producto a
trastos, REGIDORA,manta-api,bicis, MECANICO, ganchos en runtime.
[COMPROBADO] Contrato alineado a docs 01, 05 y README.
07-creative-direction.md
07 — Dirección creativa — TALÓN
1. Concepto
TALÓN es una caja de Maravillas bajo el fluorescente a las 21:00: se entra a una cinta de líneas a muro con tres números y cuatro filas, y se sale habiendo apuntado o anulado una línea, no una landing de «tu ERP». El ground es tubo apagado. El fósforo puntúa. El sello rojo, poco.
Mood elegido: phosphor.
Primer instinto descartado: bookish talonario crema / papel rosa carbón. Un tubo de parada a las 21:00 se lee en fósforo, no en papel de talonario nostálgico.
[COMPROBADO] Mood, ground y paleta salen de docs/00-day-brief.md.
2. Territorio visual
| Eje | Sí | No |
|---|---|---|
| Superficie | Tubo #101510, ink #D8F0C8, card #161C16, mark #8FD36A | Hueso MANTA, grafito PIÑÓN, velvet BOBINA, caliza LOMO, papel rosa |
| Tipo | IBM Plex Mono + Karla | Libre Baskerville+Nunito (MANTA), Spectral+Sora (PIÑÓN), Cormorant+Manrope (BOBINA) |
| Foto | Opcional cover UX; home sin foto-led (D-P1-09) | Hero+panel AP-25, plaza MANTA, gancho de taller |
| Grid | FOLD-TABLE: cinta densa + 3 datos + 4 filas | Hero 2-col + panel · bento · feed · plano Deriva |
| Acento | Mark en CTA/foco/slot activo; sello en ANULADO/error | Geranio MANTA, naranja PIÑÓN, brass de sala |
| Chrome | S-SIDE Hoy · Apuntar · Cierre | Bottom merendero, top taller, dock cineclub |
3. Paleta
| Token | Hex | Rol |
|---|---|---|
| Ground / G-PHOSPHOR | #101510 | Tubo apagado. Fondo de página. |
| Ink | #D8F0C8 | Fósforo de lectura. Texto primario. |
| Card | #161C16 | Tecla / fila / form. Superficie elevada. |
| Mark | #8FD36A | Fósforo: CTA Apuntar/Anular, foco, wordmark. |
| Mute | #7E9174 | Meta, labels, estado secundario, idle S-SIDE |
| Sello | #E24B4B | Poco: LED anulado, error, énfasis. No pinta el header. |
Jerarquía de color: el tubo carga; el mark puntúa; el sello filetea el conflicto (anulado / error). Si el sello pinta fondos enteros, deja de ser LED y se vuelve alarma retail. El texto sobre ground es ink; nunca mute como párrafo largo. Ink sobre ground debe pasar contraste WCAG 2.2 AA. [DECISIÓN]
Candidatos de mood descartados: bookish talonario crema (primer instinto), vehicle dashboard, rusted, signage.
4. Tipografía
| Uso | Familia | Tamaños de referencia |
|---|---|---|
| Wordmark | Karla 600 | 24–28 desktop · 22 mobile |
| Titular de Hoy / cierre | Karla 600 | 32–44 |
| Código TAL-XXXX | IBM Plex Mono 600 | 28–36 |
| Importes | IBM Plex Mono 500/600 | 18–28 |
| Cuerpo / disclaimers | Karla 400 | 16–17 / 26–28 lh |
| UI, S-SIDE, form, lista | Karla 400/500/600 | 14 / 16 |
| Meta (forma, status) | Karla 500 | 12–13, tracking 0.08em, mute o ink |
Prohibido: IBM Plex Mono por debajo de 14px en párrafos largos. Karla en importes (se vuelve SaaS blando). Sello como color de texto de párrafo largo (contraste).
Fuentes vetadas de la serie reciente cuando el brief fija otras: Libre Baskerville / Nunito Sans (MANTA), Spectral / Sora (PIÑÓN), Cormorant / Manrope (BOBINA), Source Serif 4 / Outfit (LOMO). IBM Plex Mono + Karla sí entran: el brief los fija. [COMPROBADO]
5. Fotografía
| Asset | Debe | No debe |
|---|---|---|
| Cover UX (si existe) | Parada / caja / fluorescente, Tetuán mood | Plaza MANTA, gancho PIÑÓN, papel rosa stock |
| Home producto | Sin tile foto-led dominante | Hero+panel AP-25 · FOLD-SPLIT |
Staff spreadsheet omite foto-led (D-P1-09). La densidad vive en la cinta. [DECISIÓN]
Alt: concepto + importe cuando haya imagen; no «imagen1». Ver doc 09.
6. Registro R-IN
Innovador denso: herramienta de caja, wordmark Karla, importes Mono, side rail de oficio. No es un dashboard de seguros. No es un kiosk de horas. No es una landing de barrio. No es papel rosa «cool».
La innovación de terna está en H-TABLE FOLD-TABLE + S-SIDE + F-EDIT, no en un look «talonario vintage». [DECISIÓN]
7. Anti-moods
| Mood | Por qué no |
|---|---|
| Bookish talonario crema / papel rosa | Primer instinto; es nostalgia de papel carbón |
| Botanical / hueso | Fue MANTA |
| Industrial / grafito | Fue PIÑÓN |
| Candlelit / velvet | Fue BOBINA |
| Mineral / caliza | Fue LOMO |
| Signage / cinta amarilla | Fue ONDA |
| Ice institucional | Fue RAMAL |
8. Densidad (AP-21 / FOLD-TABLE)
En el recorte: eslogan + 3 datos (cobrado / pendiente / anulado) + 4 filas con código, concepto, importe, forma y estado visibles sin hover. Headline huérfano + vacío = card hueca. [COMPROBADO] CRON FOLD-TABLE · D-P1-09 omite foto-led.
No hero+panel (AP-25). La cinta es el oficio. [DECISIÓN]
9. Motion
| Gesto | Tratamiento |
|---|---|
| Entrada cinta | Fade corto 120–160ms |
| Hover fila desktop | Ring mark 2px; sin lift excesivo |
| S-SIDE activo | Mark en label; idle mute |
| Sheet anular | Slide-up 160ms; reduced = instant |
| Reduced motion | 0ms |
10. Voice visual ↔ copy
El mood phosphor refuerza el microcopy: talón de caja, no Excel. Si la UI parece ERP (grid Excel, export, NIF) o factura (QR fiscal, IVA) o Hacienda (AEAT), el copy irrenunciable pierde fuerza. [DECISIÓN]
08-design-system.md
08 — Sistema de diseño — TALÓN
1. Tokens
| Token | Valor | Uso |
|---|---|---|
--ground | #101510 | Fondo de página (tubo apagado) |
--ink | #D8F0C8 | Texto primario, títulos |
--card | #161C16 | Fila, form, cierre |
--mark | #8FD36A | CTA, foco, S-SIDE activo |
--mute | #7E9174 | Meta, idle |
--sello | #E24B4B | LED anulado, error, poco |
--font-mono | IBM Plex Mono | Códigos, importes |
--font-sans | Karla | UI |
--target | 44×44 min | Toques |
Tailwind: bg-ground, text-ink, bg-card, bg-mark, text-mute, text-sello, font-mono, font-sans.
La fila vive sobre --card; el ground es tubo alrededor. [DECISIÓN]
2. Contraste (obligatorio)
| Par | Uso | Nota |
|---|---|---|
Ink #D8F0C8 sobre Ground #101510 | Cuerpo y títulos | Debe pasar WCAG 2.2 AA |
Ink sobre Card #161C16 | Texto en fila | Verificar AA |
| Mark sobre Ground | CTA fill + texto ground invertido en botón | No sustituye ink en párrafo |
| Mute sobre Ground | Meta corta; no cuerpo | Evitar párrafos mute |
| Sello sobre Ground | LED / error corto | No cuerpo |
[DECISIÓN] Sello nunca como color de párrafo. Mute nunca como único color de disclaimer largo.
CTA mark: texto #101510 sobre #8FD36A — verificar AA en implementación. [HIPÓTESIS operativa]
3. Escala de tipo
| Rol | Size / leading |
|---|---|
| Display Hoy | clamp(2.2rem, 5vw, 3.6rem) / 0.95 · Karla |
| H1 cierre / success | 2.5rem / 1 · Karla |
| Código TAL-XXXX | 28–36 · IBM Plex Mono |
| Importe | 18–28 · IBM Plex Mono |
| Cuerpo | 16–17 / 26 · Karla |
| Meta | 12–13 / 16, tracking 0.08em |
| S-SIDE | 12–14 / 16, Karla 500 |
4. Componentes
Fila de línea (cinta)
Código Mono · concepto Karla · importe Mono · forma · status. Tap PENDIENTE abre sheet anular. Orden por sort_order.
Cinta FOLD-TABLE (UI-01)
Tabla a muro; wordmark + eslogan + 3 datos (cobrado / pendiente / anulado). Sin tile foto-led. Sin hero+panel.
Dato (métrica)
Número ink grande + label mute («cobrado», «pendiente», «anulado»). Tres en fila desktop; wrap en 390. No es un sparkline ni una mesa de datos de archivo.
Form apuntar (UI-02)
Concepto, importe, forma, toggle pendiente opcional, disclaimer, submit mark.
Sheet anular (UI-10)
Código + concepto + importe en solo lectura, confirmación, submit sello/mark. Si no PENDIENTE: sello + «Esa línea no se puede anular.»
Success (UI-03)
Código Mono enorme + bloque card con concepto e importe + 4 oposiciones en ink/mute.
Cierre TITULAR (UI-05)
Grupos COBRADO / PENDIENTE / ANULADO + métricas + suma. Fila: código · concepto · importe · forma · status. Sin acciones PATCH fiscales en v1.
Login (UI-04)
Wordmark + dos inputs + CTA mark. Ayuda mute con demo.
Side nav (S-SIDE)
Tres slots: Hoy · Apuntar · Cierre. Activo: mark. Idle: mute. Fondo card/ground. Targets ≥44px.
Skeleton (UI-08)
animate-pulse bg-card o mute/20. aria-busy.
Error (UI-07)
Titular + cuerpo ink/mute + Reintentar mark. 409 usa sello en LED, no en párrafo.
Empty (UI-06)
Titular Karla + mute. Sin CTA de Excel ni de Hacienda.
Sello COBRADO / PENDIENTE / ANULADO
Texto «Cobrado» / «Pendiente» / «Anulado» + mark o mute o sello. Nunca solo el color. Poco: un sello por fila.
5. Layouts
| Superficie | Grid |
|---|---|
| Hoy 1440 | Rail S-SIDE + cinta full; 3 datos en fila; 4 filas; sin foto hero |
| Hoy 390 | Chrome compacto + 3 datos wrap + stack de 4 |
| Apuntar / Ok / login | Columna max-w-lg |
| Cierre TITULAR | Métricas + grupos; stacked < lg |
| Sheet anular | Bottom sheet max-w-lg; full-bleed 390 |
Max page 1440px. Padding 20 / 40 / 48.
6. Estados de control
| Estado | Tratamiento |
|---|---|
| Default | Card + ink |
| Hover | Ring mark 2px |
| Focus visible | Outline mark 2px offset 2 |
| Active / pressed | Mark fill breve |
| Disabled | Opacity 0.45 · no hit · aria-disabled |
| Pending | disabled + aria-busy |
| Error | Borde sello + mensaje |
| PENDIENTE seleccionada | Ring mark |
| No anulable | Sello; CTA disabled |
7. Iconografía
S-SIDE: pictogramas simples (cinta / más / cierre). Stroke 1.5–2px. No icon packs «Excel», «factura», «trasto», «bici». [DECISIÓN]
8. Elevación y bordes
| Superficie | Tratamiento |
|---|---|
| Card sobre tubo | Borde 1px mute/25; sombra mínima ink/10 |
| S-SIDE | Rail card; filete mute 1px; no material neón retail |
| Sheet | Overlay ground/70 + card; no modal centrado de SaaS |
| Modal extra | No en v1 Must |
9. Mapa a Paper UI
| UI | Componentes clave |
|---|---|
| UI-01 / 11 | Cinta + 3 datos + 4 filas + S-SIDE |
| UI-02 / 12 | Form apuntar |
| UI-10 | Sheet anular |
| UI-03 | Success |
| UI-04 | Login |
| UI-05 | Cierre |
| UI-06 | Empty |
| UI-07 | Error / 409 |
| UI-08 | Loading |
| UI-09 | Tokens |
[COMPROBADO] Inventario en 00-paper-reference.md.
09-content-guide.md
09 — Guía de contenido — TALÓN
1. Voz
TALÓN habla como caja de parada, no como ERP ni como Hacienda.
| Eje | Sí | No |
|---|---|---|
| Tono | Seco, breve, de oficio | Corporativo contable, hype fintech |
| Persona | «Apuntamos la línea» / tuteo de caja | «Emite tu factura» / «declara el modelo» |
| Ritmo | Frases cortas. Una idea por línea en disclaimers | Párrafos legales de AEAT |
| Humor | Seco, poco | Memes, jerga de startup |
[DECISIÓN] Tuteo en UI. Remedios en cierre puede verse en usted solo en docs, no en labels.
2. Microcopy irrenunciable
Presente en Hoy (pie o banner), apuntar, anular, success y pie de cierre:
| Oposición | Copy canónico |
|---|---|
| Apuntar vs cuenta móvil | Apuntar ≠ hacer la cuenta en el móvil. |
| Talón vs factura | Talón ≠ factura. |
| Cierre vs Hacienda | Cerrar el día ≠ Hacienda. |
| Producto vs Excel | TALÓN no es Excel. |
No se parafrasean hasta diluirlas. Pueden acortarse en UI estrecha manteniendo ≠. [DECISIÓN]
3. Glosario UI
| Concepto | Label canónico | Evitar |
|---|---|---|
| Home | Hoy | Inicio, Plaza, Taller, Excel, Dashboard |
| Item | Línea / Talón | SKU, factura, trasto, gancho |
| Flujo apuntar | Apuntar | Facturar, cobrar online, exportar |
| Flujo editar | Anular | Borrar, eliminar fila, soft-delete |
| CTA apuntar | Apuntar | Guardar en Excel, Emitir |
| CTA anular | Anular | Borrar, Eliminar |
| Success | Apuntado / Anulado | Factura emitida, Asiento contable |
| Staff | Cierre | Backoffice, Admin, Hacienda, Kanban |
| Estado | Cobrado / Pendiente / Anulado | Facturado / Enviado AEAT / Agotado |
| Persona auth | Titular | Regidora, Mecánica, Admin |
| Error 409 | No se puede anular | Agotado, Forbidden fiscal |
4. Pantalla a pantalla
Hoy /
| Slot | Copy |
|---|---|
| Wordmark | TALÓN |
| Eslogan | El talón, no Excel. |
| Dato 1 | {n} cobrado |
| Dato 2 | {n} pendiente |
| Dato 3 | {n} anulado |
| CTA side | Apuntar |
| Empty | Aún no hay líneas. |
| Error | La red no responde. · Reintentar |
Apuntar /apuntar (UI-02)
| Slot | Copy |
|---|---|
| Título | Apuntar |
| Label concepto | Concepto |
| Label importe | Importe (€) |
| Label forma | Forma |
| Opciones forma | Efectivo · Bizum |
| Toggle | Pendiente de cobro |
| Submit | Apuntar |
| Disclaimer | No es una factura. No es Hacienda. TALÓN no es Excel. |
| Error concepto | Escribe el concepto. |
| Error importe | Indica el importe. |
| Error forma | Elige la forma. |
Anular sheet (UI-10)
| Slot | Copy |
|---|---|
| Título | Anular |
| Meta | {concepto} · {importe} · {code} |
| Submit | Anular |
| Disabled / 409 | Esa línea no se puede anular. |
| Disclaimer | Solo pendientes. No borra el rastro. Apuntar ≠ cuenta en el móvil. |
Success /ok/:code
| Slot | Copy |
|---|---|
| Titular (apuntar) | Apuntado. |
| Titular (anular) | Anulado. |
| Código | {code} |
| Cuerpo apuntar | {concepto} · {importe} · {forma}. |
| Cuerpo anular | {concepto}. Ya no cuenta como pendiente. |
| Oposiciones | Las cuatro líneas irrenunciables |
| Volver | Volver a Hoy |
Login /login
| Slot | Copy |
|---|---|
| Título | Cierre |
| Ayuda | Solo titular. |
| Demo | remedios@talon.parada |
| Error | Email o contraseña no valen. |
Cierre /cierre
| Slot | Copy |
|---|---|
| Título | Cierre |
| Grupos | Cobrado · Pendiente · Anulado |
| Suma | Suma cobrada {n} € |
| Empty | No hay líneas en el cierre. |
| Salir | Salir |
| Pie | Cerrar el día ≠ Hacienda. |
5. Alt text de imágenes
| Asset | Alt (modelo) |
|---|---|
| Cover UX | Caja de parada bajo fluorescente, mood fósforo |
| (sin covers de líneas) | Home sin foto-led; filas son texto |
Evitar «imagen1», copy de factura con NIF. [DECISIÓN]
6. Líneas seed (atrezzo)
Ramo / planta / corona / maceta son catálogo demo. En UI no se afirma «parada municipal de Maravillas». Los blurbs pueden recordar talón ≠ factura. [SUPUESTO de parada]
7. Tono de error
| Caso | Copy |
|---|---|
| Red | La red no responde. |
| 404 | Esa línea no está. |
| 409 | Esa línea no se puede anular. |
| 400 concepto | Escribe el concepto. |
| 401 cierre | Entra como titular. |
Sin culpa al usuario. Sin jerga HTTP en UI.
8. Anti-copy (vetado)
| Vetado | Por qué |
|---|---|
| Excel / pivot / exportar hoja | TALÓN no es Excel |
| Factura / NIF / IVA / TicketBAI | Talón ≠ factura |
| Hacienda / AEAT / modelo | Cerrar ≠ Hacienda |
| Cuenta en el móvil / calculadora bancaria | Apuntar ≠ cuenta móvil |
| Trasto / manta / regidora / plaza | MANTA |
| Gancho / bici / encargo / mecánica | PIÑÓN |
| Recibido / En curso / Cerrado | PREGÓN kanban |
| «El 70% de paradas…» | Estadística inventada |
| Anular en lote | Rompe F-EDIT de una línea |
9. Criterios de aceptación de contenido
- Las cuatro oposiciones aparecen al menos en success y en una superficie de Hoy o apuntar/anular.
- Ningún CTA dice Facturar / Exportar a Excel / Declarar / Borrar.
- COBRADO se etiqueta «Cobrado», no «Facturado».
- Códigos se muestran como
TAL-XXXXen versales. - Docs y UI no inventan KPIs numéricos de Tetuán como hecho.
10-accessibility.md
10 — Accesibilidad — TALÓN
1. Objetivo
Cumplir WCAG 2.2 AA en el vertical slice L2. Ground oscuro (tubo): el par ink sobre ground es el contrato de legibilidad. La lectora mayor (68) es persona de diseño que fuerza contraste, tamaño y targets; no tiene login. [COMPROBADO] requisito del encargo · [DECISIÓN] persona a11y en docs.
2. Contraste
| Par | Ratio objetivo | Uso |
|---|---|---|
#D8F0C8 sobre #101510 | ≥ 4.5:1 (texto) / ≥ 3:1 (UI grande) | Cuerpo, títulos |
#D8F0C8 sobre #161C16 | ≥ 4.5:1 | Texto en card |
#8FD36A sobre #101510 | ≥ 3:1 para UI; texto de párrafo no | Foco, iconos |
#101510 sobre #8FD36A | ≥ 4.5:1 en CTA | Label del botón |
#7E9174 sobre #101510 | Verificar; limitar a meta corta | Labels |
#E24B4B sobre #101510 | LED / error corto | Sello; no cuerpo |
[DECISIÓN] Si mute falla AA en párrafo, se asciende a ink. Sello no escribe disclaimers. Mark no escribe disclaimers largos.
Verificación: contraste en tokens al build de UI; no se afirman ratios inventados sin medir en implementación. [HIPÓTESIS operativa] ink/ground pasa; se valida en QA (doc 13).
3. Tipografía y lectura
| Regla | Aplicación |
|---|---|
| Cuerpo ≥ 16px | Karla 16–17 |
| Códigos / importes legibles | IBM Plex Mono ≥ 14 en UI; ≥ 18 en success |
| Line-height ≥ 1.5 en cuerpo | 26–28 lh |
| Zoom 200% | Layout no rompe S-SIDE ni form |
| Sin justificado forzado | Alineación start |
4. Targets y pointer
| Elemento | Mínimo |
|---|---|
| Slots S-SIDE | 44×44 CSS px |
| CTA Apuntar / Anular | ≥ 44 px alto |
| Fila de línea | Hit area completa ≥ 44 alto |
| Inputs | ≥ 44 alto |
| Cerrar sheet | ≥ 44 |
Spacing entre slots ≥ 8px. [DECISIÓN]
5. Teclado y foco
| Superficie | Comportamiento |
|---|---|
| Hoy | Tab por S-SIDE → filas PENDIENTE → Apuntar |
| Sheet anular | Confirmar → submit; Esc cierra |
| Form apuntar | Concepto → importe → forma → submit |
| Login | Email → password → entrar |
| Cierre | Grupos legibles; salir alcanzable |
| Focus visible | Outline mark 2px offset 2 |
| Skip link | «Saltar a la cinta» en / |
Sin keyboard traps. Sheet: foco inicial en confirmación; retorno a la fila al cerrar. [DECISIÓN]
6. Semántica y nombres
| UI | Rol / nombre |
|---|---|
| S-SIDE | navigation · aria-label «TALÓN» |
| Slot activo | aria-current="page" |
| 3 datos | list o group «Métricas del día» · cada dato con texto «{n} cobrado» no solo el número |
| Filas línea | article o fila de table «{concepto} {importe}» + status en texto |
| Sheet | dialog · aria-modal · labelledby título |
| Form | label asociado; errores con aria-live="polite" |
| Loading | aria-busy="true" en región |
| Success código | Texto real, no solo imagen |
| 409 | aria-live="assertive" |
7. Imágenes
| Caso | Tratamiento |
|---|---|
| Cover UX | alt descriptivo corto |
| Home producto | Sin tile foto-led obligatorio |
| Iconos S-SIDE | aria-hidden si hay label texto visible |
8. Motion
| Preferencia | Comportamiento |
|---|---|
prefers-reduced-motion: reduce | Transiciones 0ms; sheet instant |
| Default | 120–160ms ease-out |
9. Estados y color
COBRADO / PENDIENTE / ANULADO / error nunca se comunican solo con color: texto + sello. Mark y sello refuerzan, no sustituyen. [DECISIÓN]
10. Auth y a11y
- Login solo TITULAR; lectora mayor no necesita cuenta para leer Hoy ni apuntar.
- Mensajes de error de login claros, sin enumerar si el email existe.
/cierreredirige a login con foco en email.
11. Mobile 390
- S-SIDE / chrome compacto no tapa el CTA final: padding del contenido ≥ chrome + safe-area.
- Sheet anular; submit visible.
- Formularios:
autocompleteon; importeinputmode="decimal"; passwordcurrent-password. - Viewport meta; sin zoom bloqueado. [DECISIÓN]
- UI-11 Hoy y UI-12 apuntar cubren el recorte 390. No carousel.
12. Criterios de aceptación a11y
- Ink sobre ground usado en cuerpo; mute limitado a meta.
- Targets S-SIDE y CTA ≥ 44×44.
- Focus visible mark en todos los interactivos.
- Status y métricas con texto, no solo color o número huérfano.
- Reduced motion respetado.
- Form con labels y errores anunciables.
- Ningún toast único sin pantalla como único success (hay
/ok/:code). - Sheet anular es
dialogalcanzable con teclado.
13. Fuera de v1 (L3, no deuda)
- Modo tipográfico «letra grande» persistente.
- App nativa con VoiceOver de caja física.
- ATAG de CMS (no hay CMS).
11-privacy-security.md
11 — Privacidad y seguridad — TALÓN
1. Principios
| Principio | Aplicación v1 |
|---|---|
| Minimización | Apuntar = concepto + importe + forma (+ status); anular = code; sin NIF, email de cliente, GPS |
| Separación público / oficio | Cinta y POST públicos; cierre JWT |
| Sin cuenta de ayudante | Lucia y lectora mayor no se registran |
| Transparencia de copy | Success dice que no es factura ni Hacienda |
| Secretos fuera del repo | DATABASE_URL, JWT_SECRET en env |
[DECISIÓN] No se inventa un aviso legal largo de ERP; hay disclaimer de producto y minimización real.
2. Datos tratados
| Dato | Dónde | Base operativa (modelo) | Retención v1 |
|---|---|---|---|
| Concepto / importe / forma | lineas | Oficio de caja | Mientras el seed/demo viva; sin política de mercado afirmada |
| Status | lineas.status | Cobrado / pendiente / anulado | Igual |
| Email TITULAR | users.email | Cuenta de oficio | Cuenta demo |
| Password hash | users.password_hash | Auth | bcrypt 12 |
| JWT sid | sessions | Sesión de cierre | Expiración + revoke |
No se tratan: pago de tarjeta, geolocalización, ID de dispositivo publicitario, mensajes de chat, NIF de cliente, IBAN, stock.
[SUPUESTO] La parada demo opera en España; el slice no implementa un RGPD completo de empresa real.
3. Superficies públicas vs privadas
| Superficie | Público | Privado |
|---|---|---|
GET /api/lineas | Sí · métricas + líneas | — |
GET /api/lineas/:code | Sí | — |
| POST lineas / anular | Sí · crea / actualiza fila | — |
GET /api/mesa | No · 401 | Sí · métricas + agrupación + titular |
| Hoy UI | Cinta del día | — |
| Cierre UI | — | Lectura de oficio |
[DECISIÓN] El cierre JWT no expone datos fiscales de terceros; expone el día de la parada demo.
4. AuthN / AuthZ
| Control | Detalle |
|---|---|
| Password | bcrypt cost 12 |
| JWT | HS256 · secret env · role claim |
| Guard cierre | role === TITULAR |
| Login rate | No es deuda del L2; demo sin brute-force engine |
| Logout | Revoke session + clear client token |
| HTTPS | Obligatorio en deploy; localhost HTTP en dev |
Credenciales demo en docs: remedios@talon.parada / password123. No reutilizar en producción real. [COMPROBADO] demo · [DECISIÓN] rotar fuera del case.
5. Amenazas y mitigaciones L2
| Amenaza | Mitigación |
|---|---|
| POST spam apuntar/anular | Validación concepto + importe; L3 rate-limit (no es hueco del slice) |
| Carrera de dos anulaciones | SELECT FOR UPDATE + 409 al segundo no-PENDIENTE |
| JWT robado | Expiración corta + logout; HTTPS en prod |
| IDOR cierre | Guard JWT |
| XSS | Angular escaping; no innerHTML de concepto |
| SQLi | Parámetros prepared / query builder |
| Leftover REGIDORA / MECANICO / ADMIN | Un solo rol TITULAR |
6. Contenido de importe y concepto
importe es oficio de caja, no tracking. Puede ser negativo (devolución seed). [DECISIÓN]
No se pide NIF, dirección ni datos de terceros sensibles en el form.
concepto es texto libre corto (min 2, max 120).
7. Cookies y tracking
v1 no incluye analytics de terceros ni banners de cookies de ads. North star es modelo (doc 12). [DECISIÓN]
Token JWT puede vivir en localStorage (XSS risk aceptado en demo) o memory; documentar en handoff.
8. Logs
| Qué sí | Qué no |
|---|---|
| Errores de API sin PII | Passwords, JWT completos |
| code de línea en logs | Secretos env |
9. Criterios de aceptación
- GET mesa sin Bearer → 401.
- POST lineas/anular no exige auth ni pago ni NIF.
- Password solo como hash bcrypt.
.envno versionado con secretos reales.- Copy de success no implica factura ni declaración a Hacienda.
- Segundo POST anular sobre el mismo code ya ANULADO → 409.
- Anular COBRADO → 409.
10. Fuera de v1 (L3 / org real, no deuda)
DPO, ROPA formal, exportaciones ARCO automatizadas, SSO, 2FA, WAF, pasarela, TicketBAI. Roadmap L3 si la parada deja de ser demo.
12-analytics.md
12 — Analytics y métricas — TALÓN
1. Norte
| Tipo | Métrica | Definición |
|---|---|---|
| North Star | % de consultas «¿cuánto llevamos?» resueltas en la cinta sin abrir el móvil de notas | Oficio de talón: se ve cobrado / pendiente / anulado sin recado paralelo |
[COMPROBADO] North star alineada a H1 del day brief.
[DECISIÓN] En v1 es modelo: no hay instrumentación obligatoria ni dashboard. No se afirman porcentajes medidos inventados.
2. Por qué esta north star
| Alternativa descartada | Por qué no |
|---|---|
Pageviews de / | Vanidad; no mide talón |
| Ingresos / GMV online | No hay pasarela; forma es etiqueta |
| % de facturas emitidas | Talón ≠ factura |
| % de modelos AEAT | Cerrar ≠ Hacienda |
| % de filas Excel exportadas | TALÓN no es Excel |
| % de trastos sin WhatsApp | Eso es MANTA |
| % de bicis LISTA sin WhatsApp | Eso es PIÑÓN |
El móvil de notas de «¿cuánto llevamos?» es el recado que la cinta y el cierre pretenden absorber. [SUPUESTO] operativo de diseño, no dato de campo.
3. Métricas de soporte (modelo)
| Métrica | Definición | Hipótesis |
|---|---|---|
| Activación | 1.er POST /api/lineas exitoso | H1 |
| Tasa Hoy → apuntar | / → /apuntar | H1 |
| Tasa anulación | POST anular 201 / intentos | H2 |
| Tasa 409 | POST anular 409 / intentos | Integridad |
| Mix de estados | Conteos cobrado / pendiente / anulado | H1 |
| Suma cobrada | Σ importe donde status = COBRADO | Oficio |
| Integridad auth | 401 en mesa sin token | Seguridad |
| Salud | 5xx rate API | Ops |
4. Eventos (contrato si se instrumenta en un L3)
| Evento | Props | PII |
|---|---|---|
hoy_view | metrics snapshot (conteos) | No |
apuntar_submit | forma, status | No concepto libre si sensible |
apuntar_success | code | No |
anular_submit | code | No |
anular_success | code | No |
anular_conflict | http:409 | No |
login_success | role | No |
cierre_view | — | No |
[DECISIÓN] Nunca enviar passwords ni JWT a analytics.
Instrumentar eventos no es un hueco del L2: el slice cierra sin tracker. [DECISIÓN]
5. Cálculo north star (modelo)
visitas_hoy = sesiones en /
resuelto_sin_notas =
(no medible en v1: no hay canal de notas en producto)
proxy de diseño = visitas a / o /cierre que cubren cobrado/pendiente/anulado
frente a recados paralelos (cualitativo)
[DECISIÓN] v1 no persiste un flag notas_asked. El north star queda como modelo de oficio, no como SQL fingido.
Timezone: Europe/Madrid. [DECISIÓN]
6. Integridad de expectativa (cualitativa)
Señales a vigilar en demo / soporte (no KPIs inventados):
- «¿Dónde exporto a Excel?»
- «¿Esto es una factura?»
- «¿Lo mando a Hacienda?»
- «¿Dónde está la pasarela?»
- «¿Esto es la manta de Usera?»
- «¿Esto es el taller de bicis?»
Mitigación: microcopy irrenunciable (doc 09). [HIPÓTESIS H1/H2]
7. Qué no medir en v1
| Vetado | Por qué |
|---|---|
| Heatmaps de terceros sin decisión | Privacidad |
| Funnel de pago online | No hay pasarela |
| DAU de Excel | No hay hoja |
| Estadísticas de Tetuán inventadas | Ética de verdad |
| Tracking GPS | Fuera |
8. Criterios de aceptación
- Docs y UI no muestran un % inventado como hecho.
- North star documentada y alineada a H1.
- Si hay eventos en un L3, sin secretos ni PII innecesaria.
- Health, 401 mesa y 409 anular son checks de integridad, no vanidad.
9. Relación con seed
Seed tiene 2 COBRADO + 1 PENDIENTE + 1 ANULADO · suma cobrada 20,00 €. Un guión con POST apuntar TAL-2905 y POST anular TAL-2903 es el ejemplo narrativo de activación; no es un dato de mercado. [SUPUESTO de demo]
13-qa-test-plan.md
13 — Plan de QA — TALÓN
1. Alcance
Smoke y regresión del vertical slice L2: cinta, apuntar, anular, 409, success, login, cierre, empty/error/loading, mobile 390, contraste ink/ground.
No incluye campo real de Maravillas ni load test de ERP.
[DECISIÓN] Mientras talon-app no tenga runtime, este plan es contrato. No se finge smoke verde. Completeness (doc 18) puede dejar código E2E como contrato hasta smoke real.
2. Entornos
| Entorno | URL | Notas |
|---|---|---|
| API local | http://localhost:3029 | Neon cool-cloud-04708830 |
| Web local | http://localhost:4200 | Proxy /api |
| Credenciales | remedios@talon.parada / password123 | Solo demo |
3. Smoke crítico (Must pasar cuando haya runtime)
| ID | Caso | Pasos | Esperado |
|---|---|---|---|
| S01 | Health | GET /api/health | ok · service: "talon-api" |
| S02 | Cinta | GET /api/lineas · abrir / | 4 líneas · 3 métricas · FOLD-TABLE |
| S03 | Métricas seed | Leer datos | 2 cobrado · 1 pendiente · 1 anulado · suma 20,00 |
| S04 | 409 | POST /api/lineas/anular { code: "TAL-2901" } | 409 |
| S05 | Anular | Sheet corona PENDIENTE · confirma | 201 · status ANULADO |
| S06 | Copy success | Leer /ok/:code | 4 oposiciones visibles |
| S07 | Apuntar | /apuntar · concepto + importe + forma · submit | 201 · /ok/TAL-2905 |
| S08 | Login | /login Remedios | JWT · /cierre |
| S09 | Mesa auth | GET /api/mesa con token | métricas + líneas |
| S10 | Mesa 401 | GET /api/mesa sin token | 401 |
| S11 | Mobile | / y /apuntar @390 | S-SIDE · 4 líneas · targets |
| S12 | Seed | Tras re-seed | 2 COBRADO · 1 PENDIENTE · 1 ANULADO |
4. Regresión funcional
| ID | Área | Check |
|---|---|---|
| R01 | POST apuntar crea línea | Nuevo code TAL-XXXX |
| R02 | POST anular pasa a ANULADO | TAL-2903 deja de ser PENDIENTE |
| R03 | Importe negativo seed | TAL-2904 -6,00 visible |
| R04 | Concepto vacío | 400 · no navega a ok |
| R05 | Importe inválido | 400 |
| R06 | Code inventado | /ok/TAL-9999 · 404 UI |
| R07 | Guard ruta | /cierre sin token → login ?next= |
| R08 | Logout | Token limpio · mesa 401 |
| R09 | S-SIDE | Hoy / Apuntar / Cierre navegables |
| R10 | Leftover | 0 manta-api / trastos / REGIDORA / bicis / MECANICO en UI |
| R11 | 409 ANULADO | POST anular TAL-2904 → 409 |
| R12 | Bulk | UI no permite array de codes |
5. Accesibilidad (muestra)
| ID | Check |
|---|---|
| A01 | Ink sobre ground en cuerpo |
| A02 | Focus visible mark en tab order |
| A03 | S-SIDE slots ≥ 44×44 |
| A04 | Status con texto, no solo color |
| A05 | prefers-reduced-motion |
| A06 | Labels en form apuntar, sheet y login |
| A07 | aria-busy en loading Hoy |
| A08 | Sheet como dialog |
6. Contenido
| ID | Check |
|---|---|
| C01 | Ningún CTA «Facturar» / «Exportar» / «Declarar» / «Borrar» |
| C02 | Eslogan en Hoy |
| C03 | COBRADO = «Cobrado» no «Facturado» |
| C04 | Códigos TAL-XXXX |
| C05 | Cuatro oposiciones en success |
7. Visual / Paper
| ID | Check |
|---|---|
| V01 | Cinta + 3 datos + 4 filas (no hero+panel, no plano, no bento, no feed) |
| V02 | Mood phosphor (no hueso MANTA, no grafito taller, no papel rosa) |
| V03 | Sin foto-led staff (D-P1-09) |
| V04 | Cierre = métricas del día (no kanban) |
| V05 | S-SIDE no bottom de merendero |
8. API negativa
| Caso | HTTP |
|---|---|
| Login malo | 401 |
| Apuntar sin concepto | 400 |
| Apuntar sin importe | 400 |
| Anular sin code | 400 |
| Anular sobre COBRADO | 409 |
| Anular sobre ANULADO | 409 |
| Anular code 404 | 404 |
| Mesa sin auth | 401 |
9. Datos de prueba
| Actor | Dato |
|---|---|
| Ayudante | Lucia Ayala (sin cuenta) |
| Línea happy PENDIENTE | TAL-2903 Corona 35,00 |
| Línea 409 | TAL-2901 Ramo COBRADO |
| Línea ANULADO | TAL-2904 |
| Apuntar smoke | Ramo pequeño · 10,00 · efectivo |
| TITULAR | remedios@talon.parada |
Tras smoke: re-seed para restaurar las 4 de catálogo. [DECISIÓN]
10. Criterio de salida
Smoke S01–S12 en verde cuando exista runtime. Sin P0 (health mal, apuntar/anular rotos, 409 ausente, cierre abierto sin auth, copy Excel ausente en success).
Hasta entonces: contrato documentado; no fake PASS. [DECISIÓN]
11. Fuera de alcance QA v1
Penetration test, auditoría RGPD formal, pasarela, TicketBAI, compatibilidad IE, métricas reales de north star instrumentadas. Eso es L3 u org real, no un agujero de este slice.
14-dev-handoff.md
14 — Handoff a desarrollo — TALÓN
1. Contrato vivo
| Artefacto | Path |
|---|---|
| Brief | docs/00-day-brief.md |
| Paper ref | docs/00-paper-reference.md |
| Producto | docs/01-project-definition.md |
| IA / rutas | docs/03-information-architecture.md |
| Flujos | docs/04-user-flows.md |
| Datos | docs/05-data-model.md |
| Stack | docs/06-tech-stack.md |
| DS / tokens | docs/08-design-system.md |
| Copy | docs/09-content-guide.md |
| Build | docs/20-implementation.md |
| App | /Users/cristian/orca/talon-app |
| GH | Criscode2022/talon-app |
| Paper | 01M165CVX37R8QSKBG37N0QRS4 |
| API | :3029 · talon-api |
| Neon | cool-cloud-04708830 |
Si código y docs divergen, alinear ambos; no silenciar leftover MANTA/PIÑÓN como producto. [DECISIÓN]
La app puede no existir aún: el handoff es el contrato. [DECISIÓN]
2. Definition of Done (DoD) L2
| # | Criterio |
|---|---|
| 1 | Rutas / /apuntar /ok/:code /login /cierre |
| 2 | Home = FOLD-TABLE H-TABLE (cinta + 3 datos + 4 líneas), no H-MAP ni H-BENTO ni hero+panel |
| 3 | Chrome S-SIDE Hoy · Apuntar · Cierre |
| 4 | F-EDIT: apuntar línea + anular PENDIENTE (sheet UI-10); 409 si no PENDIENTE |
| 5 | POST apuntar público; success con 4 oposiciones |
| 6 | JWT TITULAR; mesa 401 sin token |
| 7 | Seed 4 líneas · 2 COBRADO · 1 PENDIENTE · 1 ANULADO · suma 20,00 |
| 8 | Health talon-api · puerto 3029 |
| 9 | Tokens phosphor + IBM Plex Mono / Karla |
| 10 | Empty / error / loading / 409 |
| 11 | Mobile 390 usable (Hoy + apuntar) |
| 12 | 0 dominio trastos / REGIDORA / manta-api / bicis / MECANICO / ganchos |
El DoD cubre todo el slice. No queda producto in-scope como «siguiente sprint». [DECISIÓN]
3. Mapa Paper → Angular
| UI | Ruta | Componente |
|---|---|---|
| UI-01 / 11 | / | HoyPage |
| UI-02 / 12 | /apuntar | ApuntarPage |
| UI-10 | / sheet | AnularSheet |
| UI-03 | /ok/:code | OkPage |
| UI-04 | /login | LoginPage |
| UI-05 | /cierre | CierrePage |
| UI-06 / 07 / 08 | estados | mismos components |
| UI-09 | theme | Tailwind |
4. API checklist
| Método | Ruta | Auth |
|---|---|---|
| GET | /api/health | No |
| GET | /api/lineas | No |
| GET | /api/lineas/:code | No |
| POST | /api/lineas | No · apuntar |
| POST | /api/lineas/anular | No · anular · 409 |
| POST | /api/auth/login | No |
| GET | /api/mesa | JWT TITULAR |
Body apuntar: { concepto: string, importe: number, forma: "efectivo"|"bizum", status?: "COBRADO"|"PENDIENTE" }.
Body anular: { code: string }.
Ver algoritmos en doc 05 / 20. [DECISIÓN]
5. Seed y credenciales
| Item | Valor |
|---|---|
remedios@talon.parada | |
| Password | password123 |
| Codes | TAL-2901…2904 |
| Suma cobrada | 20,00 € |
6. Anti-patrones de implementación
| No hacer | Hacer |
|---|---|
| Puerto 3028 / health manta-api | 3029 / talon-api |
| Tabla trastos / tratos / bicis | lineas |
| Bottom S-BOTTOM / Top S-TOP | S-SIDE |
| Plano H-MAP / Bento H-BENTO | Cinta FOLD-TABLE H-TABLE |
| Kanban cierre | Métricas del día |
| Pago / Stripe / factura | POST concepto + importe + forma |
| AEAT / TicketBAI | Fuera |
| Hero+panel AP-25 | Cinta densa sin foto-led |
| Bulk anular | Una línea · 409 |
/dejar leftover MANTA | /apuntar + sheet anular |
7. Assets
Case assets/ puede estar vacío al inicio (staff omite foto-led). Cover UX opcional. [DECISIÓN]
8. QA mínimo antes de merge
Ejecutar smoke S01–S12 (doc 13) cuando haya runtime. Verificar copy irrenunciable en /ok/:code. Verificar 409 sobre TAL-2901.
9. Open questions (no reabren L2)
| Pregunta | Default ya decidido |
|---|---|
¿Prisma o pg + ensureSchema? | ensureSchema válido |
| ¿localStorage vs memory token? | localStorage demo OK |
| ¿Importe maxlength? | NUMERIC(12,2) |
| ¿Status default al apuntar? | COBRADO; toggle PENDIENTE |
| ¿PATCH status libre? | No en v1 |
¿Ruta /anular/:code? | No · sheet sobre / |
10. Contacto de diseño
Paper file + docs 07–09. No reinventar hueso botanical ni grafito de taller. Mood phosphor. Ground #101510. Mark #8FD36A. Sello #E24B4B poco.
15-roadmap.md
15 — Roadmap — TALÓN
1. Horizonte
| Fase | Nombre | Intención |
|---|---|---|
| L2 | Slice actual | Hoy + apuntar + anular + cierre JWT · cerrado en esta iteración (docs/contrato) |
| L3 | Nice-to-have de otro producto | Solo ideas que rompen S3, y solo con brief nuevo |
[DECISIÓN] El L2 no deja producto ni código in-scope como «próximos pasos». Este roadmap no es un cajón de deuda. Empty, error, loading, 409, mobile, auth, seed, copy y API están en el slice de hoy (como contrato).
2. Hecho en L2 (Must · cerrado en suite)
| Pieza | Estado |
|---|---|
| H-TABLE FOLD-TABLE 4 líneas + 3 métricas | Must · cerrado (docs) |
| Apuntar sin cuenta | Must · cerrado |
| F-EDIT anular PENDIENTE + 409 | Must · cerrado |
| Success + 4 oposiciones | Must · cerrado |
| Login TITULAR | Must · cerrado |
| Cierre cobrado / pendiente / anulado | Must · cerrado |
| Empty / error / loading / 390 | Must · cerrado |
| Docs 00–20 + README + executive | Must · cerrado |
| Paper 12 UX + 12 UI (inventario) | Must (ref) · cerrado |
Contrato talon-app · API :3029 · health talon-api | Must · contrato (runtime puede pendiente) |
Nada de la tabla se reabre como backlog de «el código ya vendrá» como deuda de producto: el case L2 docs cierra; el build sigue el contrato (doc 20). [DECISIÓN]
3. L3 only (nice-to-have · otro brief)
| ID | Idea | Por qué L3 | Riesgo |
|---|---|---|---|
| L3-01 | Pagos online / TPV / pasarela | Rompe S3; forma dejaría de ser etiqueta | Fintech disfrazado |
| L3-02 | AEAT / TicketBAI / factura | Rompe S3; Cerrar ≠ Hacienda | Fiscal disfrazado |
| L3-03 | Stock / SKU | Rompe S3; H3 | Inventario disfrazado |
| L3-04 | Export Excel | Contradice «TALÓN no es Excel» si se vuelve Must | Hoja disfrazada |
Estas ideas no completan TALÓN. Completarían otro producto. [DECISIÓN]
4. Anti-roadmap (no disfrazar)
| Pedido típico | Respuesta |
|---|---|
| «Pon export a Excel» | No como Must · TALÓN no es Excel |
| «Pon factura / AEAT» | No · Talón ≠ factura · Cerrar ≠ Hacienda |
| «Pon pasarela» | No en L2 · L3-01 con brief nuevo |
| «Pon stock» | No · S3 |
| «Pon búsqueda tipo LOMO» | No · rompe terna H-TABLE |
| «Pon kanban» | No · ≠ PREGÓN |
| «Pon plano de mantas» | No · N−1 ya fue MANTA |
| «Empty / loading / 409 los dejamos para después» | No · están en el L2 de hoy |
| «El código es el próximo paso del case» | El contrato L2 está cerrado; build = mismo alcance, no roadmap de producto inventado |
5. Dependencias del slice cerrado
| Dependencia | Nota |
|---|---|
Neon cool-cloud-04708830 | L2 (DATABASE_URL) |
Paper file 01M165CVX37R8QSKBG37N0QRS4 | Diseño; inventario en 00 |
talon-app · GH Criscode2022/talon-app | Contrato de build (doc 20); puede no existir aún |
6. Criterios para abrir un L3
- Smoke L2 en verde (doc 13) cuando haya runtime.
- Copy irrenunciable intacto.
- El brief L3 nombra pagos / AEAT / stock sin reabrir cinta, F-EDIT de una línea ni cierre.
- North star sigue siendo modelo o se instrumenta sin PII innecesaria.
7. Cierre
L2 docs/contrato está completo en una iteración. El roadmap es un muro contra Excel, factura y Hacienda, no una lista de lo que «faltó». [DECISIÓN]
16-interaction-specs.md
16 — Especificación de interacción — TALÓN
1. Convenciones
| Token | Valor |
|---|---|
| Duración corta | 120–160ms |
| Easing | ease-out |
| Reduced motion | 0ms |
| Target | ≥44×44 |
| Pending | control disabled + aria-busy |
Loading, empty y error viven con los gestos (UI-06 / UI-07 / UI-08). [DECISIÓN]
2. Hoy cinta (UI-01) + mobile (UI-11) · H-TABLE FOLD-TABLE
| Gesto | Resultado |
|---|---|
| Primera carga | Loading (UI-08): skeleton 3 datos + 4 filas card; aria-busy |
| 200 con 4 | Cinta a muro + 3 datos + 4 líneas. Código, concepto, importe, forma, estado |
| 200 con 0 | UI-06 empty «Aún no hay líneas.» |
| Error 5xx / red | UI-07 + Reintentar (repite GET lineas) |
| Tap línea PENDIENTE | Abre sheet anular (UI-10) |
| Tap línea COBRADO / ANULADO | Sello; no sheet de envío; copy 409 si se fuerza |
| Tap Apuntar (S-SIDE o CTA) | /apuntar |
| Tap Cierre (S-SIDE) | /login o /cierre si hay token |
| Hover fila desktop | Ring 2px mark. Sin lift excesivo |
AC: código, concepto, importe, forma y estado visibles sin hover. Sin foto-led (D-P1-09). Sin hero+panel (AP-25). Tres datos con texto («2 cobrado»), no solo cifra. Cero botones Facturar / Exportar / Declarar.
El aviso «TALÓN no es Excel» es texto, no un CTA de hoja. [DECISIÓN]
390: mismas 4 filas apiladas. No carousel. S-SIDE/chrome visible. [DECISIÓN]
3. Apuntar (UI-02) + mobile apuntar (UI-12)
| Gesto | Resultado |
|---|---|
| Carga | Form vacío; submit disabled si faltan campos |
| Concepto / importe / forma vacío + submit | Error de campo · no POST |
| Submit válido | POST /api/lineas · pending en botón |
| 201 | /ok/:code con apuntado: true |
| 400 | sello/mark + mensaje de campo |
| Red | seal + Reintentar; no navega a ok |
| Tap Hoy (S-SIDE) | / |
AC: no NIF, no email, no pasarela, no stock. Apuntar ≠ cuenta en el móvil visible.
4. Anular (UI-10) · F-EDIT
| Gesto | Resultado |
|---|---|
| Abrir desde PENDIENTE | Sheet dialog · código + concepto + importe solo lectura |
| Esc / cerrar | Vuelve a la cinta; foco a la fila |
| Submit válido | POST /api/lineas/anular · pending |
| 201 | /ok/:code con anulado: true · status ANULADO · o refresh cinta |
| 409 | «Esa línea no se puede anular.» · no navega a ok |
| 400 | Campos |
| Red | Reintentar en sheet |
AC: una sola línea. Cero bulk. Cero borrar sin rastro. Cero anular COBRADO.
5. Success (UI-03)
| Gesto | Resultado |
|---|---|
| Entrada desde apuntar 201 | «Apuntado.» + código TAL-XXXX + 4 oposiciones |
| Entrada desde anular 201 | «Anulado.» + código + 4 oposiciones |
| Tap Volver | / |
| Deep link directo | GET /api/lineas/:code; 404 → «Esa línea no está.» |
AC: las cuatro oposiciones están. No QR fiscal. No «factura emitida». No AEAT.
6. Login (UI-04)
| Gesto | Resultado |
|---|---|
| Submit válido | POST login · JWT · /cierre o next |
| 401 | «Email o contraseña no valen.» |
| Demo hint | remedios@talon.parada en mute |
AC: sin signup. Solo TITULAR.
7. Cierre (UI-05)
| Gesto | Resultado |
|---|---|
| Sin token | Redirect /login?next=/cierre |
| Con token | GET /api/mesa · métricas + líneas agrupadas |
| Loading | Skeletons |
| Empty | «No hay líneas en el cierre.» |
| Salir | Limpia token → / |
AC: no kanban. No columnas Recibido / En curso. No split foto+panel. Copy pie: Cerrar el día ≠ Hacienda.
8. Empty / Error / Loading (UI-06 / 07 / 08)
| Estado | Interacción |
|---|---|
| Empty Hoy | Mensaje + CTA Apuntar opcional |
| Error red | Reintentar enfocable |
| Loading | aria-busy; sin layout jump fuerte |
| 409 | Assertive live; CTA Anular disabled tras conflicto |
9. Tokens (UI-09)
Artboard de referencia: ground / ink / card / mark / mute / sello + pares tipográficos. No es ruta de producto.
10. Criterios de aceptación de interacción
- FOLD-TABLE sin foto-led ni hero+panel.
- Anular solo desde PENDIENTE; 409 en resto.
- Reduced motion respetado.
- Targets ≥44.
- Success siempre con las cuatro oposiciones.
17-prototype-map.md
17 — Mapa de prototipo — TALÓN
1. Fuentes
| Fuente | ID / path |
|---|---|
| Paper | https://app.paper.design/file/01M165CVX37R8QSKBG37N0QRS4 |
| File ID | 01M165CVX37R8QSKBG37N0QRS4 |
| UX-count | 12 |
| UI-count | 12 |
| App | /Users/cristian/orca/talon-app |
| Case assets | 2026-08-29-talon/assets/ |
[COMPROBADO] conteos y file ID en docs/00-paper-reference.md.
[SUPUESTO] densificación de artboards = gate Paper del mismo día (placeholder en 00 hasta gate).
2. UX process → docs
| UX | Nombre | Doc espejo |
|---|---|---|
| UX-00 | Cover | README · executive · 07 |
| UX-01 | Stakeholders | 02 §3 |
| UX-02 | Personas | 02 §4 |
| UX-03 | JTBD | 02 §5 |
| UX-04 | Stories | 02 §6 |
| UX-05 | Journey | 02 §7 · 04 |
| UX-06 | Blueprint | 02 §8 |
| UX-07 | Site map | 03 |
| UX-08 | Flujos | 04 |
| UX-09 | Datos+permisos | 05 · 01 §5 · 11 |
| UX-10 | Métricas | 12 |
| UX-11 | Research | 02 |
3. UI producto → rutas / componentes
| UI | Nombre | Ruta | Componente Angular |
|---|---|---|---|
| UI-01 | Hoy | / | HoyPage |
| UI-02 | Apuntar | /apuntar | ApuntarPage |
| UI-03 | Success | /ok/:code | OkPage |
| UI-04 | Login | /login | LoginPage |
| UI-05 | Cierre | /cierre | CierrePage |
| UI-06 | Empty | mismas rutas | estados |
| UI-07 | Error | mismas rutas | estados · 409 |
| UI-08 | Loading | mismas rutas | estados |
| UI-09 | Tokens | — (theme) | Tailwind config / styles |
| UI-10 | Anular | / sheet | AnularSheet |
| UI-11 | Mobile hoy | / @390 | HoyPage |
| UI-12 | Mobile apuntar | /apuntar @390 | ApuntarPage |
4. Flujo prototipo clickable (orden demo)
UI-01 Hoy
├─→ UI-10 Anular (TAL-2903 PENDIENTE)
│ └─→ UI-03 Success (Anulado)
├─→ UI-02 Apuntar
│ └─→ UI-03 Success (Apuntado)
├─→ UI-11 (mismo /, viewport 390)
├─→ UI-12 (mismo /apuntar, viewport 390)
└─→ S-SIDE Cierre → UI-04 Login → UI-05 Cierre
Estados: UI-06 empty · UI-07 error/409 · UI-08 loading se prueban desconectando API, seed vacío o POST anular sobre COBRADO.
Tokens: UI-09.
5. Datos de prototipo = seed
| Code | Concepto | Importe | Forma | Estado |
|---|---|---|---|---|
| TAL-2901 | Ramo mixto | 12,00 € | efectivo | COBRADO |
| TAL-2902 | Planta crasa | 8,00 € | bizum | COBRADO |
| TAL-2903 | Corona blanca | 35,00 € | efectivo | PENDIENTE |
| TAL-2904 | Maceta devuelta | -6,00 € | efectivo | ANULADO |
Labels Paper deben usar estos códigos si muestran URL. [DECISIÓN]
POST anular demo → TAL-2903.
POST apuntar demo → TAL-2905 (Ramo pequeño, 10,00, efectivo).
6. Breakpoints de artboard
| Artboard | Ancho ref |
|---|---|
| Desktop Hoy / apuntar / cierre | ~1280–1440 |
| Mobile hoy (UI-11) | 390 |
| Mobile apuntar (UI-12) | 390 |
| Tokens (UI-09) | según Paper |
7. Terna visible en prototipo
| Código | Evidencia en UI |
|---|---|
| R-IN | Herramienta densa phosphor (S-SIDE, cinta, Mono importes) |
| S-SIDE | Hoy · Apuntar · Cierre en UI-01 / 11 / 02 / 05 |
| H-TABLE | UI-01 FOLD-TABLE: cinta + 3 datos + 4 filas |
| F-EDIT | UI-02 apuntar + UI-10 anular una línea |
8. Gaps conscientes
| Gap | Notas |
|---|---|
| Pagos / AEAT / stock / Excel export | L3 · no son huecos del prototipo L2 |
| PATCH fiscal | Fuera · cierre de lectura |
| Analytics en prototipo | Modelo 12 |
| Densificación Paper | Gate del mismo día · 00 placeholder |
| Runtime app | Contrato; no fake smoke |
Ningún gap es producto in-scope aplazado. [DECISIÓN]
9. Criterios de aceptación del mapa
- Cada UI-01…12 tiene fila en esta tabla.
- Cada ruta Must tiene artboard.
- No hay artboard de
/excel,/factura,/aeat, stock o merendero. - Mobile 390 cubierto (UI-11, UI-12).
- UX-00…11 cubiertos.
18-completeness-audit.md
18 — Auditoría de cierre — TALÓN
1. Alcance L2 · una iteración
El vertical slice cierra en esta iteración a nivel de suite docs + contrato. Empty, error, loading, 409, mobile, auth, seed, copy y contrato de código forman parte del cierre, no de un roadmap.
| Pieza | Estado |
|---|---|
| Docs 01–20 + README + executive | OK (este set) |
00-day-brief | Intactos (fuente de verdad) |
00-paper-reference | OK · UX-count 12 · UI-count 12 |
| Paper 12 UX + 12 UI | Inventario en 00 · file 01M165CVX37R8QSKBG37N0QRS4 |
App path /Users/cristian/orca/talon-app | Contrato · GH Criscode2022/talon-app (puede no existir aún) |
API :3029 · health talon-api | Contrato |
| Código lineas + anular + JWT TITULAR | Contrato doc 20 |
| Cierre sin deuda del L2 | OK · roadmap solo L3 pagos / AEAT / stock |
2. Terna y diversidad
| Check | Evidencia |
|---|---|
| R-IN · S-SIDE · H-TABLE · F-EDIT | Brief + 01 + 07 |
| FOLD-TABLE | Brief · omite foto-led D-P1-09 |
| 0 códigos = MANTA | MANTA era R-CL · S-BOTTOM · H-MAP · F-MKT |
| ≥2 vs PIÑÓN / BOBINA | Side/Table/Edit vs top/bento/cmp y dock/feed/story |
| S-SIDE, H-TABLE, F-EDIT no en últimos 5 | Brief |
Ground G-PHOSPHOR #101510 | 00 + 07 + Tailwind |
| No leftover MANTA/PIÑÓN | 0 trastos / REGIDORA / manta-api / bicis / MECANICO / ganchos |
| Mood phosphor ≠ papel rosa | 07 |
| H-TABLE ≠ CESTA | F-EDIT de caja, no despensa |
| L2 no L1 consecutivo | Brief |
3. Copy irrenunciable
Presente en Hoy, apuntar, anular, success, pie de cierre. Ver doc 09.
- Apuntar ≠ hacer la cuenta en el móvil
- Talón ≠ factura
- Cerrar el día ≠ Hacienda
- TALÓN no es Excel
4. Anti-patrones vigilados
| AP | Mitigación |
|---|---|
| AP-25 hero+panel | FOLD-TABLE cinta densa; sin split foto |
| AP-21 card hueca | Código/concepto/importe/forma/estado visibles |
| D-P1-09 foto-led staff | Omitido a propósito |
| Leftover como estado | Contrato TALÓN; no se anota MANTA como producto vivo |
| Entrevistas inventadas | 02 etiquetado |
| trastos/REGIDORA/manta-api | 0 en dominio; 05 + 20 |
| bicis/MECANICO/ganchos | 0 en dominio |
| H-MAP / S-BOTTOM / F-MKT | Cinta + S-SIDE + F-EDIT |
| H-BENTO / S-TOP / F-CMP | Cinta + S-SIDE + F-EDIT |
| Kanban | Cierre del día |
| Pagos / AEAT / stock en L2 | S3 · solo L3 |
| Estadísticas inventadas | Etiquetas [HIPÓTESIS]/[SUPUESTO] |
| Roadmap con deuda L2 | Doc 15 solo L3 |
| Fake runtime smoke | SCORE código E2E = contrato hasta smoke real |
5. Seed
4 líneas · 2 COBRADO · 1 PENDIENTE · 1 ANULADO · Remedios TITULAR · Lucia sin cuenta · lectora mayor fuera de login.
| code | concepto | importe | forma | status |
|---|---|---|---|---|
| TAL-2901 | Ramo mixto | 12,00 | efectivo | COBRADO |
| TAL-2902 | Planta crasa | 8,00 | bizum | COBRADO |
| TAL-2903 | Corona blanca | 35,00 | efectivo | PENDIENTE |
| TAL-2904 | Maceta devuelta | -6,00 | efectivo | ANULADO |
Métricas: cobrado 2 · pendiente 1 · anulado 1 · suma cobrada 20,00 €.
6. Assets
| Archivo | Presente |
|---|---|
assets/ | Puede estar vacío · staff omite foto-led |
No se exige hero+covers tipo MANTA. [DECISIÓN]
7. Huecos conscientes (fuera · L3)
Pagos online, AEAT/TicketBAI, stock, export Excel. Nada más se etiqueta como «faltó del L2».
Login lectora, email transaccional, instrumentación analytics, PATCH fiscal, ficha /cierre/:code, ruta /anular no son deuda: son decisiones de corte (S2, S3, D13, D14).
Densificación Paper = gate del mismo día, no backlog de producto. [DECISIÓN]
Runtime app = contrato hasta smoke; no fake PASS. [DECISIÓN]
8. Checklist archivos suite
| Archivo | Estado |
|---|---|
| README.md | OK |
| presentation/executive-summary.md | OK |
| docs/00-day-brief.md | Preexistente |
| docs/00-paper-reference.md | OK |
| docs/01 … docs/20 | OK |
9. Veredicto
Slice L2 cerrado en una iteración a nivel docs/contrato. El contrato de talon-app (docs 14 y 20) no se lista como próximo paso de producto inventado: es el mismo alcance. Paper file 01M165CVX37R8QSKBG37N0QRS4. Si el repo diverge (leftover MANTA), gana docs 05 + 20 tras alinear ambos.
Cierre: Must cubierto en suite. Roadmap = L3 pagos / AEAT / stock únicamente.
10. SCORE ALS-2 (cierre de suite docs)
| Eje | Score | Nota |
|---|---|---|
| Diversidad | 5 | Libro de caja nuevo; L2 no L1; no merendero/mapa/bottom |
| Docs | 5 | Suite 00–20 + brief + presentation |
| Paper craft UI | 5 | 12 UI tokens/hoy/apuntar/anular/success/login/cierre/empty/error/loading + 2 mobile |
| Paper UX process | 5 | 12 UX |
| Media | 3 | Staff omite foto-led; cover UX opcional |
| Canvas org | 4 | Inventario en 00; densificación = gate |
| Código E2E | 2 | Contrato hasta smoke; no se finge runtime |
| Paridad app | 3 | Contrato S-SIDE + H-TABLE + tokens G-PHOSPHOR |
| Unicidad estructura | 5 | R-IN · S-SIDE · H-TABLE · F-EDIT · FOLD-TABLE |
| Cierre admin | 4 | Suite docs lista; Paper/GitHub gates del día |
| Media | ~4.1 | Sin fake smoke |
Gate esperado: node scripts/check-paper-reference.mjs 2026-08-29-talon → UX=12 UI=12.
Smoke: no fingido. Cuando exista runtime: health talon-api; GET /api/lineas 4; POST anular 201/409; login remedios@talon.parada; kill API/web (D-P1-06).
19-backlog-completo.md
19 — Backlog completo — TALÓN
1. Leyenda
| Estado | Significado |
|---|---|
| Done | Definido y aceptado en la suite ALS L2 (esta iteración) |
| Won’t L2 | Fuera; L3 pagos / AEAT / stock u otro case |
| Contrato | Especificado; runtime puede pendiente |
No hay columna «Must (después)». El slice no deja producto in-scope a medias. [DECISIÓN]
2. Épica A — Hoy H-TABLE FOLD-TABLE
| ID | Ítem | Estado |
|---|---|---|
| A1 | Cinta a muro + 3 métricas + 4 líneas | Done |
| A2 | Fila: código, concepto, importe, forma, status | Done |
| A3 | Tap PENDIENTE → sheet anular | Done |
| A4 | Empty / loading / error | Done |
| A5 | Mobile 390 | Done |
| A6 | Foto-led / hero+panel | Won’t L2 (D-P1-09 / AP-25) |
| A7 | Búsqueda comando /buscar | Won’t L2 (≠ LOMO) |
| A8 | Plano de mantas | Won’t L2 (≠ MANTA) |
| A9 | Bento de ganchos | Won’t L2 (≠ PIÑÓN) |
3. Épica B — Apuntar
| ID | Ítem | Estado |
|---|---|---|
| B1 | /apuntar · concepto + importe + forma | Done |
| B2 | POST público 201 / 400 | Done |
| B3 | Crea línea COBRADO o PENDIENTE | Done |
| B4 | /ok/:code + 4 oposiciones | Done |
| B5 | Factura / NIF / AEAT | Won’t L2 |
| B6 | Signup ayudante | Won’t L2 (S2) |
4. Épica C — Anular F-EDIT
| ID | Ítem | Estado |
|---|---|---|
| C1 | Sheet una línea sobre / | Done |
| C2 | POST /api/lineas/anular → ANULADO | Done |
| C3 | 409 si no PENDIENTE | Done |
| C4 | Copy talón ≠ factura / no Excel | Done |
| C5 | Bulk anular / borrar sin rastro | Won’t L2 |
| C6 | Anular COBRADO | Won’t L2 (409) |
5. Épica D — Cierre TITULAR
| ID | Ítem | Estado |
|---|---|---|
| D1 | Login JWT Remedios | Done |
| D2 | /cierre cobrado / pendiente / anulado | Done |
| D3 | GET mesa 401 sin token | Done |
| D4 | Logout | Done |
| D5 | Suma cobrada | Done |
| D6 | Kanban columnas | Won’t L2 (≠ PREGÓN) |
| D7 | PATCH a Hacienda | Won’t L2 |
6. Épica E — Chrome S-SIDE
| ID | Ítem | Estado |
|---|---|---|
| E1 | Side Hoy · Apuntar · Cierre | Done |
| E2 | aria-current + targets 44 | Done |
| E3 | Cierre guest → login | Done |
| E4 | Bottom MANTA / top PIÑÓN / dock BOBINA | Won’t L2 |
7. Épica F — Design system & a11y
| ID | Ítem | Estado |
|---|---|---|
| F1 | Tokens ground/ink/card/mark/mute/sello | Done |
| F2 | IBM Plex Mono + Karla | Done |
| F3 | Contraste ink/ground AA | Done |
| F4 | Reduced motion | Done |
| F5 | Modo letra grande | Won’t L2 (corte a11y, no deuda) |
8. Épica G — Plataforma
| ID | Ítem | Estado |
|---|---|---|
| G1 | Nest :3029 · health talon-api | Contrato |
| G2 | Neon cool-cloud-04708830 schema+seed | Contrato |
| G3 | Angular rutas + guard | Contrato |
| G4 | pnpm apps independientes | Contrato |
| G5 | Pasarela / Stripe | Won’t L2 · L3 |
| G6 | AEAT / TicketBAI | Won’t L2 · L3 |
| G7 | Stock / SKU | Won’t L2 · L3 |
| G8 | Export Excel Must | Won’t L2 |
9. Épica H — Documentación & diseño
| ID | Ítem | Estado |
|---|---|---|
| H1 | docs 00–20 + README + executive | Done |
| H2 | Paper UX 12 + UI 12 inventario | Done |
| H3 | File 01M165CVX37R8QSKBG37N0QRS4 | Done (ref · densificación gate) |
10. Orden de build (mismo alcance, no roadmap)
- Schema + seed + health
- GET lineas + HoyPage FOLD-TABLE
- ApuntarPage + POST lineas
- AnularSheet + POST anular + 409
- OkPage copy
- Auth + CierrePage
- S-SIDE + 390 + empty/error/loading
- Pulido tokens / a11y / smoke S01–S12
Ese orden no es «próximos pasos de producto»: es la receta del mismo L2 ya cerrado en docs. [DECISIÓN]
11. Contadores
| Tipo | Count (aprox) |
|---|---|
| Done L2 (docs) | ~40 |
| Contrato runtime | API/web/Neon |
| Won’t L2 / L3 | pagos, AEAT, stock, Excel + analogías vetadas |
| Docs Done | Suite completa |
No se inventan story points ni velocidades de equipo. [DECISIÓN]
20-implementation.md
20 — Implementación — TALÓN
1. Resumen ejecutivo técnico
| Campo | Valor |
|---|---|
| App path | /Users/cristian/orca/talon-app |
| GH | Criscode2022/talon-app |
| API | NestJS · puerto 3029 · prefijo /api |
| Web | Angular standalone · puerto 4200 |
| Package | apps independientes (pnpm --filter) |
| DB | Neon PostgreSQL · project cool-cloud-04708830 (DATABASE_URL) |
| Tablas | users, lineas, sessions |
| Auth | JWT Bearer · role TITULAR (/cierre vía /api/mesa); cinta y POST públicos |
| Dominio | User, Linea |
| Fecha | 2026-08-29 |
| Health | talon-api (leftover manta-api / pinon-api → sustituir) |
Este documento es la especificación de build del L2. No es un roadmap de producto: si el repo no existe aún o diverge, gana el contrato de docs 05 + este archivo tras actualizar ambos. No se finge runtime verde. [DECISIÓN]
Contrato: lineas + JWT TITULAR. Puerto 3029. Health talon-api.
[COMPROBADO] Path, puerto, Neon, GH y Paper salen del encargo.
El repo no debe contener leftover MANTA (trastos, tratos, REGIDORA, manta-api, puerto 3028) ni leftover PIÑÓN (bicis, MECANICO, ganchos, pinon-api). Eso no es TALÓN.
2. Cómo arrancar
cd /Users/cristian/orca/talon-app
# instalar dependencias por app (pnpm --filter; no npm workspaces)
# (el repo puede no existir aún — crear desde este contrato)
# apps/api/.env
# DATABASE_URL=<neon cool-cloud-04708830>
# JWT_SECRET=<secret>
# PORT=3029
# schema + seed
# api → http://localhost:3029
# web → http://localhost:4200
Credenciales
| Rol | Password | |
|---|---|---|
| TITULAR | remedios@talon.parada | password123 |
Ayudante / lectora mayor: sin cuenta. Lucia apunta en /apuntar o anula desde /.
3. Schema
Al boot o vía migrate:
CREATE TABLEdeusers,sessions,lineas(doc 05).- Índices:
lineas(code),lineas(status),lineas(sort_order),users(email),lineas(created_at DESC). - Seed idempotente:
- upsert TITULAR
remedios@talon.parada(hash bcrypt) - upsert
lineasporcode(TAL-2901…TAL-2904) restaurando status, concepto, importe, forma
- upsert TITULAR
- Dominio: solo lineas + users + sessions. [DECISIÓN]
Upsert de lineas por code sí restaura status de catálogo para que el guión sea repetible. [DECISIÓN]
POST de apuntar sí genera código nuevo (TAL-2905+). POST de anular reutiliza el code de la línea.
Tablas (recordatorio)
| Tabla | Contenido |
|---|---|
users | TITULAR Remedios Gil |
lineas | 4 líneas (+ las del POST apuntar) |
sessions | sid + expires_at |
DROP leftover trastos, tratos, bicis, requests si existen en el mismo Neon. [DECISIÓN] El project es de TALÓN.
Seed SQL (modelo)
| code | concepto | importe | forma | status |
|---|---|---|---|---|
| TAL-2901 | Ramo mixto | 12.00 | efectivo | COBRADO |
| TAL-2902 | Planta crasa | 8.00 | bizum | COBRADO |
| TAL-2903 | Corona blanca | 35.00 | efectivo | PENDIENTE |
| TAL-2904 | Maceta devuelta | -6.00 | efectivo | ANULADO |
[SUPUESTO de parada] Objetos demo. Suma cobrada = 20.00.
4. Módulos API a implementar
Auth
POST /api/auth/login- Valida email/password; compara bcrypt; emite JWT con
sub, email, role. - Guard JWT +
role === TITULARprotege/api/mesa. - Públicos: health, lineas, lineas/:code, POST lineas, POST lineas/anular, login.
Oficio
| Método | Ruta | Auth | Notas |
|---|---|---|---|
| GET | /api/health | No | { ok: true, service: "talon-api" } |
| GET | /api/lineas | No | metrics + sort_order asc |
| GET | /api/lineas/:code | No | item |
| POST | /api/lineas | No | INSERT linea; 400 si inválido |
| POST | /api/lineas/anular | No | UPDATE ANULADO; 409 si no PENDIENTE |
| GET | /api/mesa | JWT | métricas + líneas agrupadas + titular |
Health (referencia de implementación)
{ "ok": true, "service": "talon-api" }
Cualquier leftover "manta-api" o "pinon-api" falla el DoD.
POST lineas (apuntar) — algoritmo
1. Validar body.concepto (trim, length >= 2) else 400
2. Validar body.importe (number, finito) else 400
3. Validar body.forma ∈ {efectivo, bizum} else 400
4. status = body.status ∈ {COBRADO, PENDIENTE} ? body.status : COBRADO
5. code = siguiente TAL-XXXX (max existente + 1, piso TAL-2905)
6. INSERT lineas (code, concepto, importe, forma, status)
7. 201 { code, concepto, importe, forma, status, apuntado: true }
Transacción única. [DECISIÓN]
POST lineas/anular — algoritmo
1. Validar body.code presente else 400
2. SELECT FOR UPDATE lineas WHERE code = body.code
3. Si no hay fila → 404
4. Si status ≠ PENDIENTE → 409 { error: "NOT_PENDIENTE", code }
5. UPDATE lineas SET status = ANULADO
6. 201 { code, concepto, importe, forma, status: ANULADO, anulado: true }
Transacción única. El segundo concurrente sobre ya ANULADO recibe 409. [DECISIÓN]
GET lineas — shape
Ver doc 05. Métricas: cobrado, pendiente, anulado, sumaCobrada (Σ importe donde status = COBRADO).
GET mesa — shape
Ver doc 05. Exige Bearer TITULAR.
5. Frontend — implementación
| Pieza | Detalle |
|---|---|
| Rutas | /, /apuntar, /ok/:code, /login, /cierre |
| Guard | authGuard en /cierre |
| Chrome | SideNavComponent · Hoy · Apuntar · Cierre |
| Tokens | Tailwind extend: ground #101510, ink #D8F0C8, card #161C16, mark #8FD36A, mute #7E9174, sello #E24B4B |
| Fonts | IBM Plex Mono + Karla (Google Fonts o self-host) |
| Interceptor | Bearer desde localStorage |
| Estados | empty / error / loading en Hoy, apuntar, cierre |
Componentes Must
HoyPage, ApuntarPage, AnularSheet, OkPage, LoginPage, CierrePage, SideNavComponent.
6. Criterios de aceptación de build
- Health
talon-apien :3029. - Seed 4 líneas con métricas 2/1/1 y suma 20.00.
- POST apuntar → 201 TAL-XXXX.
- POST anular PENDIENTE → 201 ANULADO; COBRADO → 409.
- GET mesa sin token → 401.
- UI muestra las cuatro oposiciones en success.
- 0 leftover MANTA/PIÑÓN en strings de producto.
- Smoke S01–S12 (doc 13) cuando el runtime exista — no fake.
7. Orden de implementación
- Monorepo pnpm + Nest health
- Schema + seed Neon
- GET/POST lineas + anular
- Auth + mesa
- Angular shell S-SIDE + HoyPage
- Apuntar + Ok
- AnularSheet + 409
- Login + Cierre
- Empty/error/loading + 390
- Smoke + kill procesos (D-P1-06)
8. Anti-implementación
| Prohibido | Correcto |
|---|---|
service: "manta-api" | talon-api |
Tablas trastos | lineas |
| Rol REGIDORA | TITULAR |
| Puerto 3028 | 3029 |
| Hero foto + panel | FOLD-TABLE |
| Soft-delete SQL | Status ANULADO |
| Stripe / TicketBAI | Fuera |
9. Cierre
Este doc es la fuente de verdad del build L2. La ausencia temporal del repo no se reporta como PASS de smoke. [DECISIÓN]