# tofi-app/tofi architecture

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

- Interactive diagram: https://gitdiagram.com/tofi-app/tofi
- Repository: https://github.com/tofi-app/tofi

## Overview

ToFi is a personal budgeting app: users sign in, link financial accounts, review and categorize transactions, set budgets, and follow household cash flow, reimbursements, net worth, and investments. Mobile screens and hooks drive authenticated tRPC requests; the backend handles Plaid access and user-defined metadata, while raw Plaid financial data is relayed to the device rather than persisted server-side. Apple FinanceKit provides a separate on-device account-sync path. Evidence is limited to the README, tree, and sampled excerpts; unsampled subsystem links are included only where documented capabilities support them.

Main entry points: [`frontend/app/(tabs)/index.tsx`](https://github.com/tofi-app/tofi/blob/main/frontend/app/(tabs)/index.tsx) (Finance screens), [`backend/src/trpc/router.ts`](https://github.com/tofi-app/tofi/blob/main/backend/src/trpc/router.ts) (tRPC procedures), [`backend/src/repositories`](https://github.com/tofi-app/tofi/tree/main/backend/src/repositories) (Domain repositories), [`frontend/lib/financekit/syncEngine.ts`](https://github.com/tofi-app/tofi/blob/main/frontend/lib/financekit/syncEngine.ts) (Apple account sync)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_mobile["Mobile experience"]
  node_app["App routing<br/>[_layout.tsx]"]
  node_auth["Sign-in<br/>[login.tsx]"]
  node_onboarding["Onboarding<br/>[index.tsx]"]
  node_screens["Finance screens<br/>[index.tsx]"]
  node_api["Authenticated API client<br/>[client.ts]"]
end

subgraph group_ingestion["Account ingestion"]
  node_linkhook["Plaid Link flow<br/>[useLinkSession.ts]"]
  node_linksession["Plaid Link session"]
  node_financekit["Apple account sync<br/>[syncEngine.ts]"]
end

subgraph group_finance["Financial insights"]
  node_feed["Transaction feed"]
  node_budget["Budget tracking<br/>[useBudgets.ts]"]
  node_cashflow["Cash flow<br/>[householdFlow.ts]"]
  node_networth["Net worth<br/>[netWorth.ts]"]
  node_investmentview["Investment views<br/>[HoldingRows.tsx]"]
end

subgraph group_backend["Backend API"]
  node_server["Fastify server<br/>[server.ts]"]
  node_trpc["tRPC procedures<br/>[router.ts]"]
  node_plaidlink["Plaid link service"]
  node_transactions["Transaction routes<br/>[transactions.ts]"]
  node_budgets["Budget routes<br/>[budgets.ts]"]
  node_investments["Investment routes<br/>[investments.ts]"]
  node_repositories["Domain repositories"]
end

subgraph group_services["Storage and providers"]
  node_database[("Metadata database<br/>[client.ts]")]
  node_plaid{{"Plaid API"}}
  node_supabase{{"Supabase Auth<br/>[auth.ts]"}}
  node_financekitprovider{{"Apple FinanceKit"}}
  node_cache[("On-device cache<br/>[store.ts]")]
end

node_user(("App user"))

node_user -->|"opens"| node_app
node_app -->|"routes unauthenticated"| node_auth
node_app -->|"routes signed-in"| node_onboarding
node_auth -->|"authenticates"| node_supabase
node_onboarding -->|"starts linking"| node_linkhook
node_screens -->|"requests connection"| node_linkhook
node_linkhook -->|"requests link token"| node_api
node_linkhook -->|"opens Link"| node_linksession
node_linksession -->|"links account"| node_plaid
node_api -->|"sends authenticated tRPC"| node_server
node_server -->|"dispatches procedures"| node_trpc
node_trpc -->|"dispatches link calls"| node_plaidlink
node_trpc -->|"dispatches transaction calls"| node_transactions
node_trpc -->|"dispatches budget calls"| node_budgets
node_trpc -->|"dispatches investment calls"| node_investments
node_plaidlink -->|"creates and exchanges tokens"| node_plaid
node_plaidlink -->|"stores connection metadata"| node_repositories
node_transactions -->|"fetches financial data"| node_plaid
node_transactions -->|"reads and writes metadata"| node_repositories
node_budgets -->|"reads and writes budgets"| node_repositories
node_investments -->|"fetches holdings and activity"| node_plaid
node_investments -->|"reads connection metadata"| node_repositories
node_repositories -->|"persists user metadata"| node_database
node_transactions -->|"returns transaction data"| node_feed
node_budgets -->|"returns budget data"| node_budget
node_investments -->|"returns investment data"| node_investmentview
node_feed -->|"renders transactions"| node_screens
node_budget -->|"renders budgets"| node_screens
node_screens -->|"builds household view"| node_cashflow
node_screens -->|"builds net worth view"| node_networth
node_user -->|"grants account access"| node_financekit
node_financekit -->|"reads accounts and activity"| node_financekitprovider
node_financekit -->|"merges synced transactions"| node_cache
node_financekit -->|"provides account data"| node_screens

click node_app "https://github.com/tofi-app/tofi/blob/main/frontend/app/_layout.tsx"
click node_auth "https://github.com/tofi-app/tofi/blob/main/frontend/app/(auth)/login.tsx"
click node_onboarding "https://github.com/tofi-app/tofi/blob/main/frontend/app/onboarding/index.tsx"
click node_screens "https://github.com/tofi-app/tofi/blob/main/frontend/app/(tabs)/index.tsx"
click node_linkhook "https://github.com/tofi-app/tofi/blob/main/frontend/hooks/useLinkSession.ts"
click node_linksession "https://github.com/tofi-app/tofi/blob/main/frontend/lib/plaid/createLinkSession.ts"
click node_financekit "https://github.com/tofi-app/tofi/blob/main/frontend/lib/financekit/syncEngine.ts"
click node_feed "https://github.com/tofi-app/tofi/blob/main/frontend/hooks/useTransactionFeed.ts"
click node_budget "https://github.com/tofi-app/tofi/blob/main/frontend/hooks/useBudgets.ts"
click node_cashflow "https://github.com/tofi-app/tofi/blob/main/frontend/lib/cashflow/householdFlow.ts"
click node_networth "https://github.com/tofi-app/tofi/blob/main/frontend/lib/accounts/netWorth.ts"
click node_investmentview "https://github.com/tofi-app/tofi/blob/main/frontend/components/accounts/HoldingRows.tsx"
click node_api "https://github.com/tofi-app/tofi/blob/main/frontend/lib/api/client.ts"
click node_server "https://github.com/tofi-app/tofi/blob/main/backend/src/server.ts"
click node_trpc "https://github.com/tofi-app/tofi/blob/main/backend/src/trpc/router.ts"
click node_plaidlink "https://github.com/tofi-app/tofi/blob/main/backend/src/services/plaidLinkService.ts"
click node_transactions "https://github.com/tofi-app/tofi/blob/main/backend/src/routers/transactions.ts"
click node_budgets "https://github.com/tofi-app/tofi/blob/main/backend/src/routers/budgets.ts"
click node_investments "https://github.com/tofi-app/tofi/blob/main/backend/src/routers/investments.ts"
click node_repositories "https://github.com/tofi-app/tofi/tree/main/backend/src/repositories"
click node_database "https://github.com/tofi-app/tofi/blob/main/backend/src/lib/db/client.ts"
click node_supabase "https://github.com/tofi-app/tofi/blob/main/frontend/lib/supabase/auth.ts"
click node_cache "https://github.com/tofi-app/tofi/blob/main/frontend/lib/financekit/store.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_app,node_auth,node_onboarding,node_screens,node_api,node_user toneBlue
class node_linkhook,node_linksession,node_financekit toneAmber
class node_feed,node_budget,node_cashflow,node_networth,node_investmentview toneMint
class node_server,node_trpc,node_plaidlink,node_transactions,node_budgets,node_investments,node_repositories toneRose
class node_database,node_plaid,node_supabase,node_financekitprovider,node_cache toneIndigo
```

## Components

### Mobile experience

- [App routing](https://github.com/tofi-app/tofi/blob/main/frontend/app/_layout.tsx): `frontend/app/_layout.tsx`
- [Sign-in](https://github.com/tofi-app/tofi/blob/main/frontend/app/(auth)/login.tsx): `frontend/app/(auth)/login.tsx`
- [Onboarding](https://github.com/tofi-app/tofi/blob/main/frontend/app/onboarding/index.tsx): `frontend/app/onboarding/index.tsx`
- [Finance screens](https://github.com/tofi-app/tofi/blob/main/frontend/app/(tabs)/index.tsx): `frontend/app/(tabs)/index.tsx`
- [Authenticated API client](https://github.com/tofi-app/tofi/blob/main/frontend/lib/api/client.ts): `frontend/lib/api/client.ts`

### Account ingestion

- [Plaid Link flow](https://github.com/tofi-app/tofi/blob/main/frontend/hooks/useLinkSession.ts): `frontend/hooks/useLinkSession.ts`
- [Plaid Link session](https://github.com/tofi-app/tofi/blob/main/frontend/lib/plaid/createLinkSession.ts): `frontend/lib/plaid/createLinkSession.ts`
- [Apple account sync](https://github.com/tofi-app/tofi/blob/main/frontend/lib/financekit/syncEngine.ts): `frontend/lib/financekit/syncEngine.ts`

### Financial insights

- [Transaction feed](https://github.com/tofi-app/tofi/blob/main/frontend/hooks/useTransactionFeed.ts): `frontend/hooks/useTransactionFeed.ts`
- [Budget tracking](https://github.com/tofi-app/tofi/blob/main/frontend/hooks/useBudgets.ts): `frontend/hooks/useBudgets.ts`
- [Cash flow](https://github.com/tofi-app/tofi/blob/main/frontend/lib/cashflow/householdFlow.ts): `frontend/lib/cashflow/householdFlow.ts`
- [Net worth](https://github.com/tofi-app/tofi/blob/main/frontend/lib/accounts/netWorth.ts): `frontend/lib/accounts/netWorth.ts`
- [Investment views](https://github.com/tofi-app/tofi/blob/main/frontend/components/accounts/HoldingRows.tsx): `frontend/components/accounts/HoldingRows.tsx`

### Backend API

- [Fastify server](https://github.com/tofi-app/tofi/blob/main/backend/src/server.ts): `backend/src/server.ts`
- [tRPC procedures](https://github.com/tofi-app/tofi/blob/main/backend/src/trpc/router.ts): `backend/src/trpc/router.ts`
- [Plaid link service](https://github.com/tofi-app/tofi/blob/main/backend/src/services/plaidLinkService.ts): `backend/src/services/plaidLinkService.ts`
- [Transaction routes](https://github.com/tofi-app/tofi/blob/main/backend/src/routers/transactions.ts): `backend/src/routers/transactions.ts`
- [Budget routes](https://github.com/tofi-app/tofi/blob/main/backend/src/routers/budgets.ts): `backend/src/routers/budgets.ts`
- [Investment routes](https://github.com/tofi-app/tofi/blob/main/backend/src/routers/investments.ts): `backend/src/routers/investments.ts`
- [Domain repositories](https://github.com/tofi-app/tofi/tree/main/backend/src/repositories): `backend/src/repositories`

### Storage and providers

- [Metadata database](https://github.com/tofi-app/tofi/blob/main/backend/src/lib/db/client.ts): `backend/src/lib/db/client.ts`
- **Plaid API**
- [Supabase Auth](https://github.com/tofi-app/tofi/blob/main/frontend/lib/supabase/auth.ts): `frontend/lib/supabase/auth.ts`
- **Apple FinanceKit**
- [On-device cache](https://github.com/tofi-app/tofi/blob/main/frontend/lib/financekit/store.ts): `frontend/lib/financekit/store.ts`

### Other components

- **App user**

## Connections

- App user → App routing: opens
- App routing → Sign-in: routes unauthenticated
- App routing → Onboarding: routes signed-in
- Sign-in → Supabase Auth: authenticates
- Onboarding → Plaid Link flow: starts linking
- Finance screens → Plaid Link flow: requests connection
- Plaid Link flow → Authenticated API client: requests link token
- Plaid Link flow → Plaid Link session: opens Link
- Plaid Link session → Plaid API: links account
- Authenticated API client → Fastify server: sends authenticated tRPC
- Fastify server → tRPC procedures: dispatches procedures
- tRPC procedures → Plaid link service: dispatches link calls
- tRPC procedures → Transaction routes: dispatches transaction calls
- tRPC procedures → Budget routes: dispatches budget calls
- tRPC procedures → Investment routes: dispatches investment calls
- Plaid link service → Plaid API: creates and exchanges tokens
- Plaid link service → Domain repositories: stores connection metadata
- Transaction routes → Plaid API: fetches financial data
- Transaction routes → Domain repositories: reads and writes metadata
- Budget routes → Domain repositories: reads and writes budgets
- Investment routes → Plaid API: fetches holdings and activity
- Investment routes → Domain repositories: reads connection metadata
- Domain repositories → Metadata database: persists user metadata
- Transaction routes → Transaction feed: returns transaction data
- Budget routes → Budget tracking: returns budget data
- Investment routes → Investment views: returns investment data
- Transaction feed → Finance screens: renders transactions
- Budget tracking → Finance screens: renders budgets
- Finance screens → Cash flow: builds household view
- Finance screens → Net worth: builds net worth view
- App user → Apple account sync: grants account access
- Apple account sync → Apple FinanceKit: reads accounts and activity
- Apple account sync → On-device cache: merges synced transactions
- Apple account sync → Finance screens: provides account data
