# cartercoughlin/bloom architecture

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

- Interactive diagram: https://gitdiagram.com/cartercoughlin/bloom
- Repository: https://github.com/cartercoughlin/bloom

## Overview

Budget App is a mobile-oriented personal-finance tracker. Users authenticate, connect financial institutions through Plaid, sync balances and transactions, then categorize spending and review budgets and financial summaries. The graph also preserves the documented mobile/offline experience and the app’s subscription, tagging, and net-worth features. Several routes and feature pages are listed but unsampled; their presence is represented without inferring internal calls. Edges are limited to relationships shown in excerpts or stated in the README.

Main entry points: [`lib/supabase/server.ts`](https://github.com/cartercoughlin/bloom/blob/main/lib/supabase/server.ts) (Supabase access), [`app/api/sync-transactions/route.ts`](https://github.com/cartercoughlin/bloom/blob/main/app/api/sync-transactions/route.ts) (Transaction sync), [`app/(app)/budgets/page.tsx`](https://github.com/cartercoughlin/bloom/blob/main/app/(app)/budgets/page.tsx) (Budgets), [`app/api/net-worth-history/route.ts`](https://github.com/cartercoughlin/bloom/blob/main/app/api/net-worth-history/route.ts) (Net worth history)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_experience["App experience"]
  node_auth["Authentication<br/>[page.tsx]"]
  node_dashboard["Dashboard<br/>[page.tsx]"]
  node_transactions["Transactions<br/>[page.tsx]"]
  node_categories["Categories<br/>[page.tsx]"]
  node_accounts["Accounts<br/>[page.tsx]"]
end

subgraph group_financial_data["Financial data"]
  node_plaid_link["Bank linking<br/>[plaid-link.tsx]"]
  node_plaid_api{{"Plaid"}}
  node_transaction_sync["Transaction sync<br/>[route.ts]"]
  node_plaid_sync["Plaid sync logic<br/>[plaid-sync.ts]"]
  node_balance_api["Balance APIs<br/>[route.ts]"]
  node_supabase["Supabase access<br/>[server.ts]"]
  node_database[("Financial records")]
end

subgraph group_analysis["Budgeting and insights"]
  node_budgets["Budgets<br/>[page.tsx]"]
  node_networth["Net worth<br/>[page.tsx]"]
  node_subscriptions["Subscriptions<br/>[page.tsx]"]
  node_tags["Tags<br/>[page.tsx]"]
  node_networth_api["Net worth history<br/>[route.ts]"]
  node_networth_calc["Net worth reconstruction<br/>[reconstruct.ts]"]
  node_subscription_logic["Subscription summaries<br/>[subscriptions.ts]"]
  node_budget_logic["Budget pacing<br/>[pacing.ts]"]
end

subgraph group_platform["Mobile and caching"]
  node_app_cache["App data cache"]
  node_cached_loader["Cached data loader<br/>[use-cached-data.ts]"]
  node_capacitor["Native platform<br/>[capacitor.ts]"]
  node_pwa["Offline PWA<br/>[sw.js]"]
end

node_user(("User"))

node_user -->|"signs in"| node_auth
node_user -->|"connects account"| node_plaid_link
node_plaid_link -->|"links institution"| node_plaid_api
node_user -.->|"requests sync"| node_transaction_sync
node_transaction_sync -->|"authenticates and queries"| node_supabase
node_transaction_sync -->|"invokes sync"| node_plaid_sync
node_plaid_sync -->|"imports financial data"| node_plaid_api
node_supabase -.->|"reads and writes"| node_database
node_balance_api -->|"uses server client"| node_supabase
node_user -->|"reviews insights"| node_dashboard
node_user -->|"manages spending"| node_transactions
node_user -->|"categorizes transactions"| node_categories
node_user -->|"views accounts"| node_accounts
node_user -->|"tracks budgets"| node_budgets
node_budgets -->|"calculates pacing"| node_budget_logic
node_user -->|"reviews net worth"| node_networth
node_networth -.->|"requests history"| node_networth_api
node_networth_api -->|"loads account data"| node_supabase
node_networth_api -->|"reconstructs history"| node_networth_calc
node_user -->|"tracks subscriptions"| node_subscriptions
node_subscriptions -->|"summarizes subscriptions"| node_subscription_logic
node_user -.->|"organizes transactions"| node_tags
node_budgets -->|"loads cached data"| node_cached_loader
node_cached_loader -->|"reads and updates"| node_app_cache
node_cached_loader -->|"uses disk cache"| node_capacitor
node_user -->|"uses offline app"| node_pwa
node_user -->|"uses native app"| node_capacitor

click node_auth "https://github.com/cartercoughlin/bloom/blob/main/app/auth/login/page.tsx"
click node_dashboard "https://github.com/cartercoughlin/bloom/blob/main/app/(app)/dashboard/page.tsx"
click node_transactions "https://github.com/cartercoughlin/bloom/blob/main/app/(app)/transactions/page.tsx"
click node_categories "https://github.com/cartercoughlin/bloom/blob/main/app/(app)/categories/page.tsx"
click node_accounts "https://github.com/cartercoughlin/bloom/blob/main/app/(app)/accounts/page.tsx"
click node_budgets "https://github.com/cartercoughlin/bloom/blob/main/app/(app)/budgets/page.tsx"
click node_networth "https://github.com/cartercoughlin/bloom/blob/main/app/(app)/net-worth/page.tsx"
click node_subscriptions "https://github.com/cartercoughlin/bloom/blob/main/app/(app)/subscriptions/page.tsx"
click node_tags "https://github.com/cartercoughlin/bloom/blob/main/app/(app)/tags/page.tsx"
click node_plaid_link "https://github.com/cartercoughlin/bloom/blob/main/components/plaid-link.tsx"
click node_transaction_sync "https://github.com/cartercoughlin/bloom/blob/main/app/api/sync-transactions/route.ts"
click node_plaid_sync "https://github.com/cartercoughlin/bloom/blob/main/lib/plaid-sync.ts"
click node_balance_api "https://github.com/cartercoughlin/bloom/blob/main/app/api/account-balances/route.ts"
click node_supabase "https://github.com/cartercoughlin/bloom/blob/main/lib/supabase/server.ts"
click node_networth_api "https://github.com/cartercoughlin/bloom/blob/main/app/api/net-worth-history/route.ts"
click node_networth_calc "https://github.com/cartercoughlin/bloom/blob/main/lib/net-worth/reconstruct.ts"
click node_subscription_logic "https://github.com/cartercoughlin/bloom/blob/main/lib/subscriptions.ts"
click node_budget_logic "https://github.com/cartercoughlin/bloom/blob/main/lib/budget/pacing.ts"
click node_app_cache "https://github.com/cartercoughlin/bloom/blob/main/contexts/app-data-context.tsx"
click node_cached_loader "https://github.com/cartercoughlin/bloom/blob/main/hooks/use-cached-data.ts"
click node_capacitor "https://github.com/cartercoughlin/bloom/blob/main/lib/capacitor.ts"
click node_pwa "https://github.com/cartercoughlin/bloom/blob/main/public/sw.js"

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_auth,node_dashboard,node_transactions,node_categories,node_accounts,node_user toneBlue
class node_plaid_link,node_plaid_api,node_transaction_sync,node_plaid_sync,node_balance_api,node_supabase,node_database toneAmber
class node_budgets,node_networth,node_subscriptions,node_tags,node_networth_api,node_networth_calc,node_subscription_logic,node_budget_logic toneMint
class node_app_cache,node_cached_loader,node_capacitor,node_pwa toneRose
```

## Components

### App experience

- [Authentication](https://github.com/cartercoughlin/bloom/blob/main/app/auth/login/page.tsx): `app/auth/login/page.tsx`
- [Dashboard](https://github.com/cartercoughlin/bloom/blob/main/app/(app)/dashboard/page.tsx): `app/(app)/dashboard/page.tsx`
- [Transactions](https://github.com/cartercoughlin/bloom/blob/main/app/(app)/transactions/page.tsx): `app/(app)/transactions/page.tsx`
- [Categories](https://github.com/cartercoughlin/bloom/blob/main/app/(app)/categories/page.tsx): `app/(app)/categories/page.tsx`
- [Accounts](https://github.com/cartercoughlin/bloom/blob/main/app/(app)/accounts/page.tsx): `app/(app)/accounts/page.tsx`

### Financial data

- [Bank linking](https://github.com/cartercoughlin/bloom/blob/main/components/plaid-link.tsx): `components/plaid-link.tsx`
- **Plaid**
- [Transaction sync](https://github.com/cartercoughlin/bloom/blob/main/app/api/sync-transactions/route.ts): `app/api/sync-transactions/route.ts`
- [Plaid sync logic](https://github.com/cartercoughlin/bloom/blob/main/lib/plaid-sync.ts): `lib/plaid-sync.ts`
- [Balance APIs](https://github.com/cartercoughlin/bloom/blob/main/app/api/account-balances/route.ts): `app/api/account-balances/route.ts`
- [Supabase access](https://github.com/cartercoughlin/bloom/blob/main/lib/supabase/server.ts): `lib/supabase/server.ts`
- **Financial records**

### Budgeting and insights

- [Budgets](https://github.com/cartercoughlin/bloom/blob/main/app/(app)/budgets/page.tsx): `app/(app)/budgets/page.tsx`
- [Net worth](https://github.com/cartercoughlin/bloom/blob/main/app/(app)/net-worth/page.tsx): `app/(app)/net-worth/page.tsx`
- [Subscriptions](https://github.com/cartercoughlin/bloom/blob/main/app/(app)/subscriptions/page.tsx): `app/(app)/subscriptions/page.tsx`
- [Tags](https://github.com/cartercoughlin/bloom/blob/main/app/(app)/tags/page.tsx): `app/(app)/tags/page.tsx`
- [Net worth history](https://github.com/cartercoughlin/bloom/blob/main/app/api/net-worth-history/route.ts): `app/api/net-worth-history/route.ts`
- [Net worth reconstruction](https://github.com/cartercoughlin/bloom/blob/main/lib/net-worth/reconstruct.ts): `lib/net-worth/reconstruct.ts`
- [Subscription summaries](https://github.com/cartercoughlin/bloom/blob/main/lib/subscriptions.ts): `lib/subscriptions.ts`
- [Budget pacing](https://github.com/cartercoughlin/bloom/blob/main/lib/budget/pacing.ts): `lib/budget/pacing.ts`

### Mobile and caching

- [App data cache](https://github.com/cartercoughlin/bloom/blob/main/contexts/app-data-context.tsx): `contexts/app-data-context.tsx`
- [Cached data loader](https://github.com/cartercoughlin/bloom/blob/main/hooks/use-cached-data.ts): `hooks/use-cached-data.ts`
- [Native platform](https://github.com/cartercoughlin/bloom/blob/main/lib/capacitor.ts): `lib/capacitor.ts`
- [Offline PWA](https://github.com/cartercoughlin/bloom/blob/main/public/sw.js): `public/sw.js`

### Other components

- **User**

## Connections

- User → Authentication: signs in (evidence: `README.md`)
- User → Bank linking: connects account (evidence: `README.md`)
- Bank linking → Plaid: links institution (evidence: `README.md`)
- User → Transaction sync: requests sync
- Transaction sync → Supabase access: authenticates and queries (evidence: `app/api/sync-transactions/route.ts`)
- Transaction sync → Plaid sync logic: invokes sync (evidence: `app/api/sync-transactions/route.ts`)
- Plaid sync logic → Plaid: imports financial data (evidence: `README.md`)
- Supabase access → Financial records: reads and writes
- Balance APIs → Supabase access: uses server client (evidence: `app/api/account-balances/route.ts`)
- User → Dashboard: reviews insights (evidence: `README.md`)
- User → Transactions: manages spending (evidence: `README.md`)
- User → Categories: categorizes transactions (evidence: `README.md`)
- User → Accounts: views accounts (evidence: `README.md`)
- User → Budgets: tracks budgets (evidence: `README.md`)
- Budgets → Budget pacing: calculates pacing (evidence: `app/(app)/budgets/page.tsx`)
- User → Net worth: reviews net worth (evidence: `README.md`)
- Net worth → Net worth history: requests history
- Net worth history → Supabase access: loads account data (evidence: `app/api/net-worth-history/route.ts`)
- Net worth history → Net worth reconstruction: reconstructs history (evidence: `app/api/net-worth-history/route.ts`)
- User → Subscriptions: tracks subscriptions (evidence: `README.md`)
- Subscriptions → Subscription summaries: summarizes subscriptions (evidence: `app/(app)/subscriptions/page.tsx`)
- User → Tags: organizes transactions
- Budgets → Cached data loader: loads cached data (evidence: `app/(app)/budgets/page.tsx`)
- Cached data loader → App data cache: reads and updates (evidence: `hooks/use-cached-data.ts`)
- Cached data loader → Native platform: uses disk cache (evidence: `hooks/use-cached-data.ts`)
- User → Offline PWA: uses offline app (evidence: `README.md`)
- User → Native platform: uses native app (evidence: `README.md`)
