Volver a proyectos
Caso de estudio
1 de abril de 202612 min de lectura

Kuenta (MyMoney)

Aplicación web para gestionar dinero por períodos: onboarding, mes en curso, movimientos, ahorros y cierre. Este artículo resume arquitectura, autenticación, datos y cómo se conectan el frontend Next.js y el API .NET.

Next.js.NET 8DDDFirebasePostgreSQLBFF

Plantilla: el contenido por idioma vive en `projectCases.es.ts` y `projectCases.en.ts`. Añade una entrada en `projectCaseDefinitions` en `projectCases.ts` y enlázala desde `ProjectsSection` con `detailPath: "/project/tu-slug"`.

Resumen del producto

Kuenta es la marca del producto; el código del frontend se organiza en el repo my-money (Next.js) y el negocio y persistencia en mymoney-service (.NET, DDD). El cliente no llama al API .NET directamente desde el navegador: pasa por rutas API de Next que actúan como BFF (Backend for Frontend) y reenvían la petición con el token adecuado.


Stack principal

  • Frontend: Next.js (App Router), React, Tailwind, Redux Toolkit + redux-persist (auth), Firebase Auth en cliente.
  • Backend: .NET 8, API REST, validación de JWT de Firebase, EF Core, PostgreSQL, Redis.
  • Infra local: Docker Compose con PostgreSQL y Redis (puertos y credenciales según README del servicio).

Autenticación

En el navegador

El usuario inicia sesión con Firebase Authentication. Las credenciales públicas del proyecto Firebase viven en variables `NEXT_PUBLIC_FIREBASE_*`. El estado de sesión se integra con Redux (persistencia orientada a auth donde aplique).

BFF y cookie de sesión

Next expone rutas bajo `/api/auth/*` y `/api/backend/*`. El cliente HTTP del front apunta al BFF (`/api/backend/...`) con credenciales incluidas para que el servidor Next pueda adjuntar o refrescar el contexto de sesión sin exponer secretos al browser.

En el API .NET

El backend acepta el JWT de Firebase (header `Authorization: Bearer <token>`). Tras el login/registro, puede escribir custom claims (`user_id`, `role`, `onboarding_completed`) y devolver un `firebaseCustomToken` para intercambiarlo con `signInWithCustomToken` y obtener un ID token actualizado; si no hay token en la respuesta, el cliente usa `getIdToken(true)` para forzar refresco.

Firebase Admin en el servicio se configura vía `appsettings` (`FirebaseConfiguration`) o variable `FIREBASE_CREDENTIALS_JSON` con el JSON de cuenta de servicio.


Bases de datos y caché

PostgreSQL es la base principal (EF Core, migraciones al arranque vía `DatabaseMigrator`). Redis se usa según la configuración de conexión del servicio. En desarrollo local, Docker Compose levanta ambos con usuarios y puertos documentados en el README del API.

  • Dominios expuestos: onboarding, mymonth (período, transacciones, breakdowns), savings, dashboard, auth.
  • MyMonth y el módulo de savings independiente conviven: movimientos de período vs. tabla `savings_moves` sin `period_id` (ver README del servicio para el detalle).

Arquitectura del backend

El servicio sigue DDD en capas: Domain (entidades, value objects, interfaces sin dependencias externas), Application (casos de uso, DTOs), Infrastructure (EF Core, repositorios, Redis, integraciones) y Api (controladores, middleware, Swagger, DI).

text
┌─────────────────────────────────────────┐
│  MyMoney.Api (Controllers, middleware)   │
└─────────────────┬───────────────────────┘
                  │ usa
                  ▼
┌─────────────────────────────────────────┐
│  MyMoney.Application (servicios, DTOs)  │
└─────────────────┬───────────────────────┘
                  │ usa
                  ▼
┌─────────────────────────────────────────┐
│  MyMoney.Domain (núcleo, sin frameworks)│
└─────────────────────────────────────────┘
                  ▲
                  │ implementa
┌─────────────────┴───────────────────────┐
│  MyMoney.Infrastructure                 │
└─────────────────────────────────────────┘

`Program.cs` delega en extensiones: registro de servicios (`AddApiServices`, `AddMyMoneyLayers`) y pipeline (`ConfigureMiddleware`, `ConfigureEndpoints`), manteniendo el entry point legible.


Arquitectura del frontend

  • `src/app/`: rutas, layouts, rutas API del BFF.
  • `src/features/`: módulos por dominio (dashboard, onboarding, my-month, savings, etc.).
  • `src/Redux/features/`: slices y thunks alineados con esos dominios.
  • `src/services/`: cliente al BFF y flujos que completan login Firebase + sesión.

Hay trabajo explícito de SEO técnico: sitemap, robots, metadata y JSON-LD en layout, imágenes OG, y archivos `llms.txt` para contexto a agentes — rutas autenticadas con `noindex` donde corresponde.


Conexión extremo a extremo

text
Navegador ──► Next.js (páginas + /api/backend/*)
                    │
                    │  BACKEND_API_URL (solo servidor)
                    ▼
               API .NET ──► PostgreSQL / Redis

`BACKEND_API_URL` en el entorno de Next apunta al origen del API .NET; esa variable no sustituye la autenticación: el flujo de tokens sigue siendo Firebase + validación en el servicio.


Repositorios y demo