En esta página 00-day-brief 0%

00-day-brief.md

00 — Day brief · 2026-08-29 · TALÓN

Decisiones ALS-2 BRIEF

CampoValor
Fecha2026-08-29
NombreTALÓN
ComplejidadNivel 2 (no L1 consecutivo tras MANTA)
SectorContabilidad / parada de mercadillo (Tetuán · Maravillas)
TipoLibro de caja del día: cinta de líneas + apuntar + cierre TITULAR JWT
PlataformaWeb responsive (tabla en el iPad de la parada · rail en el portátil)
RegistroR-IN — herramienta densa, no landing de barrio
ShellS-SIDE — Hoy · Apuntar · Cierre
HomeH-TABLE — cinta de líneas a muro, sin foto hero
FlujoF-EDIT — apuntar / anular una línea
FoldFOLD-TABLE (CRON §5.9)
Por qué no MANTANo S-BOTTOM / H-MAP / F-MKT; no hotspots; no plaza
Por qué no PIÑÓNNo S-TOP / H-BENTO / F-CMP; no muro de fotos
Por qué no BOBINANo S-DOCK / H-FEED / F-STORY; no cartel+tira
Por qué no LOMONo S-CMD / H-DATA / F-LEAD; no split foto+rail (FOLD-SPLIT)
Por qué no ExcelEl 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:
    • #101510 tubo apagado (ground)
    • #D8F0C8 fósforo de lectura (ink)
    • #161C16 tecla (card)
    • #8FD36A fósforo (mark)
    • #7E9174 mute
    • #E24B4B LED 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

  1. Home tabla: 4 líneas + 3 métricas (cobrado / pendiente / anulado)
  2. Apuntar una línea (concepto, importe, forma)
  3. Anular una línea pendiente (F-EDIT)
  4. Success con código TAL-XXXX
  5. Login JWT TITULAR
  6. Cierre del día (mesa) — no kanban
  7. Empty / error / loading / mobile
  8. ≥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

IDSeñal
H1Una cinta de líneas reduce «¿cuánto llevamos?» en el móvil de notas
H2Anular en el talón evita tachar a bolígrafo y perder el recuento
H3Cuatro líneas bastan para el iPad de la parada; no hace falta Excel

Seed demo

CódigoConceptoImporteFormaEstado
TAL-2901Ramo mixto12,00 €efectivoCOBRADO
TAL-2902Planta crasa8,00 €bizumCOBRADO
TAL-2903Corona blanca35,00 €efectivoPENDIENTE
TAL-2904Maceta devuelta-6,00 €efectivoANULADO

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

URLhttps://app.paper.design/file/01M165CVX37R8QSKBG37N0QRS4
File ID01M165CVX37R8QSKBG37N0QRS4

UX-count: 12 UI-count: 12

UX process (prefijo UX- · mínimo 12)

IDNombreContenido
UX-00CoverIdentidad phosphor, terna, parada Tetuán · Maravillas
UX-01StakeholdersRemedios TITULAR, ayudante de parada
UX-02PersonasRemedios Gil / ayudante / a11y
UX-03JTBDFuncional / emocional / social
UX-04StoriesMust hoy / apuntar / anular / cierre
UX-05JourneyApuntar → cinta → anular → cerrar el día
UX-06BlueprintFrontstage / caja / Neon / 409
UX-07Site mapS-SIDE Hoy · Apuntar · Cierre
UX-08FlujosPOST lineas + anular + JWT
UX-09Datos + permisosLinea / User TITULAR
UX-10MétricasNorth star «¿cuánto llevamos?» sin móvil de notas
UX-11Research notesCOMPROBADO / SUPUESTO / HIPÓTESIS / DECISIÓN

UI producto (prefijo UI- · mínimo 10)

IDNombreFlujo
UI-01HoyHome H-TABLE cinta · FOLD-TABLE
UI-02ApuntarF-EDIT apuntar línea
UI-03SuccessTAL-XXXX copy duro
UI-04LoginJWT TITULAR
UI-05CierreMesa del día · no kanban
UI-06EmptySin líneas aún
UI-07Error409 / red
UI-08LoadingSkeletons
UI-09TokensG-PHOSPHOR
UI-10AnularF-EDIT anular pendiente
UI-11Mobile hoyCore 390
UI-12Mobile apuntarForm 390

01-project-definition.md

01 — Definición de proyecto — TALÓN

1. Identidad

CampoValor
NombreTALÓN
SignificadoEl 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 fraseCinta de líneas del día + apuntar / anular + cierre TITULAR JWT.
SectorContabilidad / parada de mercadillo (Tetuán · Maravillas, Madrid)
TipoWeb L2 — home H-TABLE FOLD-TABLE + chrome S-SIDE + flujo F-EDIT + cierre JWT — Nivel 2, vertical slice de libro de caja
PlataformaWeb responsive (tabla en el iPad de la parada · rail en el portátil)
Mercado demoEspaña · Madrid · Tetuán / Maravillas (una parada, no un ERP)
Idiomaes-ES
Fecha caso2026-08-29
TernaR-IN · S-SIDE · H-TABLE · F-EDIT
FoldFOLD-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

ProblemaQuién lo sufreEfecto
«¿Cuánto llevamos?» en notas del móvilAyudante + TITULARRecuento a ojo; errores al cierre
Apuntar se lee como cuenta en el móvilAyudanteEsperan calculadora / Excel / app bancaria
Anular se lee como borrar sin rastroTITULARTachan a bolígrafo y pierden el recuento
Cerrar el día se lee como HaciendaTITULAREsperan AEAT, TicketBAI, modelo fiscal
El cierre se lee como kanbanTITULAREsperan Recibido / En curso / Cerrado
El dueño pide pagos online y stock el día 1ParadaEl 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

IDHipótesisSeñal de validación (futura)
H1Una cinta de líneas reduce «¿cuánto llevamos?» en el móvil de notas% de visitas a / que consultan cobrado/pendiente sin abrir notas
H2Anular en el talón evita tachar a bolígrafo y perder el recuentoPOST /api/lineas/anular sobre PENDIENTE; métricas coherentes
H3Cuatro líneas bastan para el iPad de la parada; no hace falta Excel0 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

ParaValor
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ÓNUna superficie mínima: hoy + apuntar + anular + cierre, sin Excel y sin AEAT.

No es TALÓN

ExcluidoPor qué
Excel / hoja de cálculo / pivotTALÓN no es Excel
Factura / modelo fiscalTalón ≠ factura
Declaración AEAT / TicketBAICerrar el día ≠ Hacienda
Cuenta en el móvil / calculadora bancariaApuntar ≠ hacer la cuenta en el móvil
Pagos online / TPV cloud / Bizum gatewayS3 · forma de pago es etiqueta, no pasarela
Stock / SKU / catálogoS3 · 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-empresaL2 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

RolObjetivo medible en demo
AYUDANTEVer 4 líneas, apuntar una y ver el success en < 90 s, sin cuenta
TITULAREntrar a cierre, ver cobrado / pendiente / anulado en < 45 s
LECTORA MAYORNo 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ónAnónimo (ayudante)TITULARLECTORA MAYOR
Ver Hoy /Sin cuenta; usa la pública
Ver Apuntar /apuntar
POST apuntar líneaSí (mismo form público)
POST anular pendiente si PENDIENTE
Ver success /ok/:code (código en URL)
Ver cierre /cierreNo (401 / redirect)No
GET /api/mesa401
Ver detalle de cierreNoSí (mesa)
Cobrar online / AEATNo (no existe)NoFuera
Stock / SKUCopy: fueraCopy: fueraOficio 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)

TipoMétricaDefinición
North Star% de consultas «¿cuánto llevamos?» resueltas en la cinta sin móvil de notasOficio de talón, no pageviews
Activación1.er POST /api/lineas exitosoH1
Integridad de anulaciónPOST anular sobre no-PENDIENTE → 409H2
Integridad de authGET /api/mesa sin token → 401; POST lineas sin token → 201Cinta pública + cierre TITULAR cerrado
Integridad de importeSuma cobrada coherente con estados COBRADOSeed demo 20,00 €
SaludError rate API lineas4xx/5xx

7. Alcance funcional v1 (L2)

MóduloIncluido
Home cintaGET /api/lineas · tabla a muro + 3 métricas (cobrado / pendiente / anulado) + 4 líneas
Apuntar/apuntar · concepto, importe, forma · POST /api/lineas
AnularF-EDIT sobre Hoy · una línea PENDIENTE · POST /api/lineas/anular · 409 si no PENDIENTE
Success/ok/:code · código + 4 oposiciones
AuthPOST /api/auth/login → JWT TITULAR
Cierre TITULARGET /api/mesa JWT · cobrado / pendiente / anulado, no kanban
Estados UIEmpty (0 líneas), loading skeleton, error de red, 409
MobileHoy ~390px · S-SIDE Hoy · Apuntar · Cierre · targets ≥44px
Seed1 TITULAR, 4 líneas (2 COBRADO, 1 PENDIENTE, 1 ANULADO)
SaludGET /api/health{ ok: true, service: "talon-api" }

8. Criterios de aceptación de producto

  1. / 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.
  2. Quien apunta puede ver 4 líneas, apuntar una y obtener success en /ok/TAL-XXXX, o anular una PENDIENTE.
  3. /ok/:code dice explícitamente que apuntar no es hacer la cuenta en el móvil y que talón no es factura.
  4. La UI dice explícitamente que cerrar el día no es Hacienda y que TALÓN no es Excel.
  5. Sin token, GET /api/mesa responde 401. POST /api/lineas, POST /api/lineas/anular y GET /api/lineas son públicos.
  6. Un POST de apuntar no crea user, no cobra online, no abre factura, no mueve kanban, no declara a AEAT.
  7. Un POST de anular sobre no-PENDIENTE responde 409. Una línea. Sin bulk.
  8. Una TITULAR inicia sesión y ve 4 líneas (2 COBRADO, 1 PENDIENTE, 1 ANULADO) en el seed.
  9. El tablero autenticado es un cierre del día. No es un kanban de 3 columnas. No es un split lista | ficha foto.
  10. Chrome S-SIDE: Hoy · Apuntar · Cierre. Home sin bottom de merendero y sin top de taller.
  11. Rutas solo las del doc 03. No existen /excel, /factura, /aeat, /stock.
  12. GET /api/health devuelve service: "talon-api" (no manta-api, no pinon-api).
  13. TAL-2901 y TAL-2902 aparecen COBRADO; TAL-2903 PENDIENTE; TAL-2904 ANULADO; suma cobrada demo 20,00 €.
  14. Staff FOLD-TABLE omite foto-led (D-P1-09). No se diseña hero+panel (AP-25).

