App de finanzas del hogar para dos personas: cada quien entra con su propia cuenta, pero ambos comparten un mismo "hogar" con transacciones, presupuesto, deudas, metas de ahorro, inversiones y facturas recurrentes. Los montos se cifran en el dispositivo antes de guardarse.
- Cuentas, categorías, transacciones y transferencias entre cuentas
- Presupuesto mensual por categoría y resumen anual
- Deudas con método de pago avalancha, metas de ahorro y reto de ahorro
- Inversiones y facturas recurrentes
- Notas del mes, exportar reporte (PDF/CSV)
- Notificaciones in-app y push (recordatorios diarios/semanales, pagos de deuda, actividad de la pareja)
- Hogar compartido entre 2 personas: se une por código de invitación
- Flutter (Material 3) + Riverpod para estado (MVVM ligero por feature)
- Firebase: Auth (email/password + Google), Cloud Firestore, Cloud Messaging
- Cloudflare Workers para el envío de push server-side y recordatorios programados por cron (cada envío se autentica con el ID token de Firebase del usuario; no hay secreto en la app)
- fl_chart para gráficas, intl para formato de moneda/fecha
- Tipografía de marca: Plus Jakarta Sans (empaquetada localmente)
lib/
├── core/
│ ├── theme/ # Finan2Theme, paleta, tipografía
│ ├── crypto/ # HouseholdCrypto - cifrado AES-GCM de montos
│ ├── widgets/ # Finan2* widgets compartidos (bottom sheets, splash, etc.)
│ ├── notifications/ # Notificaciones locales (flutter_local_notifications)
│ ├── pwa/ # Soporte de instalación/persistencia para el target web
│ └── utils/ # incl. error_messages.dart (errores -> mensajes en español)
└── features/
├── auth/
├── household/
├── accounts/
├── categories/
├── transactions/
├── dashboard/
├── budget/
├── debts/
├── savings_goals/
├── savings_challenge/
├── investments/
├── recurring_bills/
├── transfers/
├── monthly_notes/
├── annual_summary/
├── notifications/
├── notification_prefs/
├── export/
└── settings/
Cada feature se organiza como data/ (modelos + repositorios Firestore) y presentation/
(viewmodels/ + screens/). Todas las modales de la app son bottom sheets, nunca AlertDialog
centrado (lib/core/widgets/finan2_bottom_sheet.dart).
Otras carpetas en la raíz del repo:
docs/ # sitio público (GitHub Pages): landing, política de privacidad, términos
design-archive/ # mockups de diseño (no públicos): rediseno-app.html es la referencia; diseno-app.html, el diseño anterior archivado
cloudflare/ # Worker de notificaciones push + recordatorios programados
store/ # metadata de tienda (política de privacidad, ficha de App Store)
android/fastlane/ # metadata de Play Store
Los campos monetarios (amount, balance, targetAmount, etc. — no nombres ni
descripciones) se cifran con AES-256-GCM (lib/core/crypto/household_crypto.dart) antes de
escribirse a Firestore. La llave se genera en el dispositivo al crear un hogar, viaja pegada al
código de invitación (INVITACION.llave) y se guarda localmente con flutter_secure_storage
(Keychain/Keystore).
La única copia que llega a Firestore es la de respaldo, cifrada con la frase de recuperación del hogar: 12 palabras (128 bits aleatorios, codificación BIP39 sobre la lista en español) que la app genera, muestra una vez y no guarda. Con 128 bits no hay barrido offline posible, así que ni con acceso admin al proyecto de Firebase/GCP se pueden leer los montos sin la llave o la frase.
Las invitaciones son códigos de 10 caracteres, de un solo uso y con vencimiento de 7 días, separados del ID del hogar. Un hogar solo lo pueden leer sus miembros.
Nombres, descripciones y notas de texto no están cifrados en esta versión.
flutter pub get
flutter run
Para builds web con push, incluir los dart-defines (la clave VAPID de FCM):
flutter run --dart-define-from-file=.secrets/dart-defines.json
Proyecto: finan2 (región de Firestore: southamerica-east1), configurado con
flutterfire configure. Proveedores Email/Password y Google habilitados en
Authentication.
flutter analyze
flutter test