291 lines
7.6 KiB
Markdown
291 lines
7.6 KiB
Markdown
# Especificaciones del Proyecto - Finanzas Personales
|
|
|
|
## Descripción General
|
|
Aplicación web moderna para gestión de finanzas personales. Diseño sobrio y elegante con tema oscuro.
|
|
|
|
## Stack Tecnológico
|
|
- **Framework**: Next.js 14+ (App Router)
|
|
- **Lenguaje**: TypeScript
|
|
- **Estilos**: Tailwind CSS
|
|
- **Estado**: Zustand con persistencia localStorage
|
|
- **Fechas**: date-fns
|
|
- **Gráficos**: Recharts
|
|
- **Iconos**: lucide-react
|
|
|
|
## Estructura de Directorios
|
|
```
|
|
/mnt/c/Users/Administrator/Documents/cuentas/finanzas/
|
|
├── app/ # Páginas de Next.js
|
|
├── components/ # Componentes React
|
|
│ ├── debts/ # Componentes de deudas
|
|
│ ├── cards/ # Componentes de tarjetas
|
|
│ ├── budget/ # Componentes de presupuesto
|
|
│ ├── alerts/ # Componentes de alertas
|
|
│ ├── dashboard/ # Componentes del dashboard
|
|
│ └── layout/ # Componentes de layout
|
|
├── lib/ # Utilidades y estado
|
|
│ ├── types.ts # Tipos TypeScript
|
|
│ ├── store.ts # Zustand store
|
|
│ ├── utils.ts # Helpers
|
|
│ └── alerts.ts # Lógica de alertas
|
|
├── public/ # Archivos estáticos
|
|
└── [config files]
|
|
```
|
|
|
|
## Tipos Principales
|
|
|
|
### FixedDebt
|
|
```typescript
|
|
interface FixedDebt {
|
|
id: string
|
|
name: string
|
|
amount: number
|
|
dueDay: number // 1-31
|
|
category: 'housing' | 'services' | 'subscription' | 'other'
|
|
isAutoDebit: boolean
|
|
isPaid: boolean
|
|
notes?: string
|
|
}
|
|
```
|
|
|
|
### VariableDebt
|
|
```typescript
|
|
interface VariableDebt {
|
|
id: string
|
|
name: string
|
|
amount: number
|
|
date: string // ISO date
|
|
category: 'shopping' | 'food' | 'entertainment' | 'health' | 'transport' | 'other'
|
|
isPaid: boolean
|
|
notes?: string
|
|
}
|
|
```
|
|
|
|
### CreditCard
|
|
```typescript
|
|
interface CreditCard {
|
|
id: string
|
|
name: string
|
|
lastFourDigits: string
|
|
closingDay: number // 1-31
|
|
dueDay: number // 1-31
|
|
currentBalance: number
|
|
creditLimit: number
|
|
color: string // hex color
|
|
}
|
|
```
|
|
|
|
### CardPayment
|
|
```typescript
|
|
interface CardPayment {
|
|
id: string
|
|
cardId: string
|
|
amount: number
|
|
date: string
|
|
description: string
|
|
installments?: { current: number; total: number }
|
|
}
|
|
```
|
|
|
|
### MonthlyBudget
|
|
```typescript
|
|
interface MonthlyBudget {
|
|
month: number // 1-12
|
|
year: number
|
|
totalIncome: number
|
|
fixedExpenses: number
|
|
variableExpenses: number
|
|
savingsGoal: number
|
|
}
|
|
```
|
|
|
|
### Alert
|
|
```typescript
|
|
interface Alert {
|
|
id: string
|
|
type: 'PAYMENT_DUE' | 'BUDGET_WARNING' | 'CARD_CLOSING' | 'CARD_DUE' | 'SAVINGS_GOAL' | 'UNUSUAL_SPENDING'
|
|
title: string
|
|
message: string
|
|
severity: 'info' | 'warning' | 'danger'
|
|
date: string
|
|
isRead: boolean
|
|
relatedId?: string
|
|
}
|
|
```
|
|
|
|
## Store (Zustand)
|
|
|
|
Hook: `useFinanzasStore()`
|
|
|
|
### Estado
|
|
- `fixedDebts: FixedDebt[]`
|
|
- `variableDebts: VariableDebt[]`
|
|
- `creditCards: CreditCard[]`
|
|
- `cardPayments: CardPayment[]`
|
|
- `monthlyBudgets: MonthlyBudget[]`
|
|
- `alerts: Alert[]`
|
|
- `currentMonth: number`
|
|
- `currentYear: number`
|
|
|
|
### Acciones Principales
|
|
- `addFixedDebt(debt)` / `updateFixedDebt(id, debt)` / `deleteFixedDebt(id)` / `toggleFixedDebtPaid(id)`
|
|
- `addVariableDebt(debt)` / `updateVariableDebt(id, debt)` / `deleteVariableDebt(id)` / `toggleVariableDebtPaid(id)`
|
|
- `addCreditCard(card)` / `updateCreditCard(id, card)` / `deleteCreditCard(id)`
|
|
- `addCardPayment(payment)` / `deleteCardPayment(id)`
|
|
- `setMonthlyBudget(budget)` / `updateMonthlyBudget(month, year, updates)`
|
|
- `addAlert(alert)` / `markAlertAsRead(id)` / `deleteAlert(id)` / `clearAllAlerts()`
|
|
|
|
## Paleta de Colores (Tema Oscuro)
|
|
|
|
```
|
|
Fondo principal: #0F172A (slate-900)
|
|
Cards/Superficies: #1E293B (slate-800)
|
|
Bordes: #334155 (slate-700)
|
|
Texto principal: #F8FAFC (slate-50)
|
|
Texto secundario: #94A3B8 (slate-400)
|
|
|
|
Acento positivo: #10B981 (emerald-500) // Dinero, éxito
|
|
Acento advertencia: #F59E0B (amber-500) // Alertas
|
|
Acento peligro: #EF4444 (red-500) // Urgente
|
|
Acento info: #3B82F6 (blue-500) // Información
|
|
```
|
|
|
|
## Utilidades Disponibles
|
|
|
|
### formatCurrency(amount: number): string
|
|
Formatea número como moneda argentina: `$ 1.500,50`
|
|
|
|
### formatDate(date: string | Date): string
|
|
Formato legible: "28 de enero de 2026"
|
|
|
|
### formatShortDate(date: string | Date): string
|
|
Formato corto: "28/01/2026"
|
|
|
|
### getDaysUntil(date: string | Date): number
|
|
Días hasta una fecha (negativo si ya pasó)
|
|
|
|
### getNextDateByDay(dayOfMonth: number): Date
|
|
Próxima fecha para un día específico del mes
|
|
|
|
### calculateNextClosingDate(closingDay: number): Date
|
|
Próxima fecha de cierre de tarjeta
|
|
|
|
### calculateNextDueDate(dueDay: number): Date
|
|
Próxima fecha de vencimiento
|
|
|
|
### getCardUtilization(balance: number, limit: number): number
|
|
Porcentaje de utilización de tarjeta
|
|
|
|
## Alertas Inteligentes
|
|
|
|
La función `generateAlerts()` en `/lib/alerts.ts` genera automáticamente:
|
|
|
|
1. **PAYMENT_DUE**: Deudas fijas que vencen en los próximos 3 días
|
|
2. **BUDGET_WARNING**: Gastos superan 80% del presupuesto
|
|
3. **CARD_CLOSING**: Tarjetas con cierre en próximos 3 días
|
|
4. **CARD_DUE**: Tarjetas con vencimiento en próximos 3 días
|
|
5. **SAVINGS_GOAL**: Ahorro proyectado por debajo de la meta
|
|
|
|
## Componentes Existentes
|
|
|
|
### /components/debts/
|
|
- `DebtCard.tsx` - Card individual de deuda
|
|
- `FixedDebtForm.tsx` - Formulario deuda fija
|
|
- `VariableDebtForm.tsx` - Formulario deuda variable
|
|
- `DebtSection.tsx` - Sección completa de deudas
|
|
|
|
### /components/cards/
|
|
- `CreditCardWidget.tsx` - Visualización tarjeta tipo tarjeta real
|
|
- `CreditCardForm.tsx` - Formulario tarjeta de crédito
|
|
- `CardPaymentForm.tsx` - Formulario registrar pago
|
|
- `MiniCard.tsx` - Versión compacta para selects
|
|
- `CardSection.tsx` - Sección completa de tarjetas
|
|
|
|
## Funcionalidades Requeridas
|
|
|
|
### Dashboard
|
|
- Cards de métricas (total deudas, presupuesto, ahorro)
|
|
- Lista de alertas activas
|
|
- Gráfico de distribución de gastos
|
|
- Resumen de tarjetas
|
|
|
|
### Deudas
|
|
- CRUD deudas fijas y variables
|
|
- Marcar como pagadas
|
|
- Filtros por categoría
|
|
- Indicadores visuales de vencimiento
|
|
|
|
### Tarjetas
|
|
- CRUD tarjetas de crédito
|
|
- Visualización tipo tarjeta real
|
|
- Registrar pagos
|
|
- Indicadores de cierre/vencimiento
|
|
|
|
### Presupuesto
|
|
- Configurar ingresos y metas
|
|
- Tracking de gastos vs presupuesto
|
|
- Proyecciones
|
|
|
|
### Alertas
|
|
- Generación automática basada en fechas
|
|
- Panel de alertas con severidad
|
|
- Marcar como leídas
|
|
|
|
## Patrones de Código
|
|
|
|
### Inmutabilidad (OBLIGATORIO)
|
|
```typescript
|
|
// CORRECTO
|
|
const newDebts = [...debts, newDebt]
|
|
setDebts(newDebts)
|
|
|
|
// INCORRECTO
|
|
debts.push(newDebt) // MUTACIÓN!
|
|
```
|
|
|
|
### Manejo de Estado
|
|
```typescript
|
|
const store = useFinanzasStore()
|
|
const fixedDebts = store.fixedDebts
|
|
const addDebt = store.addFixedDebt
|
|
```
|
|
|
|
### Formularios
|
|
- Validar antes de enviar
|
|
- Mostrar errores de validación
|
|
- Usar estados locales con useState
|
|
- Llamar onSubmit con datos validados
|
|
|
|
### Estilos
|
|
- Usar clases de Tailwind
|
|
- Tema oscuro por defecto
|
|
- Colores de la paleta definida
|
|
- Hover states para interactividad
|
|
|
|
## Archivos Críticos
|
|
|
|
1. `/lib/types.ts` - Todos los tipos TypeScript
|
|
2. `/lib/store.ts` - Estado global con Zustand
|
|
3. `/lib/utils.ts` - Funciones utilitarias
|
|
4. `/lib/alerts.ts` - Lógica de alertas inteligentes
|
|
|
|
## Comandos
|
|
|
|
```bash
|
|
# Desarrollo
|
|
npm run dev
|
|
|
|
# Build
|
|
npm run build
|
|
|
|
# La app se sirve estáticamente desde /dist
|
|
```
|
|
|
|
## Notas Importantes
|
|
|
|
- **Persistencia**: Todo se guarda en localStorage automáticamente
|
|
- **Sin backend**: La app funciona completamente en el cliente
|
|
- **Responsive**: Debe funcionar en móvil y desktop
|
|
- **Dark mode**: Único tema, no hay toggle de tema claro
|
|
- **Accesibilidad**: Usar labels, aria-labels, roles apropiados
|