9. Stack y artefactos

CapaDetalle
FrontendAngular + Tailwind · puerto 4200
BackendNestJS · puerto 3029
DBNeon PostgreSQL · project cool-cloud-04708830 (DATABASE_URL)
AuthJWT (TITULAR)
DiseñoPaper 01M165CVX37R8QSKBG37N0QRS4
Repo app/Users/cristian/orca/talon-app/ · GH Criscode2022/talon-app
Packagepnpm

[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

RiesgoImpactoMitigación v1
Expectativa de Excel«¿Dónde exporto?»Copy «TALÓN no es Excel»
Expectativa de facturaModelo fiscalCopy «Talón ≠ factura»
Expectativa de HaciendaAEAT, TicketBAICopy «Cerrar el día ≠ Hacienda»
Expectativa de cuenta móvilCalculadora / Bizum appCopy «Apuntar ≠ hacer la cuenta en el móvil»
Expectativa de kanbanRecibido / En cursoCierre del día, no columnas de flujo
Leftover MANTAtrastos, REGIDORA, manta-api, plazaContrato TALÓN; health talon-api; 0 copy de merendero
Leftover PIÑÓNbicis, MECANICO, ganchosDominio lineas + TITULAR
Pagos online el día 1Alcance L3 disfrazadoS3; H3: cuatro líneas
Stock el día 1Alcance inventarioS3
Cuenta de ayudanteRompe S2Sin signup; POST público
Home percibida como landingPérdida de H-TABLE / AP-25Cinta densa FOLD-TABLE, no hero+panel
Home percibida como plano MANTAConfundir con N−1Tabla, no H-MAP
Home percibida como bentoConfundir con PIÑÓNCinta, no H-BENTO
Anular COBRADORompe H2409 si no PENDIENTE
0 líneasCinta vacía sin oficioEmpty «Aún no hay líneas.»
Notas del móvil en paraleloH1 no se mideNorth star etiquetada como modelo
Sello como texto de párrafoContraste WCAGSello #E24B4B pinta ANULADO/error; ink escribe

11. Glosario

TérminoDefinición en TALÓN
TalónCinta del día; el producto, no la factura
LíneaEntrada de caja (lineas); código TAL-XXXX
CódigoTAL-XXXX; identifica la línea
ApuntarPOST /api/lineas; no es hacer la cuenta en el móvil
AnularPOST /api/lineas/anular; marca ANULADO si estaba PENDIENTE
HoySuperficie H-TABLE pública de líneas; cinta a muro
CierreSuperficie JWT de Remedios (métricas del día, no kanban ni Hacienda)
CobradoEstado COBRADO
PendienteEstado PENDIENTE; se puede anular
AnuladoEstado ANULADO; LED sello
SuccessCódigo (TAL-XXXX); no es una factura
S-SIDEChrome: Hoy · Apuntar · Cierre
TITULARUsuario autenticado que opera el cierre
AYUDANTEQuien apunta; no tiene fila en users
Formaefectivo / bizum (etiqueta; no pasarela)
ExcelHoja de cálculo; fuera. TALÓN no es Excel
FacturaModelo fiscal; fuera. Talón ≠ factura
HaciendaAEAT / TicketBAI; fuera. Cerrar ≠ Hacienda
PhosphorMood: tubo, fluorescente de parada a las 21:00; no papel rosa carbón
GroundTubo apagado #101510
InkFósforo de lectura #D8F0C8
CardTecla #161C16
MarkFósforo #8FD36A
Mute#7E9174
Sello#E24B4B, poco
FOLD-TABLEHome tabla densa; omite foto-led

12. Decisiones de diseño (cierre de brief)

IDDecisiónAlternativa descartada
D1Home = cinta H-TABLE FOLD-TABLEHero+panel (AP-25) · plano MANTA · bento PIÑÓN · feed BOBINA
D2Shell side Hoy · Apuntar · Cierre (S-SIDE)Bottom de merendero · top de taller · dock de cineclub
D3Registro innovador denso: herramienta de caja, no landing (R-IN)Papel rosa talonario (primer instinto) · botanical MANTA
D4Flujo F-EDIT (apuntar / anular una línea)F-MKT, F-CMP, F-LEAD, carrito checkout
D5Mood phosphorBookish talonario crema (primer instinto), vehicle dashboard, rusted, signage
D6Un rol autenticado TITULARMulti-rol ayudante / cliente / contable
D7Status COBRADO / PENDIENTE / ANULADOKanban; «facturado»; «enviado a AEAT»
D8Ayudante sin cuentaSignup, socio, usuario de caja
D9Cinta pública sin PII sensible de cierreTablero público enumerable de Hacienda
D10POST público de apuntar con concepto + importe + formaFormulario de NIF + factura + stock
D11Ground G-PHOSPHOR #101510G-BONE, G-GRAPHITE, G-VELVET, G-STONE, papel rosa
D12Success en /ok/:codeToast único sin pantalla
D13Apuntar en /apuntar; anular sheet sobre / (sin quinta ruta Must)/anular/:code; wizard fiscal
D14Cierre TITULAR = métricas + líneas del día, no kanban ni split fotoRecibido / En curso / Cerrado; lista | ficha
D15Cinta pública + cierre JWT (no auth-first total)Todo cerrado (rompería S2) · todo abierto (rompería cierre)
D16Sin pagos online / AEAT / stockPasarela + TicketBAI + inventario
D17Leftover MANTA/PIÑÓN no es el productoMantener trastos / REGIDORA / manta-api / bicis
D18Health talon-api · puerto 3029leftover manta-api · :3028
D19Anular = solo PENDIENTE; 409 si noSoft-delete libre; anular COBRADO
D20Staff omite foto-led (D-P1-09); FOLD-TABLEFOLD-SPLIT / hero+panel AP-25

13. Relación con el día anterior

CaseTernaPor qué TALÓN no lo copia
MANTA (N−1)R-CL · S-BOTTOM · H-MAP · F-MKTNo merendero, no plano, no bottom, no trastos, no REGIDORA
PIÑÓN (N−2)R-HY · S-TOP · H-BENTO · F-CMPNo taller, no ganchos, no bento, no configurador, no MECANICO
BOBINA (N−3)R-IN · S-DOCK · H-FEED · F-STORYComparte R-IN; no cineclub, no feed, no dock, no butaca
LOMO (N−4)R-CL · S-CMD · H-DATA · F-LEADNo archivo, no ejemplares, no comando; H-TABLE de caja ≠ mesa de datos de biblioteca
CESTAR-CL · S-RAIL · H-TABLE · F-LEADComparte H-TABLE; aquí F-EDIT de caja, no despensa ONG
MATIZR-HY · S-BOTTOM · H-BENTO · F-EDITComparte 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)

ObjetivoMétodo en este casoSalida
Entender actores de la parada de mercadilloModelado 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-EDITJourney + service blueprint§7–8
Traducir a requisitos L2 hoy + apuntar + anular + cierreMatriz 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

ProhibidoPermitido
«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 realQuotes de persona etiquetadas como constructo de diseño
Volumen medido «22 ramos/semana» como KPI de mercadoLíneas de seed de producto, etiquetadas como demo
Parada municipal oficial en Maravillas 2026Parada 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

StakeholderInfluenciaInterésNecesidad principal
TITULAR (Remedios)AltaMuy altaVer cobrado / pendiente / anulado sin Hacienda ni Excel
AYUDANTE (quien apunta)Alta en el gestoMuy altaApuntar una línea y ver el código, sin cuenta
LECTORA MAYOR (a11y)Media formal, baja en producto día 1AltaLeer la cinta con contraste y targets; sin login forzado
Parada / cajaAlta formalAltaQue se vea el día; que no se confunda con Excel ni factura
Excel / hojasCompetencia / analogía falsaFuera de alcance; no clonar pivot
Factura / AEATAnalogía falsa de cierreFuera; Cerrar el día ≠ Hacienda
Cuenta móvil / calculadoraAnalogía falsa de apuntarFuera; Apuntar ≠ cuenta en el móvil
MANTA / merenderoAnti-patrón N−1Fuera; no trastos, no REGIDORA, no manta-api
PIÑÓN / tallerAnti-patrón N−2Fuera; no bicis, no ganchos, no MECANICO
Notas del móvil / WhatsAppCanal paraleloNo es el backoffice; H1 apunta a reducirlo
Contable externoFueraFuera 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

CampoDetalle
Edad / contexto52 años; titular de la parada TALÓN en Tetuán · Maravillas; cierre del día, no de Hacienda. Edad = constructo.
DigitalFluida en el iPad / portátil de la caja; la cinta pública también la mira
GoalsVer qué está cobrado, pendiente y anulado; cerrar el día sin Excel
PainsNotas 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 demoremedios@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

CampoDetalle
Edad / contexto28 años; ayuda en la parada; apunta ventas y pendientes; no quiere «otra cuenta de Excel». Edad = constructo.
DigitaliPad de la caja o móvil; no se registra si puede evitarlo
GoalsVer la cinta; apuntar concepto + importe + forma; anular un pendiente; llevarse un código
PainsEl 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 demoLucia 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)

CampoDetalle
Edad / contexto68 años; puede mirar la cinta en la caja; contraste y tamaño importan. Edad = constructo de la serie a11y.
DigitalNo tiene login en el slice L2; usa la superficie pública si el contraste y los targets aguantan
GoalsEntender cobrado / pendiente / anulado, sin mistificarse con Excel ni con Hacienda
PainsTexto 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

JobPor qué no
Hacer la cuenta en el móvilApuntar ≠ cuenta en el móvil · S3
Emitir facturaTalón ≠ factura
Declarar a Hacienda / TicketBAICerrar el día ≠ Hacienda
Sustituir a ExcelTALÓN no es Excel
Cobrar online / TPVS3
Gestionar stock / SKUS3 · H3
Dejar un trasto en la manta≠ MANTA
Dejar una bici / configurar arreglo≠ PIÑÓN
Pedir butaca de cineclub≠ BOBINA

