# ferxodj/cash-flow-supabase architecture

> Architecture diagram of the GitHub repository ferxodj/cash-flow-supabase, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ferxodj/cash-flow-supabase
- Repository: https://github.com/ferxodj/cash-flow-supabase

## Overview

1. This is a single Next.js App Router application that serves both the UI and the backend. The repository is organized around `app/`, with pages, layouts, client components, and a large set of server `route.ts` handlers under `app/api/`.

2. The UI is split into two major product modes:
   - `home_finanzas_solo` for personal finances.
   - `home_finanzas_parejas` for shared/couple finances.
   These have their own shells, sidebars, dashboards, charts, and section pages, so the architecture is intentionally domain-separated at the route and component level.

3. The public/auth surfaces are small but important: landing pages, a not-authenticated screen, auth callback handling, password reset, and couple invitation acceptance/rejection flows. The repo also has dedicated routes for login/logout/me and OAuth/session management.

4. The backend is mostly API-first. The `app/api/` tree exposes CRUD and summary endpoints for finance entities such as incomes, savings, debts, investments, budget categories, fx losses, user preferences/goals, and profile data. Many endpoints are grouped by domain, with nested routes for actions like withdraw, revert, analytics, monthly summaries, and item-by-id operations.

5. There are two data domains with different boundaries:
   - Solo finances: incomes, savings, investments, budget distribution, losses, profile, and personal analytics.
   - Couple finances: invite/accept/reject lifecycle, shared views, annual panel, combined net summary, shared budget, debts, and notification management.
   This is the main architectural split in the app.

6. Persistence is backed by Supabase. The repo includes `app/lib/supabase.ts` for client access and `app/lib/supabaseAdmin.ts` for privileged server-side operations, plus SQL schema files in `supabase/`. That suggests the app uses Supabase Postgres as the system of record, with some routes requiring elevated access for administrative actions or password/email flows.

7. Authentication and authorization are handled across the app by session utilities and middleware. The presence of `middleware.ts`, `app/lib/session.ts`, and the session/profile routes indicates route protection, user identity propagation, and request-time access checks are central to the architecture.

8. Notifications are a first-class backend subsystem. Debt alerts are sent through `app/api/debts/notify` and `app/api/cron/debts-notify`, with the README describing Vercel Cron integration and anti-spam tracking via a notifications table. Email delivery is abstracted behind `app/lib/mailer.ts`.

9. Reporting and analytics are implemented as server-backed summary endpoints plus client chart components. Examples include annual panels, net summary, monthly income/savings views, investment analytics, and budget distribution charts. The UI generally fetches aggregated data from API routes rather than computing everything client-side.

10. There is also a data export path: `app/api/export/csv` produces CSV output from financial data, which means the backend exposes a reporting boundary separate from the dashboard views.

11. Shared UI infrastructure lives in `app/components/` and the various `lib/` helpers. These include global loading, headers, access inputs/cards, fetch-header installers, and navigation blockers, which support the app shell and cross-cutting UX behavior rather than a single business domain.

12. Deployment/runtime assumptions matter here: the app is designed for Vercel, with cron support declared in `vercel.ts` and environment variables for Supabase, session secrets, cron authorization, and optional mail/reset flows. The repo is therefore a serverless Next.js app with Supabase as the main backend service and Vercel as the hosting/scheduling layer.

Main entry points: [`app/api/couple/invite/route.ts`](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/couple/invite/route.ts) (Couple finance API), [`app/page.tsx`](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/page.tsx) (App root), [`app/api/debts/notify/route.ts`](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/debts/notify/route.ts) (Notifications), [`app/home_finanzas_solo/page.tsx`](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_solo/page.tsx) (Solo mode)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ui["UI routes"]
  node_root["App root<br/>Next app<br/>[page.tsx]"]
  node_landing["Public pages<br/>Public/auth<br/>[page.tsx]"]
  node_solo["Solo mode<br/>Personal finance UI<br/>[page.tsx]"]
  node_couple["Couple mode<br/>Shared finance UI<br/>[page.tsx]"]
  node_solo_shell["Solo shell<br/>Layout shell<br/>[HomeSoloShell.tsx]"]
  node_couple_shell["Couple shell<br/>Layout shell"]
  node_solo_dash["Solo dashboards<br/>Views<br/>[page.tsx]"]
  node_couple_dash["Couple dashboards<br/>Views<br/>[page.tsx]"]
  node_public_couple["Couple invite flow<br/>Invite screens<br/>[page.tsx]"]
end

