Roadmap de desarrollo
El sistema Aquazaku no se construye de una sola vez. Se construye módulo por módulo, cada uno en su expresión mínima viable, con la arquitectura entre proyectos y el dominio ya cerrados antes de tocar el primer endpoint.
Esta página define qué se construye, en qué orden, y por qué en ese orden.
El detalle de cómo se construye cada módulo vive en su propio cambio SDD
(sdd/<módulo>/) y se linkea desde el catálogo.
Principios rectores
Sección titulada «Principios rectores»El orden y la cadencia del roadmap se sostienen sobre cinco reglas. Las dos primeras son reglas de oro declaradas explícitamente; las demás son convenciones que ya están vigentes en el proyecto.
1. De menos a más — la fundación antes que el resto
Sección titulada «1. De menos a más — la fundación antes que el resto»Cada módulo se construye en su expresión mínima viable antes de agregar complejidad. Si un módulo necesita identidad para funcionar, identidad se construye primero. Si necesita stock para vender, stock se construye antes que ventas.
Por qué: el módulo fundacional es el que menos-a-más dicta. En Aquazaku
eso es Auth + RBAC: nada funciona sin saber quién opera y qué puede hacer.
Referencia: memoria architecture/aquazaku-golden-rules.
2. Mobile-first como metodología de UI, no como plataforma
Sección titulada «2. Mobile-first como metodología de UI, no como plataforma»Resuelto al implementar M0 (ver Decisiones abiertas): “mobile first” se interpreta como metodología de diseño UI — responsive, touch targets accesibles, sticky bottom CTAs — aplicada a TODA superficie. NO se interpreta como prioridad de plataforma: la prioridad sigue siendo web Admin + POS primero (decisión
estrategia/mvp-scope-web-first).Dejó de ser un supuesto construyéndolo: los hitos del MVP salieron todos por web, y la app del seller sigue diferida a M8.
Por qué: las dos lecturas son coherentes mientras no haya app móvil. La metodología mobile-first ya se aplica a la web responsiva del POS (mostrador) y del Admin (que se opera desde el celular cuando el dueño viaja).
3. Build incremental — no más iteración de diseño
Sección titulada «3. Build incremental — no más iteración de diseño»El ciclo de iteración sobre los mockups de claude-design/ está cerrado.
Lo que falta se corrige al construir, no en una nueva ronda de diseño.
Por qué: los mockups ya tienen fidelidad suficiente para servir de
referencia visual. Seguir puliendo diseño es costo que no aporta valor. Las
derivas conocidas (vencimiento 6m vs 30d, entrega vs retornables,
personas placeholder) se resuelven en la implementación. Referencia: memoria
architecture/aquazaku-build-strategy.
4. Orden fundación → operacionales → soporte
Sección titulada «4. Orden fundación → operacionales → soporte»| Fase | Qué incluye | Razón de ser |
|---|---|---|
| Fundación | M0 (Auth + RBAC) | Sin identidad no hay permisos, sin permisos no hay módulo que funcione. |
| Operacionales | M1–M7 (Productos, Stock, Insumos, Producción, Clientes, Ventas, Retornables) | Son los módulos que operan el negocio día a día. Cada uno depende del anterior. |
| Soporte y control | M10, M9, M11, M12, M13 (Precios, Proveedores, Contador, Alertas, Auditoría) | Son módulos que consumen lo que los operacionales ya registran, o que auditan lo que ya pasó. No son blockers de la operación. |
| Post-MVP | M8 (Rutas y seller mobile) | Mobile-first del seller + rutas con offline-first se difiere a post-MVP (decisión estrategia/mvp-scope-web-first). |
5. Cada módulo pasa por el pipeline SDD completo
Sección titulada «5. Cada módulo pasa por el pipeline SDD completo»Cada módulo atraviesa spec → design → tasks → apply → verify → archive antes de pasar al siguiente. No se arranca un módulo mientras el anterior esté a medias. Ver Pipeline SDD abajo.
Arquitectura general
Sección titulada «Arquitectura general»Estructura polyrepo
Sección titulada «Estructura polyrepo»/Users/mao/code/aquazaku/ ← repo "paraguas" (no versiona código)├── docs/ ← Astro Starlight — este sitio (✅ activo)├── api/ ← Backend y API HTTP/JSON (✅ en producción)├── web/ ← Admin + POS responsivo (✅ en producción)├── mobile/ ← App del seller (🔲 POST-MVP)├── claude-design/ ← Mockups visuales (referencia, no docs)└── README.md / .gitignoreCada subproyecto (api/, web/, mobile/) vive en su propio repo git
independiente y está ignorado por la raíz. La raíz solo contiene README y
.gitignore para anclar el workspace y darle a engram un nombre de proyecto
único.
Por qué polyrepo y no monorepo: preserva el repo aquazaku-docs que ya
existía y evita que engram fragmente la memoria por repo. Las decisiones
transversales (ej. sincronización, contrato API) viven en un solo silo.
Referencia: memoria aquazaku/arquitectura/estrategia-repos.
Contrato entre proyectos
Sección titulada «Contrato entre proyectos»| Proyecto | Rol | Contrato hacia afuera | Estado |
|---|---|---|---|
docs/ |
Documentación técnica | Sirve páginas estáticas (Astro Starlight). | ✅ activo |
api/ |
Backend | Expone HTTP/JSON. Autentica, valida reglas, registra auditoría. | ✅ api.aquazaku.com · api-ci verde en cada merge a main |
web/ |
Admin + POS | Server-rendered responsiva. Consume api/ solo desde el servidor. |
✅ app.aquazaku.com · web-ci verde en cada merge a main |
mobile/ |
App seller | React Native o equivalente. Consume api/. |
🔲 POST-MVP |
Reglas de dependencia:
api/no conoceweb/nimobile/. Solo expone endpoints.web/ymobile/solo hablan conapi/. Nunca directo a la base.docs/no referencia código deapi/ni deweb/— describe reglas y decisiones, no implementaciones.
Las capas internas de cada proyecto (modelo de datos, controllers, componentes UI) se definen cuando arranca ese proyecto, no antes. Esta página describe el contrato entre proyectos, no las decisiones internas.
Roles del sistema
Sección titulada «Roles del sistema»El sistema tiene cuatro roles canónicos — no tres. El contador se agregó
en la sesión del 18-ago-2026 para temas tributarios en Colombia (DIAN) y es
el único rol que no muta datos.
| Rol | Quién es | Dónde opera | Permisos |
|---|---|---|---|
admin |
Dueño / administración | Web (remoto, escritorio en planta cuando viaja) | todo, sin restricciones |
seller |
Vendedor — contacta clientes a distancia (llamada/WhatsApp) y registra ventas | Web (mobile-first UI) en MVP; app móvil post-MVP | Acotados a su alcance (propio, ruta) |
pos |
Operario de planta + mostrador | Web / terminal en la planta | Acotados a planta + mostrador |
contador |
Contador externo o interno | Web, solo lectura | Lectura + descarga de PDFs y CSV |
Multi-rol: un usuario puede tener N roles asignados a la vez (ej.
["pos", "seller"]). Todo se audita bajo el mismo user_id. La UI muestra
los módulos según los roles que el usuario tiene. Referencia: memoria
dominio/acceso/roles-y-multi-rol.
Por qué existe contador aparte de admin: el dueño no debe ser quien se
genera a sí mismo los reportes que va a presentar. La separación agrega un
testigo externo al sistema.
La matriz completa celda por celda está en Roles y permisos.
Módulos del sistema
Sección titulada «Módulos del sistema»El sistema se divide en 16 módulos numerados M0–M15 (M8 diferido a post-MVP). M14 y M15 no estaban en el plan original: salieron de ver el sistema en manos de quien lo usa. El número indica el orden de construcción sugerido, no prioridad de negocio: M0 es fundación porque todo lo demás lo necesita, no porque sea el más visible.
Tabla de módulos
Sección titulada «Tabla de módulos»| # | Módulo | Propósito (una línea) | Roles que lo usan | Depende de | Estado |
|---|---|---|---|---|---|
| M0 | Auth + RBAC | Identidad, login, permisos por rol y alcance | Todos | — | ✅ terminado |
| M1 | Productos y catálogo | Qué se vende: pacas 600ml/300ml, botellones con sus unidades y conversiones | admin, pos, seller, contador |
M0 | ✅ terminado |
| M2 | Stock de producto terminado | Lotes, vencimiento 30d, FIFO, bloqueo de vencidos | admin, pos, seller, contador |
M0, M1 | ✅ terminado |
| — | Fase de diseño | Sistema de diseño aplicado: marca real, vidrio y agua, semáforo de estados, vacíos, errores sin jerga, voz de usted, accesibilidad medida | — | M2 | ✅ terminada |
| M3 | Insumos | Tapas, sellos, bolsas por kg con stock mínimo configurable (default 200/200) | admin, pos |
M0 | ✅ terminado |
| M4 | Producción y cierre del día | Cierre diario que mueve agua, stock e insumos en una transacción; balance de los dos tanques con reconciliación contra el nivel observado | admin, pos, contador |
M0, M1, M2, M3 | ✅ terminado |
| M5 | Clientes | Identidad con documento y dígito calculado, estado de verificación con responsable, tipo con lista de precios, direcciones como entidad y crédito que la base no deja habilitar sin verificar | admin, pos, seller, contador |
M0 | ✅ terminado |
| M6 | Ventas | Venta inmutable con precio congelado, anulación que revierte al mismo lote, cobros como documento aparte, devoluciones, descuentos con piso sostenido por la base, factura electrónica como intención | admin, pos, seller, contador |
M0, M1, M2, M5 | ✅ terminado |
| M7 | Retornables (botellones y bases) | Entrega con flujo híbrido, devoluciones, daño con tarifa fija, traza por id_sticker |
admin, pos, contador |
M0, M5 | ✅ terminado |
| M8 | Rutas y seller mobile | App nativa del seller, offline-first, cierre de ruta | seller, admin, contador |
M0, M5, M6, M7 | ⏸ POST-MVP |
| M9 | Proveedores y compras | Mixto contado/transferencia/crédito, sin módulo de CxP completo | admin, pos, contador |
M0, M3 | ✅ terminado |
| M10 | Precios y promociones | Listas residencial/comercial con piso, códigos de descuento con piso absoluto | admin, pos, seller, contador |
M0, M1 | ✅ entregado en M1+M6 |
| M11 | Contador | Panel solo lectura: extracto de los cinco movimientos de plata, cartera por edad, resumen mensual, CSV con columnas a elección, PDF por impresión del navegador | contador, admin |
M0, M5, M6, M7, M9, M10 | ✅ terminado |
| M12 | Alertas | Umbrales configurables en parametros, con sus límites en la base y cada cambio auditado con el valor anterior |
admin (configura), pos (ve los avisos) |
M0, M2, M3, M4 | ✅ terminado |
| M13 | Auditoría | Quién hizo qué cuándo; transversal — todo módulo registra | admin (consulta) |
M0 + transversal | ✅ entregado en M0 |
| M14 | Clientes ubicables | Dirección en nomenclatura colombiana, municipio del DANE, pin que pone la persona, y al menos un teléfono | admin, pos, seller, contador |
M0, M5 | ✅ terminado |
| M15 | Seguimientos | La lista de direcciones a las que hay que llamar, con su propio módulo; el tablero solo avisa cuántas hay | admin, seller, pos, contador |
M0, M5 | ✅ terminado |
Reglas del orden
Sección titulada «Reglas del orden»- M0 es fundación. Nada arranca antes que M0.
- M1, M2, M3 pueden ir en cualquier orden entre sí una vez M0 esté verificado. Son las “tablas maestras” del catálogo.
- M4 necesita M1+M2+M3. Producción registra producto, descuenta stock y consume insumos — los tres juntos.
- M5, M6, M7 se necesitan mutuamente en parte: M5 (clientes) habilita M6 (ventas) y M7 (retornables a un cliente). M7 puede arrancar con cliente opcional, pero la versión completa depende de M5.
- M10 va antes que M6 si se quiere validar precios antes de vender; o puede ir después de M6 si se arranca con precios hardcodeados y se flexibiliza después. Decisión de cadencia.
- M9, M11, M12, M13 son soporte — entran cuando los operacionales ya tienen datos reales para consumir/auditar.
- M8 queda explícitamente fuera del MVP. Se referencia acá para que no se olvide, pero no se implementa en esta fase.
Documentos de dominio ya existentes
Sección titulada «Documentos de dominio ya existentes»Cada módulo tiene su documentación de dominio en /docs/dominio/ con las
reglas de negocio (RN-*) ya acordadas. El roadmap no las repite —
linkea.
| Módulo | Doc de dominio | Reglas principales (referencia) |
|---|---|---|
| M1 | Productos y catálogo | RN-CAT-01 a 11 (catálogo cerrado, desactivar sin borrar, precio en el producto, piso absoluto, paca indivisible) |
| M2 | Stock | RN-STK-01 a 08 (ubicación, motivos, FIFO, devoluciones, descarte, lote y vencimiento 30d) |
| M3 | Insumos | ✅ documentado el 22-ago-2026. Mínimo 200/200 confirmado como valor inicial configurable (RN-INS-03); falta la equivalencia kg→unidades de bolsas (pregunta 37) |
| M4 | Producción | RN-PRD-02 a 24 (tanques separados, cierre diario, lote, encendido/apagado, etc.) |
| M5 | Clientes | RN-CLI-08 (documento único), RN-CLI-12 (crédito), RN-CLI-15 (verificación) |
| M6 | Ventas | RN-VEN-01 a 13 (inmutabilidad, anulación, precios, descuentos, factura) |
| M7 | Botellones y bases | RN-ENV-01+ y RN-BAS-01+ (entrega híbrida, daño con tarifa, id_sticker) |
| M9 | Proveedores | RN-PRO-01 a 07 (la compra le pone nombre al inventario que ya entra, crédito modelado sin ejercerse, aviso de vencidas) |
| M11 | Contador | RN-CON-01 a 09 (lee y no escribe, reportes reproducibles, el extracto cuadra o lo dice, cartera por edad, resumen mensual por meses enteros, columnas a elección salvo el monto, y el hueco de los gastos declarado) |
| M0 | Roles y permisos | RN-ACC-01 a 05 (multi-rol, UI oculta, alcance, auditoría, desactivación) |
Convenciones transversales
Sección titulada «Convenciones transversales»Reglas que aplican a todos los módulos, no a uno solo. El roadmap las recuerda; el detalle vive en los docs de dominio y en engram.
| Convención | Referencia |
|---|---|
Reglas con ID RN-XXX-## — área + correlativo, estado explícito (✅ / 🟡 / 🔴) |
aquazaku/dominio/convencion-reglas |
| Mobile-first como metodología UI — touch targets ≥ 44px, sticky bottom CTAs, responsive de entrada | architecture/aquazaku-golden-rules |
| Datos en bandas, no falsa precisión — “entre 3 y 5 días”, nunca “4,3” | RN-PRD-15 |
| Acción irreversible con motivo obligatorio — anulaciones, ajustes, descartes: texto ≥ 10 caracteres | aquazaku/dominio/convencion-reglas + claude-design reglas-como-tests |
| El saldo calculado manda, la lectura visual reconcilia — patrón inventario contable vs conteo físico | RN-PRD-14 |
| Personas de los mockups son placeholder — al construir, el admin crea un perfil por cada rol canónico | design/placeholder-personas |
Multi-rol por usuario, un user_id único — la UI oculta módulos según el rol ejercido, la API prohíbe |
RN-ACC-01 a 03 |
Pipeline SDD por módulo
Sección titulada «Pipeline SDD por módulo»Cada módulo recorre las seis fases de Spec-Driven Development antes de pasar al siguiente. No se pisan fases entre módulos distintos.
spec → ¿QUÉ se hace? (requerimientos + escenarios Given/When/Then)design → ¿CÓMO se hace? (arquitectura interna, archivos, contratos, datos)tasks → ¿CÓMO se parte? (lista de tareas implementables, agrupables)apply → CONSTRUIR (código + tests, commits por unidades de revisión)verify → PROBAR (ejecutar tests, simular escenarios, UAT conversacional)archive → SINCRONIZAR (delta specs → spec canónico, cleanup)Un módulo queda archivado solo cuando su verify pasa. El siguiente módulo
puede arrancar en design mientras el anterior está en apply, pero no antes.
Estado actual
Sección titulada «Estado actual»Al 11-oct-2026:
| Fase | Módulo |
|---|---|
| ✅ Terminado | M0 — Auth + RBAC · M1 — Productos · M2 — Stock · Fase de diseño (marca, vidrio, agua, estados, vacíos, voz de usted, accesibilidad) · M3 — Insumos · M4 — Producción · M5 — Clientes · M6 — Ventas · M7 — Retornables · M9 — Proveedores · M11 — Contador · M12 — Alertas · M15 — Seguimientos |
| Design en curso | — |
| Apply en curso | — |
| Pendiente | — | | Diferido (post-MVP) | M8 — Rutas y seller mobile |
Los trece hitos del MVP están cerrados, M14 —lo que pidió la primera demo con el cliente— y M15 también.
M14 — Clientes ubicables
Sección titulada «M14 — Clientes ubicables»No estaba en el roadmap: salió de ver el sistema en manos de quien lo va a usar. Dos huecos que ninguna revisión de código había mostrado.
La dirección era un campo de texto. Ahora se descompone en la nomenclatura
colombiana —CL 45 A # 12 B - 34— con municipio, departamento y un pin
opcional en el mapa.
Ningún campo de ubicación es obligatorio, y es una decisión: Aquazaku reparte en
pueblos donde una dirección puede ser «Vereda La Peña, casa de tabla azul».
Exigir la estructura haría que el operador invente CL 1 # 1-1 para poder
guardar — perdiendo el dato y ensuciando la base.
Lo que sí exige la base es que el conjunto ubique: direcciones_ubicable
pide al menos una de estructura, línea libre, indicaciones o coordenadas.
No había ningún dato de contacto. Se había construido la cartera por edad para saber a quién llamar primero, y no había a qué número llamar.
Lo que sostiene la ortografía
Sección titulada «Lo que sostiene la ortografía»Municipio y departamento salen del catálogo oficial del DANE: 33 departamentos, 1122 municipios, con coordenadas. Se guardan en minúscula y se muestran con la ortografía correcta.
Hace falta un catálogo y no una transformación: «Campo de la Cruz» no se
reconstruye desde campo de la cruz —un título automático daría «Campo De La
Cruz»— porque las preposiciones en minúscula dependen de cuál palabra es.
Y sigue aceptando lo que el DANE no lista: las veredas.
El pin se arrastra, no se busca
Sección titulada «El pin se arrastra, no se busca»Ningún servicio geocodifica CL 5 # 3-24, Campo de la Cruz con precisión. El
mapa se centra en el municipio y la persona pone el pin: las coordenadas
salen de alguien que sabe dónde está la casa. Una ruta calculada sobre una
posición inventada es peor que ninguna — y esas coordenadas son la base de M8.
M15 — Seguimientos
Sección titulada «M15 — Seguimientos»La lista de clientes a los que hay que llamar (RN-CLI-18) arrancó como una sección del tablero. Funcionaba — pero el peso de la tarjeta (días, teléfonos, etiqueta, botón de WhatsApp, dos franjas de urgencia) le ganaba al resto y el tablero dejaba de leerse como «qué hacer / cómo venimos»: se leía como «llamar a Yeimy».
La mudanza
Sección titulada «La mudanza»La lista completa se mudó al módulo Seguimientos (/modulos/seguimientos),
visible para los cuatro roles — todos tienen clientes:ver, que es lo que pide
el endpoint. El tablero conserva solo el recordatorio: si hay N clientes a
los que llamar, lo dice como un pendiente más, con la cantidad exacta y un link
«Ir a Seguimientos →».
Qué cambió y qué no
Sección titulada «Qué cambió y qué no»| Pieza | Estado |
|---|---|
Endpoint /clientes/a-llamar |
intacto |
Componente ClientesParaLlamar |
intacto, mismos tests |
| Permisos | intactos (clientes:ver) |
| Render del tablero | saqué la sección, sumé el pendiente |
| Catálogo de módulos | entrada nueva seguimientos |
Es el primer caso del patrón «sección pesada del tablero migra a módulo propio». El tablero sigue cumpliendo su rol de vistazo general del negocio; la vista dedicada es la lista completa.
M12 fue el último. Los avisos ya funcionaban —el de bases (RN-BAS-13), el de compras vencidas (RN-PRO-07), el de vencimiento próximo (RN-STK-11)—, pero con el umbral escrito en el código. Lo que cerró M12 es que ese número se mueve desde la administración.
Y las constantes se borraron, no quedaron como default. Un default en el código más una fila en la base son dos lugares donde configurar lo mismo, y el día que discrepen nadie sabría cuál manda.
Los límites de cada umbral viven en la base con un CHECK
(ADR-0006): un umbral en cero apaga
la alerta sin decirlo, y uno enorme la deja siempre encendida — las dos formas
de romperla se ven igual desde afuera, porque en las dos nadie reacciona.
Cada cambio queda en la bitácora con el valor anterior. Un aviso que dejó de sonar tiene dos explicaciones —el problema desapareció, o alguien movió el número— y meses después no hay forma de distinguirlas sin eso.
Lo que sigue no es un hito: son M8 y la facturación electrónica, diferidos a propósito —están en la tabla de arriba—, y las preguntas abiertas con el contador.
M10 (Precios) también está entregado, absorbido por M1 y M6: listas residencial/comercial con piso, códigos de descuento y el piso sostenido por la base.
El resto del documento de dominio está cerrado: las reglas RN-* que ya están
publicadas en /dominio/ cubren lo que el módulo necesita definir, no
cómo lo implementa. El SDD de cada módulo traduce esas reglas en código.
Decisiones abiertas
Sección titulada «Decisiones abiertas»No queda ninguna que frene la spec de un módulo. Los hitos del MVP están cerrados y M8 es la única pieza diferida, a propósito.
Lo que sigue abierto son las preguntas a Aquazaku —las mediciones 🟠 que hay que ir a tomar en la planta, las 🟢 del módulo de perfil y las 🔵 del contador—. Ninguna frena código en curso: los módulos que dependían de un número se entregaron con el número vacío y diciéndolo, en vez de estimarlo.
Resuelta al construir M7 (26-ago-2026)
Sección titulada «Resuelta al construir M7 (26-ago-2026)»| Pregunta | Cómo quedó |
|---|---|
Nombre del módulo de retornables: ¿entrega o retornables? |
retornables, en los dos repos. Se decidió construyéndolo, no discutiéndolo; entrega quedó como el nombre de los mockups de claude-design/ |
Resueltas al diseñar M3 (22-ago-2026)
Sección titulada «Resueltas al diseñar M3 (22-ago-2026)»| Pregunta | Cómo quedó |
|---|---|
| Stock mínimo default de insumos | 200 tapas / 200 sellos como valor inicial, configurable desde la administración (RN-INS-03) |
| Las bolsas se cuentan por kilo o por unidad | Se compran por kilo y se guardan por unidad (RN-INS-02). La conversión es una medición de planta, no una constante (pregunta 37) |
| El cloro y los filtros entran como stock | No — son gasto, no inventario (RN-INS-04) |
Resueltas al implementar M2 (22-ago-2026)
Sección titulada «Resueltas al implementar M2 (22-ago-2026)»| Pregunta | Cómo quedó |
|---|---|
| Umbral del aviso de vencimiento próximo | 7 días como valor inicial, configurable desde la administración (RN-STK-11) — pregunta 36 cerrada |
Resueltas al implementar M0
Sección titulada «Resueltas al implementar M0»| Pregunta | Cómo quedó |
|---|---|
| Interpretación de “mobile-first” | Metodología de UI. La app móvil del seller es post-MVP; se arranca por web y las pantallas se diseñan desde el ancho chico hacia arriba |
Stack del proyecto api/ |
ADR-0001, y ya implementado: Node 22, Fastify 5, Drizzle, Postgres 17, Better-Auth 1.7. La ADR dice 16 porque eso se eligió en agosto de 2026; local migró a 17 el 16-sep-2026 para alinearse con producción y CI |
Derivas heredadas del paquete claude-design/ |
M0 se construyó desde el dominio y los ADR, no desde los mockups. Las derivas documentadas en el verify del 19-ago-2026 no se replicaron en el código; siguen valiendo como advertencia para los módulos que sí usen esos diseños |
Ver también
Sección titulada «Ver también»- Catálogo de módulos — índice rápido por módulo.
- Dominio — reglas RN-* que el roadmap asume ya cerradas.
- Decisiones técnicas — ADRs que respaldan el orden y la estructura.
- Qué falta preguntar — preguntas abiertas a Aquazaku (principalmente mediciones 🟠 que requieren ir a la planta).