6. Stories Must (v1)

IDComoQuieroPara
US-01AyudanteVer cinta H-TABLE de 4 líneas + 3 métricasDistinguir talón de Excel / feed / plano / bento
US-02AyudanteApuntar una línea (concepto, importe, forma) y ver success TAL-XXXXDejar constancia, no facturar
US-03AyudanteAnular una línea PENDIENTE (F-EDIT)Evitar tachar a bolígrafo
US-04AyudanteRecibir 409 si la línea no está PENDIENTENo anular lo ya cobrado / ya anulado
US-05TitularEntrar con JWTAbrir el cierre del día
US-06TitularVer cobrado / pendiente / anuladoOficio sin kanban ni Hacienda
US-07AmbosVer empty / error / loadingNo quedarse en blanco
US-08AyudanteUsar S-SIDE en 390Hoy · 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)

  1. Lucia abre /. Ve cinta a muro + 3 datos (cobrado / pendiente / anulado) + 4 líneas. TAL-2901 COBRADO; TAL-2903 PENDIENTE. [H1]
  2. Toca Apuntar → /apuntar. Concepto, importe, forma. POST /api/lineas/ok/TAL-2905. Lee las cuatro oposiciones. [H3]
  3. Alternativa: toca anular sobre TAL-2903 → sheet anular (UI-10). POST /api/lineas/anular → ANULADO. [H2]
  4. Intento de anular TAL-2901 COBRADO → 409 «Esa línea no se puede anular.»
  5. Remedios entra a /login/cierre. Líneas por estado + métricas.
  6. 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)

CapaQué 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.
SoporteNest · Neon cool-cloud-04708830 · JWT TITULAR · Paper phosphor

9. Matriz hallazgo → requisito → feature

Hallazgo (etiquetado)RequisitoFeature v1
[HIPÓTESIS H1] Cinta reduce notas del móvil4 líneas + 3 métricas en fold tabla/ H-TABLE FOLD-TABLE
[HIPÓTESIS H2] Anular evita tachar a bolígrafoPOST anular de un código PENDIENTE; 409 si noUI-10 · POST /api/lineas/anular
[HIPÓTESIS H3] Cuatro líneas bastanSin ExcelSeed 4 · no hoja
[SUPUESTO S2] Sin cuenta de ayudantePOST públicoPOST /api/lineas + anular
[SUPUESTO S1] 4–12 / mañanaDemo 4Seed TAL-2901…2904
[DECISIÓN S3] Sin pagos online / AEAT / stockNo pasarela, no TicketBAI, no SKUFuera 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

PrincipioAplicación
Cinta firstLa 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 / cierreLucia apunta o anula sin cuenta; Remedios entra con JWT
Apuntar | anular → successProfundidad 1–2 desde la cinta hasta el código (F-EDIT)
El núcleo es una líneaF-EDIT: una línea a la vez, sin bulk Excel
Cierre TITULAR = díaCobrado / pendiente / anulado; no kanban, no split lista | ficha foto
Lenguaje de dominioLínea, talón, hoy, cierre, apuntar, anular — no «SKU», «factura», «trasto», «gancho»
Apuntar no es cuenta móvilEl success no tiene calculadora ni extracto bancario
Talón no es ExcelNo hay pivot, no hay hojas, no hay export Must
Chrome de cajaS-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

AudienciaNodos relevantes
AYUDANTEHoy → Apuntar o Anular (sheet) → Ok. No ve /cierre
TITULARLogin → Cierre · (puede leer Hoy y apuntar)
LECTORA MAYORHoy / 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)

SlotDestinoVisibilidadNotas
Hoy/TodosVuelve a la cinta. No es hero de marca
Apuntar/apuntarTodosEntra al form de apuntar
Cierre/cierreTITULAR; si guest → /login?next=/cierreOficio 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)

ElementoDestinoNotas
Tabla a muroCinta densa; sin foto hero (D-P1-09)
Wordmark TALÓN/Sello mark sobre ground
Eslogan«El talón, no Excel.»
3 datosCobrado / Pendiente / Anulado (números del seed)
Fila de líneasheet anular si PENDIENTE4 líneas; código, concepto, importe, forma, estado
Tap PENDIENTEUI-10 sheetArranque de anular F-EDIT
Tap COBRADO / ANULADOsello + copy; no POST anular409 si se fuerza
CTA Apuntar/apuntarS-SIDE o lead
Slot Cierre (mute)/login o /cierre si hay tokenOficio, 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)

SlotDestinoNotas
← Hoy/Un paso atrás, no stepper fiscal
Form/apuntarConcepto, importe, forma
EnviarPOST → /ok/:codeUna acción

[DECISIÓN] Apuntar no es un modal efímero sin URL. No hay wizard de AEAT.

Chrome de anular (sheet sobre /)

SlotDestinoNotas
Cerrar/Conserva la cinta
Confirmaciónmismo pathCódigo + concepto en solo lectura
EnviarPOST /api/lineas/anular → feedback / /ok/:codeUna línea
No PENDIENTE409 / disabled«Esa línea no se puede anular.»

Chrome de cierre (/cierre autenticado)

SlotDestinoVisibilidadNotas
Cierre/cierreAuthTitular de oficio
MétricasAuthCobrado / pendiente / anulado + suma
LíneasAuthAgrupadas o listadas por estado
Hoy/AuthSecundario vía S-SIDE
Salirlimpia token → /AuthCabecera 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)