subgraph group_api["API routes"]
  node_session_api["Session API<br/>Auth/session<br/>[route.ts]"]
  node_profile_api["Profile API<br/>User account<br/>[route.ts]"]
  node_solo_api["Solo finance API<br/>Personal finance<br/>[route.ts]"]
  node_couple_api["Couple finance API<br/>Shared finance<br/>[route.ts]"]
  node_notify_api["Notifications<br/>Debt alerts<br/>[route.ts]"]
end

subgraph group_shared["Shared infra"]
  node_supabase_client[("Supabase client<br/>DB client<br/>[supabase.ts]")]
  node_supabase_admin[("Supabase admin<br/>Privileged DB<br/>[supabaseAdmin.ts]")]
  node_session_lib["Session utils<br/>Auth guards<br/>[session.ts]"]
  node_mailer["Mailer<br/>Email delivery<br/>[mailer.ts]"]
end

subgraph group_data["Data/runtime"]
  node_schemas["Supabase SQL<br/>Postgres schema<br/>[finanzas.sql]"]
  node_runtime["Vercel runtime<br/>Hosting/cron<br/>[vercel.ts]"]
end

node_root -->|"routes"| node_landing
node_root -->|"routes"| node_solo
node_root -->|"routes"| node_couple
node_solo -->|"uses"| node_solo_shell
node_couple -->|"uses"| node_couple_shell
node_solo -->|"contains"| node_solo_dash
node_couple -->|"contains"| node_couple_dash
node_public_couple -->|"invites"| node_couple_api
node_session_api -->|"uses"| node_session_lib
node_profile_api -->|"uses"| node_session_lib
node_solo_api -->|"reads/writes"| node_supabase_client
node_couple_api -->|"reads/writes"| node_supabase_client
node_profile_api -->|"privileged"| node_supabase_admin
node_notify_api -->|"checks"| node_supabase_admin
node_notify_api -->|"sends"| node_mailer
node_solo_api -->|"persists"| node_schemas
node_couple_api -->|"persists"| node_schemas
node_session_api -->|"runs on"| node_runtime
node_notify_api -->|"scheduled by"| node_runtime
node_landing -->|"auth"| node_session_api
node_solo_dash -->|"fetches"| node_solo_api
node_couple_dash -->|"fetches"| node_couple_api

