PDR-STACK-001 — Stack Tecnológico del SaaS Contable
Propósito: Documentar y justificar el stack tecnológico de Átomo. Es la decisión que determina el costo de desarrollo, el costo de operación por tenant, la velocidad de entrega y la capacidad de implementar la reexpresión por inflación en el futuro.
1. Metadatos
PDR-ID: PDR-STACK-001
Título: Stack tecnológico — Frontend React + Backend Supabase/PostgreSQL + Monorepo
Estado: BORRADOR
Dominio: priorizacion
Fecha: 2026-08-07
Autor: LEDGER-ARCHITECT (Protonion)
2. Hipótesis de Negocio
Creemos que el stack React + Supabase (PostgreSQL con RLS) es el punto óptimo entre velocidad de entrega, costo de operación por tenant y capacidad de cumplir la partida doble con integridad garantizada a nivel de base de datos, porque permite imponer las invariantes contables (Debe=Haber, inmutabilidad, tenant_id) con CONSTRAINTS y RLS nativos.
Problema: Un sistema contable no puede darse el lujo de errores: la integridad debe estar garantizada en la base de datos, no solo en la lógica de la aplicación. Y el presupuesto del MVP es ajustado.
Solución propuesta:
- Frontend: React 18 + TypeScript + Vite + TailwindCSS (patrón ProyectoNaif, probado por el equipo).
- Backend: Supabase (PostgreSQL 16 + Auth + RLS + Edge Functions en TypeScript).
- Base de datos: PostgreSQL — CONSTRAINTS de partida doble, RLS multi-tenant, numeric exacto para montos.
Mecanismo causal: PostgreSQL permite CHECK (monto >= 0), triggers de inmutabilidad y RLS por tenant como capa de seguridad independiente de la aplicación → la integridad contable sobrevive incluso a un bug de la app.
3. Decisión
Adoptamos monorepo con frontend React (Vite/TypeScript/Tailwind) + backend Supabase (PostgreSQL 16 + RLS + Edge Functions) como stack de Átomo.
- QUÉ se decide: PostgreSQL como único motor de datos (con
numeric(18,2)para montos, CONSTRAINTS de partida doble, RLS por tenant). Frontend en React con Astronaut Protocol. Auth vía Supabase Auth (email/password + magic link). - QUÉ NO se decide: No usamos microservicios en Fase 1 (monolito modular + Edge Functions para tareas específicas como cálculo de IVA por lote). No usamos NoSQL. No usamos serverless de terceros para el core contable.
- POR QUÉ: El stack es el mismo probado en ProyectoNaif (el equipo lo domina), PostgreSQL es el estándar de oro para integridad transaccional, y el costo de operación es predecible ($0-25/mes de infraestructura).
- CUÁNDO: Fase 1.
4. Contexto y Alternativas Consideradas
4.1 Alternativa A — React + Supabase/PostgreSQL (ADOPTADA)
| Aspecto | Descripción |
|---|---|
| Voto a favor | Stack dominado por el equipo, RLS nativo, integridad transaccional PostgreSQL, costo predecible, sin servidores |
| Voto en contra | Supabase es managed (no self-hosted en Fase 1); Edge Functions con límites |
| Costo estimado | $0-25/mes operación; ~cero en desarrollo extra |
| Riesgo principal | Dependencia de un proveedor → mitigado con export completo de BD |
4.2 Alternativa B — Python/FastAPI + PostgreSQL (estilo ZF)
| Aspecto | Descripción |
|---|---|
| Voto a favor | Control total del backend, sin límites de Edge Functions |
| Voto en contra | Servidor que administrar, más tiempo de desarrollo, más superficie de ataque |
| Costo estimado | +120-200h de desarrollo, +$20-50/mes operación |
| Riesgo principal | Más lento al mercado |
4.3 Alternativa C — Next.js full-stack (API Routes + Prisma + PostgreSQL)
| Aspecto | Descripción |
|---|---|
| Voto a favor | Un solo framework, SSR para reportes |
| Voto en contra | Menos maduro para RLS (Prisma no expone RLS de forma transparente), más configuración |
| Costo estimado | +80-120h |
| Riesgo principal | La seguridad multi-tenant queda a nivel de aplicación (más frágil) |
5. Premisas de Negocio Vinculadas
| Premisa | Relación | ADR vinculado |
|---|---|---|
| El equipo domina React/Vite/Supabase | soporta | ADR-STACK-0001 (pendiente) |
| El costo de operación debe ser predecible y bajo | soporta | ADR-STACK-0001 |
| La integridad contable vive en la BD | depende de | ADR-STACK-0001 |
6. Supuestos No Validados (Riesgos)
| Supuesto | Relación | Señal de validación |
|---|---|---|
| Supabase Free tier es suficiente en beta | depende de | < 50K transacciones mensuales en beta |
| RLS no degrada el rendimiento | depende de | Latencia p99 < 200ms con RLS activo |
7. Métricas de Validación
| Métrica | Línea Base | Objetivo (Señal Verde) | Señal Roja | Plazo |
|---|---|---|---|---|
| Costo de operación mensual | — | ≤ $25/mes con 50 tenants | > $100/mes | 6 meses post-lanzamiento |
| Latencia p99 del core contable | — | < 200ms | > 1s | Continuo |
| Tiempo de desarrollo Fase 1 | — | ≤ estimado en COTIZACION.md | > +30% | Fin Fase 1 |
7.1 Señal Verde (Decisión Validada)
- Operación ≤ $25/mes con 50 tenants.
- Los CONSTRAINTS de partida doble se cumplen en producción.
7.2 Señal Roja (Pivot Trigger)
- El costo de operación escala por encima de $100/mes con pocos tenants.
- Limitaciones de Edge Functions bloquean una funcionalidad P0.
8. Análisis de Riesgos (360°)
| Riesgo | Impacto | Probabilidad | Mitigación | Costo de mitigación |
|---|---|---|---|---|
| Dependencia de Supabase | Alto | Media | Export de BD planificado, SQL portable, backup diario | Bajo |
| Límites de Edge Functions | Medio | Baja | Mover lógica compleja a la app con transacciones SQL | Bajo |
| RLS mal configurado = fuga | Alto | Baja | Tests de aislamiento obligatorios en CI | Dentro del desarrollo |
9. Puerta de Retroceso (Pivot/Escape Hatch)
Condición de pivot: El costo de operación supera $100/mes con menos de 100 tenants activos, o una funcionalidad P0 queda bloqueada por límites del proveedor.
Nuevo rumbo: Migrar el backend a FastAPI/Python + PostgreSQL (el equipo ya lo hizo en ZF), manteniendo el frontend React. El schema SQL es portable.
Costo de pivot: 200-300h. Alto pero acotado gracias al SQL portable.
Ventana de decisión: 12 meses post-lanzamiento.
10. Referencias
| Recurso | Tipo | Enlace |
|---|---|---|
| ARD (stack detallado) | Arquitectura | ARD.md |
| ProyectoNaif (stack probado) | Referencia | Lab/ProyectoNaif/ARD.md |
| ZF (backend Python) | Referencia | Protonion/ZF/ |
| Template PDR | Metodología | Protonion/ZF/docs/decisions/product/TEMPLATE-PDR.md |
11. Firmas
| Rol | Nombre | Fecha | Decisión |
|---|---|---|---|
| Product Owner (Domain Expert) | Baduy Salazar | — | ⏳ Pendiente |
| LEDGER-ARCHITECT | — | 2026-08-07 | ⏳ Propuesto |
| FINOPS | — | — | ⏳ Pendiente |
| GOVERNOR | — | — | ⏳ Pendiente |
12. Historial de Cambios
| Versión | Fecha | Cambio | Autor |
|---|---|---|---|
| 0.1 | 2026-08-07 | Creación inicial | LEDGER-ARCHITECT |
Fin del PDR — Stack Tecnológico