ConceptoLabel
HomeHoy (no «Inicio», no «Plaza», no «Taller», no «Excel»)
Flujo apuntarApuntar (no «facturar», no «cobrar online», no «exportar»)
Flujo editarAnular (no «borrar», no «eliminar fila Excel»)
SuccessApuntado / Anulado / código
StaffCierre (no «Backoffice», no «Kanban», no «Hacienda»)
AuthTitular (no «Área cliente», no «Regidora», no «Mecánica»)
CTA apuntarApuntar (no «Facturar», no «Guardar en Excel»)
CTA anularAnular (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

RutaQué hayQué no hay
/Cinta, eslogan, 3 métricas, 4 líneas, S-SIDE, sheet anularPrecios de catálogo, login de ayudante, Excel, AEAT, trastos
/apuntarConcepto, importe, forma, disclaimerNIF, email, pasarela, stock, socio
/ok/:codeCódigo + 4 oposicionesFactura, ticket fiscal, «ya está en Hacienda», QR de TPV
/loginEmail / clave TITULARSignup de ayudante
/cierreMétricas + líneas del díaColumnas 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.

EstadoSuperficie
LoadingSkeletons 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 incompletoCTA 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

PiezaForma
LíneaTAL-2901TAL-2904 (TAL versales, guion, 4 dígitos)
Apuntar nuevoTAL-2905+ secuencial al POST /api/lineas
Anularmismo code de la línea PENDIENTE
Success/ok/TAL-2903 o /ok/TAL-2905

9. Mapa Paper → rutas

ArtboardRutaComponente
UI-01 Hoy/HoyPage
UI-11 Mobile hoy/ @390HoyPage
UI-02 Apuntar/apuntarApuntarPage
UI-12 Mobile apuntar/apuntar @390ApuntarPage
UI-10 Anular/ sheetAnularSheet en HoyPage
UI-03 Success/ok/:codeOkPage
UI-04 Login/loginLoginPage
UI-05 Cierre/cierreCierrePage
UI-06 Emptymismas rutasestados
UI-07 Errormismas rutasestados
UI-08 Loadingmismas rutasestados
UI-09 TokensthemeTailwind

[COMPROBADO] Mapeo alineado a docs/00-paper-reference.md.

04-user-flows.md

04 — Flujos de usuario — TALÓN

1. Convenciones

TokenSignificado
F-EDITApuntar o anular una línea; la home es la cinta, no un wizard fiscal
Cierre / mesaOficio TITULAR, JWT · GET /api/mesa
201Línea apuntada (nuevo) o anulada (PENDIENTE → ANULADO)
400Concepto / importe / forma inválidos
401Cierre sin token
404Código inexistente
409Anular 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-2905 muestra 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 ANULADO y 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, /cierre redirige a /login?next=/cierre.
  • GET /api/mesa sin 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 aparece (oficio de rastro). [DECISIÓN]

6. F5 — Estados de sistema

EstadoTriggerUI
Loading HoyGET lineas en vueloSkeletons de cinta + 3 datos + 4 filas (UI-08)
Empty Hoy200 { lineas: [] }«Aún no hay líneas.» (UI-06)
Error Hoy5xx / redReintentar (UI-07)
Loading apuntarForm listo; submit pending (UI-08)
Loading anularPOST en vuelopending en CTA
409no PENDIENTE«Esa línea no se puede anular.» (UI-07)
Loading cierreGET mesa en vueloSkeletons de métricas + líneas
Empty cierre200 sin líneas«No hay líneas en el cierre.»
Login 401credenciales«Email o contraseña no valen.»
404 successcódigo inexistente«Esa línea no está.»

7. Flujos que no existen

FlujoPor qué
Signup ayudanteS2 · Apuntar ≠ socio
Facturar / AEAT / TicketBAIS3 · Talón ≠ factura · Cerrar ≠ Hacienda
Export Excel / pivotTALÓN no es Excel
Cobrar online / TPV / pasarelaForma = etiqueta · S3
Stock / SKU / inventarioS3 · H3
Chat≠ PREGÓN
Dejar trasto / llevarse≠ MANTA
Configurar arreglo / dejar bici≠ PIÑÓN
Pedir butaca≠ BOBINA
Login lectora mayorSlice L2 · docs / a11y
PATCH libre de estado a HaciendaRemedios lee el día; no declara
Búsqueda ?q=Sin S-CMD
Bulk anular / multi-líneaRompe F-EDIT de una línea

8. Tiempos de demo (modelo)

ActorRecorridoTecho
Lucia (apuntar)Apuntar → form → código< 90 s
Lucia (anular)Hoy → sheet → anulado< 60 s
Lucia (409)COBRADO → bloqueo → PENDIENTE< 60 s
RemediosLogin → 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

  1. / — cinta a muro + 3 datos (2 cobrado / 1 pendiente / 1 anulado) + 4 líneas. Eslogan. S-SIDE.
  2. 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.
  3. Apuntar — /apuntar · Ramo pequeño · 10,00 · efectivo · /ok/TAL-2905. Copy ×4.
  4. Anular — tap corona PENDIENTE · confirma · ANULADO.
  5. Reintento corona → 409.
  6. /loginremedios@talon.parada / password123.
  7. /cierre — métricas + líneas; suma cobrada demo 20,00 € (+ nuevos cobrados si se apuntó).
  8. 390: cinta + S-SIDE; no carousel; targets ≥44px.
  9. API down: error + Reintentar.

10. Contratos de error de API (flujo)

CasoHTTPUI
POST apuntar, concepto vacío400«Escribe el concepto.»
POST apuntar, importe inválido400«Indica el importe.»
POST apuntar, forma vacía400«Elige la forma.»
POST anular, code ausente400«Elige una línea.»
POST anular, no PENDIENTE409«Esa línea no se puede anular.»
POST, redmark + Reintentar; no navega a ok
GET mesa sin JWT401redirect login
Login malo401copy de login
GET /ok code 404404«Esa línea no está.»

11. S-SIDE en flujo

DesdeSlotComportamiento
/Hoyaria-current
/Apuntar/apuntar
/apuntarApuntararia-current
/ok/:codeHoyVuelve a la cinta
/ guestCierre/login?next=/cierre
/ con tokenCierre/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:

EntidadTabla SQLPropósito
UserusersIdentidad de oficio (rol TITULAR)
SessionsessionsSesión JWT / token persistido
LinealineasEntrada 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

ValorDescripción
TITULARTitular del cierre; único rol autenticado v1

LineaStatus

ValorDescripción
COBRADOCobrado en el día
PENDIENTEPendiente de cobro; se puede anular
ANULADOAnulado; 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 ≠ PENDIENTE409. [DECISIÓN]
Remedios no hace PATCH libre a AEAT en v1: el cierre es lectura del día. [DECISIÓN]

FormaPago (etiqueta)

ValorDescripción
efectivoEfectivo en caja
bizumEtiqueta 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

ColumnaTipoNotas
idBIGSERIAL PK
emailTEXT UNIQUEremedios@talon.parada
password_hashTEXTbcrypt 12
nameTEXTRemedios Gil
roleTEXTTITULAR
created_atTIMESTAMPTZ

sessions

ColumnaTipoNotas
idUUID PKsid del JWT
user_idBIGINT FK
expires_atTIMESTAMPTZ
revoked_atTIMESTAMPTZlogout
created_atTIMESTAMPTZ

lineas

ColumnaTipoNotas
idBIGSERIAL PK
codeTEXT UNIQUETAL-2901
conceptoTEXTRamo mixto · Planta crasa · Corona blanca · Maceta devuelta · o el del form
importeNUMERIC(12,2)12.00 / 8.00 / 35.00 / -6.00
formaTEXTefectivo | bizum
statusTEXTCOBRADO | PENDIENTE | ANULADO
sort_orderINTEGER1 = primera fila de la cinta
created_at / updated_atTIMESTAMPTZ

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

codeconceptoimporteformastatus
TAL-2901Ramo mixto12,00efectivoCOBRADO
TAL-2902Planta crasa8,00bizumCOBRADO
TAL-2903Corona blanca35,00efectivoPENDIENTE
TAL-2904Maceta devuelta-6,00efectivoANULADO

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 ≠ PENDIENTE409; 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

ReglaDetalle
Unicidad de códigolineas.code UNIQUE
Anular solo PENDIENTESi status ≠ PENDIENTE → 409
Apuntar no escribe ANULADOPOST lineas no crea ANULADO directo
Sin user en líneaNo FK a users desde lineas
Cierre privadoGET /api/mesa exige JWT role TITULAR
Cinta públicaGET /api/lineas sin auth
Una líneaBody de anular = un code; no array

8. Fuera del modelo v1

ConceptoPor qué fuera
NIF / factura / IVATalón ≠ factura · Cerrar ≠ Hacienda
Email del clienteMinimización; S2
Pasarela / TPVForma = etiqueta · S3
Stock / SKUS3 · H3
Tabla trastos / tratosLeftover MANTA
Tabla bicis / requestsLeftover PIÑÓN
PATCH a AEATCierre de lectura
Bulk / Excel rowsH3 · F-EDIT
Multi-tenant paradaL2 compacto

9. Naming vs leftover

Prohibido (leftover)Contrato TALÓN
trastos / tratos / mantaslineas / talón / hoy
REGIDORATITULAR
manta-api / pinon-apitalon-api
MNT-XXXX / PIN-XXXXTAL-XXXX
LIBRE / PEDIDO / ENTREGADOCOBRADO / PENDIENTE / ANULADO
puerto 3028 / 30273029
/dejar / /encargo/apuntar + sheet anular

06-tech-stack.md

06 — Stack técnico — TALÓN

1. Resumen

CapaElecciónNotas
FrontendAngular (standalone) + TailwindPuerto 4200
BackendNestJSPuerto 3029 · prefijo /api
DBNeon PostgreSQLProject cool-cloud-04708830 · DATABASE_URL
AuthJWT BearerRol TITULAR
PackagepnpmApps independientes (pnpm --filter)
DiseñoPaperFile 01M165CVX37R8QSKBG37N0QRS4
Repo/Users/cristian/orca/talon-appGH 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ónRazónAlternativa descartada
Angular standaloneCoherencia serie ALS-2 dailyNext/React (rompería espejo de cases)
NestJSMismo contrato API que MANTA/PIÑÓNExpress suelto sin módulos
NeonPostgres managed; project dedicado TALÓNSQLite local (no portfolio cloud)
TailwindTokens phosphor rápidosCSS modules sin design tokens
JWTCierre cerrado; cinta abiertaSession cookie-only sin Bearer documentado
pnpm filterMonorepo ligero sin npm workspacesTurborepo pesado para L2

3. Puertos y health

ServicioPuertoHealth
API3029GET /api/health{ ok: true, service: "talon-api" }
Web4200Angular 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 (/apihttp://localhost:3029). [DECISIÓN]

5. Variables de entorno (API)

VariableUso
DATABASE_URLNeon connection string (project cool-cloud-04708830)
JWT_SECRETFirma HS256
PORT3029
NODE_ENVdevelopment / production

No commitear secretos. .env local; ejemplo en .env.example sin credenciales reales. [DECISIÓN]

6. Auth

PiezaDetalle
LoginPOST /api/auth/login { email, password }
Hashbcrypt 12
TokenJWT · claims sub, email, role: TITULAR
GuardBearer en GET /api/mesa
Públicohealth, lineas, lineas/:code, POST lineas, POST lineas/anular, login
Storage weblocalStorage o memory + interceptor; logout limpia

[COMPROBADO] Credenciales demo: remedios@talon.parada / password123.

7. Endpoints (contrato)

MétodoRutaAuthRespuesta clave
GET/api/healthNotalon-api
GET/api/lineasNometrics + array 4
GET/api/lineas/:codeNoitem · soporte success [DECISIÓN]
POST/api/lineasNo201 / 400 · apuntar
POST/api/lineas/anularNo201 / 400 / 409 · anular
POST/api/auth/loginNo{ accessToken }
GET/api/mesaJWTmétricas + líneas agrupadas

CORS: origen http://localhost:4200 en dev. [DECISIÓN]

8. Frontend — rutas y componentes

RutaComponenteGuard
/HoyPage (+ AnularSheet)
/apuntarApuntarPage
/ok/:codeOkPage
/loginLoginPage
/cierreCierrePageauthGuard TITULAR

Chrome: SideNavComponent (S-SIDE). Tokens Tailwind: ground, ink, card, mark, mute, sello.

9. Assets

Origen caseDestino 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

HerramientaUso v1
TypeScriptStrict en api y web
ESLint / PrettierSerie daily
Vitest / JestSmoke API del slice
PlaywrightSmoke S01–S12 del plan QA (doc 13) cuando exista runtime

11. Anti-stack (no introducir)

TecnologíaPor qué no
Prisma obligatorioBrief no lo exige; ensureSchema + pg válido
Stripe / pagoForma = etiqueta
TicketBAI / AEAT SDKCerrar ≠ Hacienda
Firebase AuthJWT propio TITULAR
GraphQLREST L2
Socket.io / chat≠ PREGÓN
Mapbox / GPSFuera
Excel export MustTALÓN no es Excel
Leftover Nest modules trastos / bicis≠ MANTA / PIÑÓN

12. Criterios de aceptación técnicos

  1. GET /api/healthservice: "talon-api".
  2. Seed idempotente: 1 TITULAR + 4 líneas.
  3. POST apuntar crea línea y devuelve TAL-XXXX.
  4. POST anular sobre PENDIENTE → 201 ANULADO; sobre no-PENDIENTE → 409.
  5. GET mesa sin token → 401.
  6. Web en 4200 consume API 3029 sin mixed-content local.
  7. 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

EjeNo
SuperficieTubo #101510, ink #D8F0C8, card #161C16, mark #8FD36AHueso MANTA, grafito PIÑÓN, velvet BOBINA, caliza LOMO, papel rosa
TipoIBM Plex Mono + KarlaLibre Baskerville+Nunito (MANTA), Spectral+Sora (PIÑÓN), Cormorant+Manrope (BOBINA)
FotoOpcional cover UX; home sin foto-led (D-P1-09)Hero+panel AP-25, plaza MANTA, gancho de taller
GridFOLD-TABLE: cinta densa + 3 datos + 4 filasHero 2-col + panel · bento · feed · plano Deriva
AcentoMark en CTA/foco/slot activo; sello en ANULADO/errorGeranio MANTA, naranja PIÑÓN, brass de sala
ChromeS-SIDE Hoy · Apuntar · CierreBottom merendero, top taller, dock cineclub

3. Paleta

TokenHexRol
Ground / G-PHOSPHOR#101510Tubo apagado. Fondo de página.
Ink#D8F0C8Fósforo de lectura. Texto primario.
Card#161C16Tecla / fila / form. Superficie elevada.
Mark#8FD36AFósforo: CTA Apuntar/Anular, foco, wordmark.
Mute#7E9174Meta, labels, estado secundario, idle S-SIDE
Sello#E24B4BPoco: 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

UsoFamiliaTamaños de referencia
WordmarkKarla 60024–28 desktop · 22 mobile
Titular de Hoy / cierreKarla 60032–44
Código TAL-XXXXIBM Plex Mono 60028–36
ImportesIBM Plex Mono 500/60018–28
Cuerpo / disclaimersKarla 40016–17 / 26–28 lh
UI, S-SIDE, form, listaKarla 400/500/60014 / 16
Meta (forma, status)Karla 50012–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 entran: el brief los fija. [COMPROBADO]

5. Fotografía

AssetDebeNo debe
Cover UX (si existe)Parada / caja / fluorescente, Tetuán moodPlaza MANTA, gancho PIÑÓN, papel rosa stock
Home productoSin tile foto-led dominanteHero+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

MoodPor qué no
Bookish talonario crema / papel rosaPrimer instinto; es nostalgia de papel carbón
Botanical / huesoFue MANTA
Industrial / grafitoFue PIÑÓN
Candlelit / velvetFue BOBINA
Mineral / calizaFue LOMO
Signage / cinta amarillaFue ONDA
Ice institucionalFue 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

GestoTratamiento
Entrada cintaFade corto 120–160ms
Hover fila desktopRing mark 2px; sin lift excesivo
S-SIDE activoMark en label; idle mute
Sheet anularSlide-up 160ms; reduced = instant
Reduced motion0ms

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

TokenValorUso
--ground#101510Fondo de página (tubo apagado)
--ink#D8F0C8Texto primario, títulos
--card#161C16Fila, form, cierre
--mark#8FD36ACTA, foco, S-SIDE activo
--mute#7E9174Meta, idle
--sello#E24B4BLED anulado, error, poco
--font-monoIBM Plex MonoCódigos, importes
--font-sansKarlaUI
--target44×44 minToques

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)

ParUsoNota
Ink #D8F0C8 sobre Ground #101510Cuerpo y títulosDebe pasar WCAG 2.2 AA
Ink sobre Card #161C16Texto en filaVerificar AA
Mark sobre GroundCTA fill + texto ground invertido en botónNo sustituye ink en párrafo
Mute sobre GroundMeta corta; no cuerpoEvitar párrafos mute
Sello sobre GroundLED / error cortoNo 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

RolSize / leading
Display Hoyclamp(2.2rem, 5vw, 3.6rem) / 0.95 · Karla
H1 cierre / success2.5rem / 1 · Karla
Código TAL-XXXX28–36 · IBM Plex Mono
Importe18–28 · IBM Plex Mono
Cuerpo16–17 / 26 · Karla
Meta12–13 / 16, tracking 0.08em
S-SIDE12–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

SuperficieGrid
Hoy 1440Rail S-SIDE + cinta full; 3 datos en fila; 4 filas; sin foto hero
Hoy 390Chrome compacto + 3 datos wrap + stack de 4
Apuntar / Ok / loginColumna max-w-lg
Cierre TITULARMétricas + grupos; stacked < lg
Sheet anularBottom sheet max-w-lg; full-bleed 390

Max page 1440px. Padding 20 / 40 / 48.

6. Estados de control

EstadoTratamiento
DefaultCard + ink
HoverRing mark 2px
Focus visibleOutline mark 2px offset 2
Active / pressedMark fill breve
DisabledOpacity 0.45 · no hit · aria-disabled
Pendingdisabled + aria-busy
ErrorBorde sello + mensaje
PENDIENTE seleccionadaRing mark
No anulableSello; 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

SuperficieTratamiento
Card sobre tuboBorde 1px mute/25; sombra mínima ink/10
S-SIDERail card; filete mute 1px; no material neón retail
SheetOverlay ground/70 + card; no modal centrado de SaaS
Modal extraNo en v1 Must

9. Mapa a Paper UI

UIComponentes clave
UI-01 / 11Cinta + 3 datos + 4 filas + S-SIDE
UI-02 / 12Form apuntar
UI-10Sheet anular
UI-03Success
UI-04Login
UI-05Cierre
UI-06Empty
UI-07Error / 409
UI-08Loading
UI-09Tokens

[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.

EjeNo
TonoSeco, breve, de oficioCorporativo contable, hype fintech
Persona«Apuntamos la línea» / tuteo de caja«Emite tu factura» / «declara el modelo»
RitmoFrases cortas. Una idea por línea en disclaimersPárrafos legales de AEAT
HumorSeco, pocoMemes, 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ónCopy canónico
Apuntar vs cuenta móvilApuntar ≠ hacer la cuenta en el móvil.
Talón vs facturaTalón ≠ factura.
Cierre vs HaciendaCerrar el día ≠ Hacienda.
Producto vs ExcelTALÓN no es Excel.

No se parafrasean hasta diluirlas. Pueden acortarse en UI estrecha manteniendo ≠. [DECISIÓN]

3. Glosario UI

ConceptoLabel canónicoEvitar
HomeHoyInicio, Plaza, Taller, Excel, Dashboard
ItemLínea / TalónSKU, factura, trasto, gancho
Flujo apuntarApuntarFacturar, cobrar online, exportar
Flujo editarAnularBorrar, eliminar fila, soft-delete
CTA apuntarApuntarGuardar en Excel, Emitir
CTA anularAnularBorrar, Eliminar
SuccessApuntado / AnuladoFactura emitida, Asiento contable
StaffCierreBackoffice, Admin, Hacienda, Kanban
EstadoCobrado / Pendiente / AnuladoFacturado / Enviado AEAT / Agotado
Persona authTitularRegidora, Mecánica, Admin
Error 409No se puede anularAgotado, Forbidden fiscal

4. Pantalla a pantalla

Hoy /

SlotCopy
WordmarkTALÓN
EsloganEl talón, no Excel.
Dato 1{n} cobrado
Dato 2{n} pendiente
Dato 3{n} anulado
CTA sideApuntar
EmptyAún no hay líneas.
ErrorLa red no responde. · Reintentar

Apuntar /apuntar (UI-02)

SlotCopy
TítuloApuntar
Label conceptoConcepto
Label importeImporte (€)
Label formaForma
Opciones formaEfectivo · Bizum
TogglePendiente de cobro
SubmitApuntar
DisclaimerNo es una factura. No es Hacienda. TALÓN no es Excel.
Error conceptoEscribe el concepto.
Error importeIndica el importe.
Error formaElige la forma.

Anular sheet (UI-10)

SlotCopy
TítuloAnular
Meta{concepto} · {importe} · {code}
SubmitAnular
Disabled / 409Esa línea no se puede anular.
DisclaimerSolo pendientes. No borra el rastro. Apuntar ≠ cuenta en el móvil.

Success /ok/:code

SlotCopy
Titular (apuntar)Apuntado.
Titular (anular)Anulado.
Código{code}
Cuerpo apuntar{concepto} · {importe} · {forma}.
Cuerpo anular{concepto}. Ya no cuenta como pendiente.
OposicionesLas cuatro líneas irrenunciables
VolverVolver a Hoy

Login /login

SlotCopy
TítuloCierre
AyudaSolo titular.
Demoremedios@talon.parada
ErrorEmail o contraseña no valen.

Cierre /cierre

SlotCopy
TítuloCierre
GruposCobrado · Pendiente · Anulado
SumaSuma cobrada {n} €
EmptyNo hay líneas en el cierre.
SalirSalir
PieCerrar el día ≠ Hacienda.

5. Alt text de imágenes

AssetAlt (modelo)
Cover UXCaja 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

CasoCopy
RedLa red no responde.
404Esa línea no está.
409Esa línea no se puede anular.
400 conceptoEscribe el concepto.
401 cierreEntra como titular.

Sin culpa al usuario. Sin jerga HTTP en UI.

8. Anti-copy (vetado)

VetadoPor qué
Excel / pivot / exportar hojaTALÓN no es Excel
Factura / NIF / IVA / TicketBAITalón ≠ factura
Hacienda / AEAT / modeloCerrar ≠ Hacienda
Cuenta en el móvil / calculadora bancariaApuntar ≠ cuenta móvil
Trasto / manta / regidora / plazaMANTA
Gancho / bici / encargo / mecánicaPIÑÓN
Recibido / En curso / CerradoPREGÓN kanban
«El 70% de paradas…»Estadística inventada
Anular en loteRompe F-EDIT de una línea

9. Criterios de aceptación de contenido

  1. Las cuatro oposiciones aparecen al menos en success y en una superficie de Hoy o apuntar/anular.
  2. Ningún CTA dice Facturar / Exportar a Excel / Declarar / Borrar.
  3. COBRADO se etiqueta «Cobrado», no «Facturado».
  4. Códigos se muestran como TAL-XXXX en versales.
  5. 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

ParRatio objetivoUso
#D8F0C8 sobre #101510≥ 4.5:1 (texto) / ≥ 3:1 (UI grande)Cuerpo, títulos
#D8F0C8 sobre #161C16≥ 4.5:1Texto en card
#8FD36A sobre #101510≥ 3:1 para UI; texto de párrafo noFoco, iconos
#101510 sobre #8FD36A≥ 4.5:1 en CTALabel del botón
#7E9174 sobre #101510Verificar; limitar a meta cortaLabels
#E24B4B sobre #101510LED / error cortoSello; 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

ReglaAplicación
Cuerpo ≥ 16pxKarla 16–17
Códigos / importes legiblesIBM Plex Mono ≥ 14 en UI; ≥ 18 en success
Line-height ≥ 1.5 en cuerpo26–28 lh
Zoom 200%Layout no rompe S-SIDE ni form
Sin justificado forzadoAlineación start

4. Targets y pointer

ElementoMínimo
Slots S-SIDE44×44 CSS px
CTA Apuntar / Anular≥ 44 px alto
Fila de líneaHit area completa ≥ 44 alto
Inputs≥ 44 alto
Cerrar sheet≥ 44

Spacing entre slots ≥ 8px. [DECISIÓN]

5. Teclado y foco

SuperficieComportamiento
HoyTab por S-SIDE → filas PENDIENTE → Apuntar
Sheet anularConfirmar → submit; Esc cierra
Form apuntarConcepto → importe → forma → submit
LoginEmail → password → entrar
CierreGrupos legibles; salir alcanzable
Focus visibleOutline 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

UIRol / nombre
S-SIDEnavigation · aria-label «TALÓN»
Slot activoaria-current="page"
3 datoslist o group «Métricas del día» · cada dato con texto «{n} cobrado» no solo el número
Filas líneaarticle o fila de table «{concepto} {importe}» + status en texto
Sheetdialog · aria-modal · labelledby título
Formlabel asociado; errores con aria-live="polite"
Loadingaria-busy="true" en región
Success códigoTexto real, no solo imagen
409aria-live="assertive"

7. Imágenes

CasoTratamiento
Cover UXalt descriptivo corto
Home productoSin tile foto-led obligatorio
Iconos S-SIDEaria-hidden si hay label texto visible

8. Motion

PreferenciaComportamiento
prefers-reduced-motion: reduceTransiciones 0ms; sheet instant
Default120–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.
  • /cierre redirige 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: autocomplete on; importe inputmode="decimal"; password current-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

  1. Ink sobre ground usado en cuerpo; mute limitado a meta.
  2. Targets S-SIDE y CTA ≥ 44×44.
  3. Focus visible mark en todos los interactivos.
  4. Status y métricas con texto, no solo color o número huérfano.
  5. Reduced motion respetado.
  6. Form con labels y errores anunciables.
  7. Ningún toast único sin pantalla como único success (hay /ok/:code).
  8. Sheet anular es dialog alcanzable 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

PrincipioAplicación v1
MinimizaciónApuntar = concepto + importe + forma (+ status); anular = code; sin NIF, email de cliente, GPS
Separación público / oficioCinta y POST públicos; cierre JWT
Sin cuenta de ayudanteLucia y lectora mayor no se registran
Transparencia de copySuccess dice que no es factura ni Hacienda
Secretos fuera del repoDATABASE_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

DatoDóndeBase operativa (modelo)Retención v1
Concepto / importe / formalineasOficio de cajaMientras el seed/demo viva; sin política de mercado afirmada
Statuslineas.statusCobrado / pendiente / anuladoIgual
Email TITULARusers.emailCuenta de oficioCuenta demo
Password hashusers.password_hashAuthbcrypt 12
JWT sidsessionsSesión de cierreExpiració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

SuperficiePúblicoPrivado
GET /api/lineasSí · métricas + líneas
GET /api/lineas/:code
POST lineas / anularSí · crea / actualiza fila
GET /api/mesaNo · 401Sí · métricas + agrupación + titular
Hoy UICinta del día
Cierre UILectura de oficio

[DECISIÓN] El cierre JWT no expone datos fiscales de terceros; expone el día de la parada demo.

4. AuthN / AuthZ

ControlDetalle
Passwordbcrypt cost 12
JWTHS256 · secret env · role claim
Guard cierrerole === TITULAR
Login rateNo es deuda del L2; demo sin brute-force engine
LogoutRevoke session + clear client token
HTTPSObligatorio 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

AmenazaMitigación
POST spam apuntar/anularValidación concepto + importe; L3 rate-limit (no es hueco del slice)
Carrera de dos anulacionesSELECT FOR UPDATE + 409 al segundo no-PENDIENTE
JWT robadoExpiración corta + logout; HTTPS en prod
IDOR cierreGuard JWT
XSSAngular escaping; no innerHTML de concepto
SQLiParámetros prepared / query builder
Leftover REGIDORA / MECANICO / ADMINUn 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 PIIPasswords, JWT completos
code de línea en logsSecretos env

9. Criterios de aceptación

  1. GET mesa sin Bearer → 401.
  2. POST lineas/anular no exige auth ni pago ni NIF.
  3. Password solo como hash bcrypt.
  4. .env no versionado con secretos reales.
  5. Copy de success no implica factura ni declaración a Hacienda.
  6. Segundo POST anular sobre el mismo code ya ANULADO → 409.
  7. 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

TipoMétricaDefinición
North Star% de consultas «¿cuánto llevamos?» resueltas en la cinta sin abrir el móvil de notasOficio 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 descartadaPor qué no
Pageviews de /Vanidad; no mide talón
Ingresos / GMV onlineNo hay pasarela; forma es etiqueta
% de facturas emitidasTalón ≠ factura
% de modelos AEATCerrar ≠ Hacienda
% de filas Excel exportadasTALÓN no es Excel
% de trastos sin WhatsAppEso es MANTA
% de bicis LISTA sin WhatsAppEso 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étricaDefiniciónHipótesis
Activación1.er POST /api/lineas exitosoH1
Tasa Hoy → apuntar//apuntarH1
Tasa anulaciónPOST anular 201 / intentosH2
Tasa 409POST anular 409 / intentosIntegridad
Mix de estadosConteos cobrado / pendiente / anuladoH1
Suma cobradaΣ importe donde status = COBRADOOficio
Integridad auth401 en mesa sin tokenSeguridad
Salud5xx rate APIOps

4. Eventos (contrato si se instrumenta en un L3)

EventoPropsPII
hoy_viewmetrics snapshot (conteos)No
apuntar_submitforma, statusNo concepto libre si sensible
apuntar_successcodeNo
anular_submitcodeNo
anular_successcodeNo
anular_conflicthttp:409No
login_successroleNo
cierre_viewNo

[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

VetadoPor qué
Heatmaps de terceros sin decisiónPrivacidad
Funnel de pago onlineNo hay pasarela
DAU de ExcelNo hay hoja
Estadísticas de Tetuán inventadasÉtica de verdad
Tracking GPSFuera

8. Criterios de aceptación

  1. Docs y UI no muestran un % inventado como hecho.
  2. North star documentada y alineada a H1.
  3. Si hay eventos en un L3, sin secretos ni PII innecesaria.
  4. 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

EntornoURLNotas
API localhttp://localhost:3029Neon cool-cloud-04708830
Web localhttp://localhost:4200Proxy /api
Credencialesremedios@talon.parada / password123Solo demo

3. Smoke crítico (Must pasar cuando haya runtime)

IDCasoPasosEsperado
S01HealthGET /api/healthok · service: "talon-api"
S02CintaGET /api/lineas · abrir /4 líneas · 3 métricas · FOLD-TABLE
S03Métricas seedLeer datos2 cobrado · 1 pendiente · 1 anulado · suma 20,00
S04409POST /api/lineas/anular { code: "TAL-2901" }409
S05AnularSheet corona PENDIENTE · confirma201 · status ANULADO
S06Copy successLeer /ok/:code4 oposiciones visibles
S07Apuntar/apuntar · concepto + importe + forma · submit201 · /ok/TAL-2905
S08Login/login RemediosJWT · /cierre
S09Mesa authGET /api/mesa con tokenmétricas + líneas
S10Mesa 401GET /api/mesa sin token401
S11Mobile/ y /apuntar @390S-SIDE · 4 líneas · targets
S12SeedTras re-seed2 COBRADO · 1 PENDIENTE · 1 ANULADO

4. Regresión funcional

IDÁreaCheck
R01POST apuntar crea líneaNuevo code TAL-XXXX
R02POST anular pasa a ANULADOTAL-2903 deja de ser PENDIENTE
R03Importe negativo seedTAL-2904 -6,00 visible
R04Concepto vacío400 · no navega a ok
R05Importe inválido400
R06Code inventado/ok/TAL-9999 · 404 UI
R07Guard ruta/cierre sin token → login ?next=
R08LogoutToken limpio · mesa 401
R09S-SIDEHoy / Apuntar / Cierre navegables
R10Leftover0 manta-api / trastos / REGIDORA / bicis / MECANICO en UI
R11409 ANULADOPOST anular TAL-2904 → 409
R12BulkUI no permite array de codes

5. Accesibilidad (muestra)

IDCheck
A01Ink sobre ground en cuerpo
A02Focus visible mark en tab order
A03S-SIDE slots ≥ 44×44
A04Status con texto, no solo color
A05prefers-reduced-motion
A06Labels en form apuntar, sheet y login
A07aria-busy en loading Hoy
A08Sheet como dialog

6. Contenido

IDCheck
C01Ningún CTA «Facturar» / «Exportar» / «Declarar» / «Borrar»
C02Eslogan en Hoy
C03COBRADO = «Cobrado» no «Facturado»
C04Códigos TAL-XXXX
C05Cuatro oposiciones en success

7. Visual / Paper

IDCheck
V01Cinta + 3 datos + 4 filas (no hero+panel, no plano, no bento, no feed)
V02Mood phosphor (no hueso MANTA, no grafito taller, no papel rosa)
V03Sin foto-led staff (D-P1-09)
V04Cierre = métricas del día (no kanban)
V05S-SIDE no bottom de merendero

8. API negativa

CasoHTTP
Login malo401
Apuntar sin concepto400
Apuntar sin importe400
Anular sin code400
Anular sobre COBRADO409
Anular sobre ANULADO409
Anular code 404404
Mesa sin auth401

9. Datos de prueba

ActorDato
AyudanteLucia Ayala (sin cuenta)
Línea happy PENDIENTETAL-2903 Corona 35,00
Línea 409TAL-2901 Ramo COBRADO
Línea ANULADOTAL-2904
Apuntar smokeRamo pequeño · 10,00 · efectivo
TITULARremedios@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

ArtefactoPath
Briefdocs/00-day-brief.md
Paper refdocs/00-paper-reference.md
Productodocs/01-project-definition.md
IA / rutasdocs/03-information-architecture.md
Flujosdocs/04-user-flows.md
Datosdocs/05-data-model.md
Stackdocs/06-tech-stack.md
DS / tokensdocs/08-design-system.md
Copydocs/09-content-guide.md
Builddocs/20-implementation.md
App/Users/cristian/orca/talon-app
GHCriscode2022/talon-app
Paper01M165CVX37R8QSKBG37N0QRS4
API:3029 · talon-api
Neoncool-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
1Rutas / /apuntar /ok/:code /login /cierre
2Home = FOLD-TABLE H-TABLE (cinta + 3 datos + 4 líneas), no H-MAP ni H-BENTO ni hero+panel
3Chrome S-SIDE Hoy · Apuntar · Cierre
4F-EDIT: apuntar línea + anular PENDIENTE (sheet UI-10); 409 si no PENDIENTE
5POST apuntar público; success con 4 oposiciones
6JWT TITULAR; mesa 401 sin token
7Seed 4 líneas · 2 COBRADO · 1 PENDIENTE · 1 ANULADO · suma 20,00
8Health talon-api · puerto 3029
9Tokens phosphor + IBM Plex Mono / Karla
10Empty / error / loading / 409
11Mobile 390 usable (Hoy + apuntar)
120 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

UIRutaComponente
UI-01 / 11/HoyPage
UI-02 / 12/apuntarApuntarPage
UI-10/ sheetAnularSheet
UI-03/ok/:codeOkPage
UI-04/loginLoginPage
UI-05/cierreCierrePage
UI-06 / 07 / 08estadosmismos components
UI-09themeTailwind

4. API checklist

MétodoRutaAuth
GET/api/healthNo
GET/api/lineasNo
GET/api/lineas/:codeNo
POST/api/lineasNo · apuntar
POST/api/lineas/anularNo · anular · 409
POST/api/auth/loginNo
GET/api/mesaJWT 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

ItemValor
Emailremedios@talon.parada
Passwordpassword123
CodesTAL-2901…2904
Suma cobrada20,00 €

6. Anti-patrones de implementación

No hacerHacer
Puerto 3028 / health manta-api3029 / talon-api
Tabla trastos / tratos / bicislineas
Bottom S-BOTTOM / Top S-TOPS-SIDE
Plano H-MAP / Bento H-BENTOCinta FOLD-TABLE H-TABLE
Kanban cierreMétricas del día
Pago / Stripe / facturaPOST concepto + importe + forma
AEAT / TicketBAIFuera
Hero+panel AP-25Cinta densa sin foto-led
Bulk anularUna 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)

PreguntaDefault 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

FaseNombreIntención
L2Slice actualHoy + apuntar + anular + cierre JWT · cerrado en esta iteración (docs/contrato)
L3Nice-to-have de otro productoSolo 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)

PiezaEstado
H-TABLE FOLD-TABLE 4 líneas + 3 métricasMust · cerrado (docs)
Apuntar sin cuentaMust · cerrado
F-EDIT anular PENDIENTE + 409Must · cerrado
Success + 4 oposicionesMust · cerrado
Login TITULARMust · cerrado
Cierre cobrado / pendiente / anuladoMust · cerrado
Empty / error / loading / 390Must · cerrado
Docs 00–20 + README + executiveMust · cerrado
Paper 12 UX + 12 UI (inventario)Must (ref) · cerrado
Contrato talon-app · API :3029 · health talon-apiMust · 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)

