Arquitectura de Aplicación y Datos
Arquitectura en capas para el MVP de Partidas. Diseñada para simplicidad, portabilidad y migración futura a base de datos.
Diagrama de Arquitectura
Navegador
Usuario Final
Capa 1 — Presentación
React + Tailwind CSS + App Router
Capa 2 — Lógica de Aplicación
React Hooks + TypeScript
Capa 3 — API (Backend for Frontend)
Next.js API Routes
Capa 4 — Persistencia
localStorage (MVP) → PostgreSQL (post-MVP)
Interfaz abstracta IRepository para desacoplar la capa de datos. Permite migrar de localStorage a Supabase/PostgreSQL sin cambiar componentes ni hooks.
Stack Tecnológico
frontend
Next.js 14 (App Router) + TypeScript + Tailwind CSS
backend
Next.js API Routes (serverless functions)
persistencia
localStorage (MVP) → PostgreSQL/Supabase (post-MVP)
deploy
Docker (standalone output) + Coolify
ci
Pipeline Tank (build + health check gate)
Detalle de Capas
Presentación (UI)
Componentes React con Tailwind CSS. Layouts con App Router. Responsive mobile-first.
Lógica de Aplicación
Hooks personalizados para estado y operaciones CRUD. Cálculos de presupuesto y desviación.
API (Backend for Frontend)
API Routes de Next.js para operaciones CRUD. Validación de datos en servidor.
Persistencia
localStorage para MVP. Interfaz abstracta que permite migración futura a base de datos.
Principios de Arquitectura
- Separación de responsabilidades por capas
- Componentes atómicos y reutilizables
- Estado local con hooks — sin estado global complejo
- API RESTful consistente
- Mobile-first responsive design
- Datos tipados con TypeScript end-to-end
- Sin dependencias externas innecesarias
- Deploy idempotente y reproducible con Docker
Modelo de Datos
Entidades principales del MVP con sus atributos clave. Almacenadas como JSON en localStorage.
Proyecto
- id: string
- nombre: string
- cliente: string
- ubicacion: string
- fechaInicio: Date
- fechaFin: Date
- responsable: string
- estado: enum
- creadoEn: Date
Partida
- id: string
- proyectoId: string
- categoria: string
- codigo: string
- descripcion: string
- unidad: string
- cantidad: number
- precioUnitario: number
- total: number
RegistroEjecutado
- id: string
- partidaId: string
- cantidadEjecutada: number
- montoEjecutado: number
- fecha: Date
- observaciones: string
ItemCronograma
- id: string
- partidaId: string
- fase: string
- fechaInicioPlan: Date
- fechaFinPlan: Date
- fechaInicioReal: Date
- fechaFinReal: Date
- progreso: number