click node_root "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/page.tsx"
click node_landing "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/no_autenticado/page.tsx"
click node_solo "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_solo/page.tsx"
click node_couple "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_parejas/page.tsx"
click node_solo_shell "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_solo/components/HomeSoloShell.tsx"
click node_couple_shell "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_parejas/components/HomeParejasShell.tsx"
click node_solo_dash "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_solo/panel_anual/page.tsx"
click node_couple_dash "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_parejas/panel_anual/page.tsx"
click node_public_couple "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/pareja/aceptar/page.tsx"
click node_session_api "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/session/login/route.ts"
click node_profile_api "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/profile/me/route.ts"
click node_solo_api "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/incomes/route.ts"
click node_couple_api "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/couple/invite/route.ts"
click node_notify_api "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/debts/notify/route.ts"
click node_supabase_client "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/lib/supabase.ts"
click node_supabase_admin "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/lib/supabaseAdmin.ts"
click node_session_lib "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/lib/session.ts"
click node_mailer "https://github.com/ferxodj/cash-flow-supabase/blob/main/app/lib/mailer.ts"
click node_schemas "https://github.com/ferxodj/cash-flow-supabase/blob/main/supabase/finanzas.sql"
click node_runtime "https://github.com/ferxodj/cash-flow-supabase/blob/main/vercel.ts"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_root,node_landing,node_solo,node_couple,node_solo_shell,node_couple_shell,node_solo_dash,node_couple_dash,node_public_couple toneBlue
class node_session_api,node_profile_api,node_solo_api,node_couple_api,node_notify_api toneAmber
class node_supabase_client,node_supabase_admin,node_session_lib,node_mailer toneMint
class node_schemas,node_runtime toneRose
```

## Components

### UI routes

Public pages and the two finance product modes

- [App root](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/page.tsx): Next app · Top-level App Router entrypoint and route composition · `app/page.tsx`
- [Public pages](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/no_autenticado/page.tsx): Public/auth · Landing, unauthenticated, auth callback, and password reset surfaces · `app/no_autenticado/page.tsx`
- [Solo mode](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_solo/page.tsx): Personal finance UI · Standalone personal-finance shell and route set · `app/home_finanzas_solo/page.tsx`
- [Couple mode](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_parejas/page.tsx): Shared finance UI · Shared/couple-finance shell and route set · `app/home_finanzas_parejas/page.tsx`
- [Solo shell](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_solo/components/HomeSoloShell.tsx): Layout shell · Sidebar and layout wrapper for personal-finance views · `app/home_finanzas_solo/components/HomeSoloShell.tsx`
- [Couple shell](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_parejas/components/HomeParejasShell.tsx): Layout shell · Sidebar and layout wrapper for couple-finance views · `app/home_finanzas_parejas/components/HomeParejasShell.tsx`
- [Solo dashboards](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_solo/panel_anual/page.tsx): Views · Annual panel, savings, investments, budget, transactions, and profile screens · `app/home_finanzas_solo/panel_anual/page.tsx`
- [Couple dashboards](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/home_finanzas_parejas/panel_anual/page.tsx): Views · Annual panel, savings, debts, investments, budget, notifications, and profile screens · `app/home_finanzas_parejas/panel_anual/page.tsx`
- [Couple invite flow](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/pareja/aceptar/page.tsx): Invite screens · Accept/reject invitation and registration-linked couple flows · `app/pareja/aceptar/page.tsx`

### API routes

Server-side endpoints grouped by domain

- [Session API](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/session/login/route.ts): Auth/session · Login, logout, me, and OAuth session endpoints · `app/api/session/login/route.ts`
- [Profile API](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/profile/me/route.ts): User account · Profile read/update, password, and email-change endpoints · `app/api/profile/me/route.ts`
- [Solo finance API](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/incomes/route.ts): Personal finance · Incomes, savings, investments, budget 50/30/20, FX losses, goals, preferences, and exports · `app/api/incomes/route.ts`
- [Couple finance API](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/couple/invite/route.ts): Shared finance · Couple invite lifecycle, shared views, annual panel, net summary, notifications, and shared budgets/debts · `app/api/couple/invite/route.ts`
- [Notifications](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/api/debts/notify/route.ts): Debt alerts · Debt notification endpoint and cron-driven notification job · `app/api/debts/notify/route.ts`

### Shared infra

Cross-cutting components and server helpers

- [Supabase client](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/lib/supabase.ts): DB client · Browser/server Supabase access helper · `app/lib/supabase.ts`
- [Supabase admin](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/lib/supabaseAdmin.ts): Privileged DB · Server-only elevated Supabase helper for protected flows · `app/lib/supabaseAdmin.ts`
- [Session utils](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/lib/session.ts): Auth guards · Session propagation, request-time checks, and middleware support · `app/lib/session.ts`
- [Mailer](https://github.com/ferxodj/cash-flow-supabase/blob/main/app/lib/mailer.ts): Email delivery · Email transport used by password reset, invitations, and account flows · `app/lib/mailer.ts`

### Data/runtime

Persistence schema and deployment/runtime config

- [Supabase SQL](https://github.com/ferxodj/cash-flow-supabase/blob/main/supabase/finanzas.sql): Postgres schema · Database schema and seed/migration SQL for the finance domains · `supabase/finanzas.sql`
- [Vercel runtime](https://github.com/ferxodj/cash-flow-supabase/blob/main/vercel.ts): Hosting/cron · Deployment, environment variables, and scheduled cron execution · `vercel.ts`

## Connections

- App root → Public pages: routes · App-level public entrypoints
- App root → Solo mode: routes · Personal-finance product area
- App root → Couple mode: routes · Shared-finance product area
- Solo mode → Solo shell: uses · Solo views render within the personal shell
- Couple mode → Couple shell: uses · Couple views render within the shared shell
- Solo mode → Solo dashboards: contains · Solo mode sections and dashboards
- Couple mode → Couple dashboards: contains · Couple mode sections and dashboards
- Couple invite flow → Couple finance API: invites · Invitation acceptance/rejection is backed by couple APIs
- Session API → Session utils: uses · Session routes depend on shared auth/session helpers
- Profile API → Session utils: uses · Account operations are protected by session checks
- Solo finance API → Supabase client: reads/writes · Personal-finance endpoints access database data
- Couple finance API → Supabase client: reads/writes · Shared-finance endpoints access database data
- Profile API → Supabase admin: privileged · Email/password/profile flows may need elevated access
- Notifications → Supabase admin: checks · Notification anti-spam and job actions use server privileges
- Notifications → Mailer: sends · Debt alerts are delivered by email
- Solo finance API → Supabase SQL: persists · Solo finance data is stored in Supabase Postgres
- Couple finance API → Supabase SQL: persists · Couple finance data is stored in Supabase Postgres
- Session API → Vercel runtime: runs on · Auth and cron flows are deployed on Vercel
- Notifications → Vercel runtime: scheduled by · Debt notification checks are cron-triggered
- Public pages → Session API: auth · Public surfaces connect into session management
- Solo dashboards → Solo finance API: fetches · Solo dashboards consume aggregated API data
- Couple dashboards → Couple finance API: fetches · Couple dashboards consume aggregated API data