IDIdeaPor qué L3Riesgo
L3-01Pagos online / TPV / pasarelaRompe S3; forma dejaría de ser etiquetaFintech disfrazado
L3-02AEAT / TicketBAI / facturaRompe S3; Cerrar ≠ HaciendaFiscal disfrazado
L3-03Stock / SKURompe S3; H3Inventario disfrazado
L3-04Export ExcelContradice «TALÓN no es Excel» si se vuelve MustHoja disfrazada

Estas ideas no completan TALÓN. Completarían otro producto. [DECISIÓN]

4. Anti-roadmap (no disfrazar)

Pedido típicoRespuesta
«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

DependenciaNota
Neon cool-cloud-04708830L2 (DATABASE_URL)
Paper file 01M165CVX37R8QSKBG37N0QRS4Diseño; inventario en 00
talon-app · GH Criscode2022/talon-appContrato de build (doc 20); puede no existir aún

6. Criterios para abrir un L3

  1. Smoke L2 en verde (doc 13) cuando haya runtime.
  2. Copy irrenunciable intacto.
  3. El brief L3 nombra pagos / AEAT / stock sin reabrir cinta, F-EDIT de una línea ni cierre.
  4. 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

TokenValor
Duración corta120–160ms
Easingease-out
Reduced motion0ms
Target≥44×44
Pendingcontrol 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

GestoResultado
Primera cargaLoading (UI-08): skeleton 3 datos + 4 filas card; aria-busy
200 con 4Cinta a muro + 3 datos + 4 líneas. Código, concepto, importe, forma, estado
200 con 0UI-06 empty «Aún no hay líneas.»
Error 5xx / redUI-07 + Reintentar (repite GET lineas)
Tap línea PENDIENTEAbre sheet anular (UI-10)
Tap línea COBRADO / ANULADOSello; 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 desktopRing 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)

GestoResultado
CargaForm vacío; submit disabled si faltan campos
Concepto / importe / forma vacío + submitError de campo · no POST
Submit válidoPOST /api/lineas · pending en botón
201/ok/:code con apuntado: true
400sello/mark + mensaje de campo
Redseal + 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

GestoResultado
Abrir desde PENDIENTESheet dialog · código + concepto + importe solo lectura
Esc / cerrarVuelve a la cinta; foco a la fila
Submit válidoPOST /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
400Campos
RedReintentar en sheet

AC: una sola línea. Cero bulk. Cero borrar sin rastro. Cero anular COBRADO.


5. Success (UI-03)

GestoResultado
Entrada desde apuntar 201«Apuntado.» + código TAL-XXXX + 4 oposiciones
Entrada desde anular 201«Anulado.» + código + 4 oposiciones
Tap Volver/
Deep link directoGET /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)

GestoResultado
Submit válidoPOST login · JWT · /cierre o next
401«Email o contraseña no valen.»
Demo hintremedios@talon.parada en mute

AC: sin signup. Solo TITULAR.


7. Cierre (UI-05)

GestoResultado
Sin tokenRedirect /login?next=/cierre
Con tokenGET /api/mesa · métricas + líneas agrupadas
LoadingSkeletons
Empty«No hay líneas en el cierre.»
SalirLimpia 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)

EstadoInteracción
Empty HoyMensaje + CTA Apuntar opcional
Error redReintentar enfocable
Loadingaria-busy; sin layout jump fuerte
409Assertive 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

  1. FOLD-TABLE sin foto-led ni hero+panel.
  2. Anular solo desde PENDIENTE; 409 en resto.
  3. Reduced motion respetado.
  4. Targets ≥44.
  5. Success siempre con las cuatro oposiciones.

17-prototype-map.md

17 — Mapa de prototipo — TALÓN

1. Fuentes

FuenteID / path
Paperhttps://app.paper.design/file/01M165CVX37R8QSKBG37N0QRS4
File ID01M165CVX37R8QSKBG37N0QRS4
UX-count12
UI-count12
App/Users/cristian/orca/talon-app
Case assets2026-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

UXNombreDoc espejo
UX-00CoverREADME · executive · 07
UX-01Stakeholders02 §3
UX-02Personas02 §4
UX-03JTBD02 §5
UX-04Stories02 §6
UX-05Journey02 §7 · 04
UX-06Blueprint02 §8
UX-07Site map03
UX-08Flujos04
UX-09Datos+permisos05 · 01 §5 · 11
UX-10Métricas12
UX-11Research02

3. UI producto → rutas / componentes

UINombreRutaComponente Angular
UI-01Hoy/HoyPage
UI-02Apuntar/apuntarApuntarPage
UI-03Success/ok/:codeOkPage
UI-04Login/loginLoginPage
UI-05Cierre/cierreCierrePage
UI-06Emptymismas rutasestados
UI-07Errormismas rutasestados · 409
UI-08Loadingmismas rutasestados
UI-09Tokens— (theme)Tailwind config / styles
UI-10Anular/ sheetAnularSheet
UI-11Mobile hoy/ @390HoyPage
UI-12Mobile apuntar/apuntar @390ApuntarPage

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

CodeConceptoImporteFormaEstado
TAL-2901Ramo mixto12,00 €efectivoCOBRADO
TAL-2902Planta crasa8,00 €bizumCOBRADO
TAL-2903Corona blanca35,00 €efectivoPENDIENTE
TAL-2904Maceta devuelta-6,00 €efectivoANULADO

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

ArtboardAncho 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ódigoEvidencia en UI
R-INHerramienta densa phosphor (S-SIDE, cinta, Mono importes)
S-SIDEHoy · Apuntar · Cierre en UI-01 / 11 / 02 / 05
H-TABLEUI-01 FOLD-TABLE: cinta + 3 datos + 4 filas
F-EDITUI-02 apuntar + UI-10 anular una línea

8. Gaps conscientes

GapNotas
Pagos / AEAT / stock / Excel exportL3 · no son huecos del prototipo L2
PATCH fiscalFuera · cierre de lectura
Analytics en prototipoModelo 12
Densificación PaperGate del mismo día · 00 placeholder
Runtime appContrato; no fake smoke

Ningún gap es producto in-scope aplazado. [DECISIÓN]

9. Criterios de aceptación del mapa

  1. Cada UI-01…12 tiene fila en esta tabla.
  2. Cada ruta Must tiene artboard.
  3. No hay artboard de /excel, /factura, /aeat, stock o merendero.
  4. Mobile 390 cubierto (UI-11, UI-12).
  5. 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.

PiezaEstado
Docs 01–20 + README + executiveOK (este set)
00-day-briefIntactos (fuente de verdad)
00-paper-referenceOK · UX-count 12 · UI-count 12
Paper 12 UX + 12 UIInventario en 00 · file 01M165CVX37R8QSKBG37N0QRS4
App path /Users/cristian/orca/talon-appContrato · GH Criscode2022/talon-app (puede no existir aún)
API :3029 · health talon-apiContrato
Código lineas + anular + JWT TITULARContrato doc 20
Cierre sin deuda del L2OK · roadmap solo L3 pagos / AEAT / stock

2. Terna y diversidad

CheckEvidencia
R-IN · S-SIDE · H-TABLE · F-EDITBrief + 01 + 07
FOLD-TABLEBrief · omite foto-led D-P1-09
0 códigos = MANTAMANTA era R-CL · S-BOTTOM · H-MAP · F-MKT
≥2 vs PIÑÓN / BOBINASide/Table/Edit vs top/bento/cmp y dock/feed/story
S-SIDE, H-TABLE, F-EDIT no en últimos 5Brief
Ground G-PHOSPHOR #10151000 + 07 + Tailwind
No leftover MANTA/PIÑÓN0 trastos / REGIDORA / manta-api / bicis / MECANICO / ganchos
Mood phosphor ≠ papel rosa07
H-TABLE ≠ CESTAF-EDIT de caja, no despensa
L2 no L1 consecutivoBrief

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

APMitigación
AP-25 hero+panelFOLD-TABLE cinta densa; sin split foto
AP-21 card huecaCódigo/concepto/importe/forma/estado visibles
D-P1-09 foto-led staffOmitido a propósito
Leftover como estadoContrato TALÓN; no se anota MANTA como producto vivo
Entrevistas inventadas02 etiquetado
trastos/REGIDORA/manta-api0 en dominio; 05 + 20
bicis/MECANICO/ganchos0 en dominio
H-MAP / S-BOTTOM / F-MKTCinta + S-SIDE + F-EDIT
H-BENTO / S-TOP / F-CMPCinta + S-SIDE + F-EDIT
KanbanCierre del día
Pagos / AEAT / stock en L2S3 · solo L3
Estadísticas inventadasEtiquetas [HIPÓTESIS]/[SUPUESTO]
Roadmap con deuda L2Doc 15 solo L3
Fake runtime smokeSCORE 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.

codeconceptoimporteformastatus
TAL-2901Ramo mixto12,00efectivoCOBRADO
TAL-2902Planta crasa8,00bizumCOBRADO
TAL-2903Corona blanca35,00efectivoPENDIENTE
TAL-2904Maceta devuelta-6,00efectivoANULADO

Métricas: cobrado 2 · pendiente 1 · anulado 1 · suma cobrada 20,00 €.

6. Assets

ArchivoPresente
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

ArchivoEstado
README.mdOK
presentation/executive-summary.mdOK
docs/00-day-brief.mdPreexistente
docs/00-paper-reference.mdOK
docs/01 … docs/20OK

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)

EjeScoreNota
Diversidad5Libro de caja nuevo; L2 no L1; no merendero/mapa/bottom
Docs5Suite 00–20 + brief + presentation
Paper craft UI512 UI tokens/hoy/apuntar/anular/success/login/cierre/empty/error/loading + 2 mobile
Paper UX process512 UX
Media3Staff omite foto-led; cover UX opcional
Canvas org4Inventario en 00; densificación = gate
Código E2E2Contrato hasta smoke; no se finge runtime
Paridad app3Contrato S-SIDE + H-TABLE + tokens G-PHOSPHOR
Unicidad estructura5R-IN · S-SIDE · H-TABLE · F-EDIT · FOLD-TABLE
Cierre admin4Suite docs lista; Paper/GitHub gates del día
Media~4.1Sin 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

EstadoSignificado
DoneDefinido y aceptado en la suite ALS L2 (esta iteración)
Won’t L2Fuera; L3 pagos / AEAT / stock u otro case
ContratoEspecificado; 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ÍtemEstado
A1Cinta a muro + 3 métricas + 4 líneasDone
A2Fila: código, concepto, importe, forma, statusDone
A3Tap PENDIENTE → sheet anularDone
A4Empty / loading / errorDone
A5Mobile 390Done
A6Foto-led / hero+panelWon’t L2 (D-P1-09 / AP-25)
A7Búsqueda comando /buscarWon’t L2 (≠ LOMO)
A8Plano de mantasWon’t L2 (≠ MANTA)
A9Bento de ganchosWon’t L2 (≠ PIÑÓN)

3. Épica B — Apuntar

IDÍtemEstado
B1/apuntar · concepto + importe + formaDone
B2POST público 201 / 400Done
B3Crea línea COBRADO o PENDIENTEDone
B4/ok/:code + 4 oposicionesDone
B5Factura / NIF / AEATWon’t L2
B6Signup ayudanteWon’t L2 (S2)

4. Épica C — Anular F-EDIT

IDÍtemEstado
C1Sheet una línea sobre /Done
C2POST /api/lineas/anular → ANULADODone
C3409 si no PENDIENTEDone
C4Copy talón ≠ factura / no ExcelDone
C5Bulk anular / borrar sin rastroWon’t L2
C6Anular COBRADOWon’t L2 (409)

5. Épica D — Cierre TITULAR

IDÍtemEstado
D1Login JWT RemediosDone
D2/cierre cobrado / pendiente / anuladoDone
D3GET mesa 401 sin tokenDone
D4LogoutDone
D5Suma cobradaDone
D6Kanban columnasWon’t L2 (≠ PREGÓN)
D7PATCH a HaciendaWon’t L2

6. Épica E — Chrome S-SIDE

IDÍtemEstado
E1Side Hoy · Apuntar · CierreDone
E2aria-current + targets 44Done
E3Cierre guest → loginDone
E4Bottom MANTA / top PIÑÓN / dock BOBINAWon’t L2

7. Épica F — Design system & a11y

IDÍtemEstado
F1Tokens ground/ink/card/mark/mute/selloDone
F2IBM Plex Mono + KarlaDone
F3Contraste ink/ground AADone
F4Reduced motionDone
F5Modo letra grandeWon’t L2 (corte a11y, no deuda)

8. Épica G — Plataforma

IDÍtemEstado
G1Nest :3029 · health talon-apiContrato
G2Neon cool-cloud-04708830 schema+seedContrato
G3Angular rutas + guardContrato
G4pnpm apps independientesContrato
G5Pasarela / StripeWon’t L2 · L3
G6AEAT / TicketBAIWon’t L2 · L3
G7Stock / SKUWon’t L2 · L3
G8Export Excel MustWon’t L2

9. Épica H — Documentación & diseño

IDÍtemEstado
H1docs 00–20 + README + executiveDone
H2Paper UX 12 + UI 12 inventarioDone
H3File 01M165CVX37R8QSKBG37N0QRS4Done (ref · densificación gate)

10. Orden de build (mismo alcance, no roadmap)

  1. Schema + seed + health
  2. GET lineas + HoyPage FOLD-TABLE
  3. ApuntarPage + POST lineas
  4. AnularSheet + POST anular + 409
  5. OkPage copy
  6. Auth + CierrePage
  7. S-SIDE + 390 + empty/error/loading
  8. 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

TipoCount (aprox)
Done L2 (docs)~40
Contrato runtimeAPI/web/Neon
Won’t L2 / L3pagos, AEAT, stock, Excel + analogías vetadas
Docs DoneSuite 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

CampoValor
App path/Users/cristian/orca/talon-app
GHCriscode2022/talon-app
APINestJS · puerto 3029 · prefijo /api
WebAngular standalone · puerto 4200
Packageapps independientes (pnpm --filter)
DBNeon PostgreSQL · project cool-cloud-04708830 (DATABASE_URL)
Tablasusers, lineas, sessions
AuthJWT Bearer · role TITULAR (/cierre vía /api/mesa); cinta y POST públicos
DominioUser, Linea
Fecha2026-08-29
Healthtalon-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

RolEmailPassword
TITULARremedios@talon.paradapassword123

Ayudante / lectora mayor: sin cuenta. Lucia apunta en /apuntar o anula desde /.

3. Schema

Al boot o vía migrate:

  1. CREATE TABLE de users, sessions, lineas (doc 05).
  2. Índices: lineas(code), lineas(status), lineas(sort_order), users(email), lineas(created_at DESC).
  3. Seed idempotente:
    • upsert TITULAR remedios@talon.parada (hash bcrypt)
    • upsert lineas por code (TAL-2901TAL-2904) restaurando status, concepto, importe, forma
  4. Dominio: solo lineas + users + sessions. [DECISIÓN]

Upsert de lineas por code restaura status de catálogo para que el guión sea repetible. [DECISIÓN]

POST de apuntar genera código nuevo (TAL-2905+). POST de anular reutiliza el code de la línea.

Tablas (recordatorio)

TablaContenido
usersTITULAR Remedios Gil
lineas4 líneas (+ las del POST apuntar)
sessionssid + 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)

codeconceptoimporteformastatus
TAL-2901Ramo mixto12.00efectivoCOBRADO
TAL-2902Planta crasa8.00bizumCOBRADO
TAL-2903Corona blanca35.00efectivoPENDIENTE
TAL-2904Maceta devuelta-6.00efectivoANULADO

[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 === TITULAR protege /api/mesa.
  • Públicos: health, lineas, lineas/:code, POST lineas, POST lineas/anular, login.

Oficio

MétodoRutaAuthNotas
GET/api/healthNo{ ok: true, service: "talon-api" }
GET/api/lineasNometrics + sort_order asc
GET/api/lineas/:codeNoitem
POST/api/lineasNoINSERT linea; 400 si inválido
POST/api/lineas/anularNoUPDATE ANULADO; 409 si no PENDIENTE
GET/api/mesaJWTmé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

PiezaDetalle
Rutas/, /apuntar, /ok/:code, /login, /cierre
GuardauthGuard en /cierre
ChromeSideNavComponent · Hoy · Apuntar · Cierre
TokensTailwind extend: ground #101510, ink #D8F0C8, card #161C16, mark #8FD36A, mute #7E9174, sello #E24B4B
FontsIBM Plex Mono + Karla (Google Fonts o self-host)
InterceptorBearer desde localStorage
Estadosempty / error / loading en Hoy, apuntar, cierre

Componentes Must

HoyPage, ApuntarPage, AnularSheet, OkPage, LoginPage, CierrePage, SideNavComponent.

6. Criterios de aceptación de build

  1. Health talon-api en :3029.
  2. Seed 4 líneas con métricas 2/1/1 y suma 20.00.
  3. POST apuntar → 201 TAL-XXXX.
  4. POST anular PENDIENTE → 201 ANULADO; COBRADO → 409.
  5. GET mesa sin token → 401.
  6. UI muestra las cuatro oposiciones en success.
  7. 0 leftover MANTA/PIÑÓN en strings de producto.
  8. Smoke S01–S12 (doc 13) cuando el runtime exista — no fake.

7. Orden de implementación

  1. Monorepo pnpm + Nest health
  2. Schema + seed Neon
  3. GET/POST lineas + anular
  4. Auth + mesa
  5. Angular shell S-SIDE + HoyPage
  6. Apuntar + Ok
  7. AnularSheet + 409
  8. Login + Cierre
  9. Empty/error/loading + 390
  10. Smoke + kill procesos (D-P1-06)

8. Anti-implementación

ProhibidoCorrecto
service: "manta-api"talon-api
Tablas trastoslineas
Rol REGIDORATITULAR
Puerto 30283029
Hero foto + panelFOLD-TABLE
Soft-delete SQLStatus ANULADO
Stripe / TicketBAIFuera

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]