# krezzy88/sochat architecture

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

- Interactive diagram: https://gitdiagram.com/krezzy88/sochat
- Repository: https://github.com/krezzy88/sochat

## Overview

SổChat is a Vietnamese personal-finance workspace whose central flow is chat message → extraction proposal → user review and confirmation → auditable ledger entry. The React client calls a session- and CSRF-protected Express API; deterministic parsing is primary, with guarded Gemini extraction available for ambiguous input. The API persists exact integer VND data in PostgreSQL and also serves analytics, budgets, goals, assistant answers, and opt-in semantic search. Several feature modules were not sampled; their presence and capabilities are documented in README.md, so those branches are shown without claiming unsampled implementation details.

Main entry points: [`apps/api/src/http/app.ts`](https://github.com/krezzy88/sochat/blob/main/apps/api/src/http/app.ts) (HTTP application), [`apps/web/src/api.ts`](https://github.com/krezzy88/sochat/blob/main/apps/web/src/api.ts) (JSON API client), [`apps/web/src/App.tsx`](https://github.com/krezzy88/sochat/blob/main/apps/web/src/App.tsx) (Finance workspace), [`apps/api/src/extraction/hybrid.ts`](https://github.com/krezzy88/sochat/blob/main/apps/api/src/extraction/hybrid.ts) (Hybrid extraction)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["Finance workspace"]
  node_workspace["Finance workspace<br/>[App.tsx]"]
  node_chat["Chat and drafts<br/>[Chat.tsx]"]
  node_ledger_ui["Ledger management<br/>[Transactions.tsx]"]
  node_analytics["Analytics dashboard<br/>[Dashboard.tsx]"]
  node_budgets["Category budgets<br/>[Budgets.tsx]"]
  node_goals["Savings goals<br/>[Goals.tsx]"]
  node_assistant_ui["Ledger assistant<br/>[QueryPanel.tsx]"]
  node_semantic_ui["Semantic search<br/>[SemanticSearch.tsx]"]
  node_settings["Account settings<br/>[Settings.tsx]"]
  node_api_client["JSON API client<br/>[api.ts]"]
end

subgraph group_api["API and extraction"]
  node_http_api["HTTP application<br/>[app.ts]"]
  node_revision["Draft revision<br/>[revision.ts]"]
  node_assistant["Question interpretation<br/>[assistant.ts]"]
  node_semantic["Semantic endpoints<br/>[semantic.ts]"]
  node_repository["Finance operations<br/>[repository.ts]"]
  node_hybrid["Hybrid extraction<br/>[hybrid.ts]"]
  node_provider["Gemini adapter<br/>[provider.ts]"]
end

subgraph group_data["Ledger and providers"]
  node_extraction_store["Extraction records<br/>[store.ts]"]
  node_postgres[("PostgreSQL ledger<br/>[repositories.ts]")]
  node_tenant["Tenant sessions<br/>[tenant.ts]"]
end

subgraph group_language["Language processing"]
  node_parser["Vietnamese parser<br/>[index.ts]"]
  node_amounts["Amount parsing<br/>[amounts.ts]"]
  node_dates["Date resolution<br/>[dates.ts]"]
  node_classification["Category classification<br/>[classify.ts]"]
end

node_person(("Finance user"))
node_gemini["Google Gemini"]

node_person -->|"uses"| node_workspace
node_workspace -->|"opens"| node_chat
node_workspace -->|"opens"| node_ledger_ui
node_workspace -->|"opens"| node_analytics
node_workspace -->|"opens"| node_budgets
node_workspace -->|"opens"| node_goals
node_workspace -->|"opens"| node_settings
node_chat -->|"requests"| node_api_client
node_ledger_ui -->|"requests"| node_api_client
node_analytics -->|"requests"| node_api_client
node_budgets -->|"requests"| node_api_client
node_goals -->|"requests"| node_api_client
node_assistant_ui -->|"requests"| node_api_client
node_semantic_ui -->|"requests"| node_api_client
node_settings -->|"requests"| node_api_client
node_api_client -->|"calls"| node_http_api
node_http_api -->|"scopes requests"| node_tenant
node_http_api -->|"extracts drafts"| node_hybrid
node_http_api -->|"revises drafts"| node_revision
node_http_api -->|"interprets questions"| node_assistant
node_http_api -->|"routes search"| node_semantic
node_http_api -->|"serves ledger"| node_repository
node_hybrid -->|"parses rules"| node_parser
node_hybrid -->|"requests extraction"| node_provider
node_hybrid -->|"checks limits"| node_extraction_store
node_provider -.->|"calls API"| node_gemini
node_semantic -->|"uses embeddings"| node_extraction_store
node_repository -->|"reads and writes"| node_postgres
node_parser -->|"extracts amounts"| node_amounts
node_parser -->|"resolves dates"| node_dates
node_parser -->|"classifies items"| node_classification
node_assistant_ui -->|"asks ledger"| node_http_api
node_semantic_ui -->|"searches notes"| node_http_api

click node_workspace "https://github.com/krezzy88/sochat/blob/main/apps/web/src/App.tsx"
click node_chat "https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Chat.tsx"
click node_ledger_ui "https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Transactions.tsx"
click node_analytics "https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Dashboard.tsx"
click node_budgets "https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Budgets.tsx"
click node_goals "https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Goals.tsx"
click node_assistant_ui "https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/QueryPanel.tsx"
click node_semantic_ui "https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/SemanticSearch.tsx"
click node_settings "https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Settings.tsx"
click node_api_client "https://github.com/krezzy88/sochat/blob/main/apps/web/src/api.ts"
click node_http_api "https://github.com/krezzy88/sochat/blob/main/apps/api/src/http/app.ts"
click node_revision "https://github.com/krezzy88/sochat/blob/main/apps/api/src/http/revision.ts"
click node_assistant "https://github.com/krezzy88/sochat/blob/main/apps/api/src/http/assistant.ts"
click node_semantic "https://github.com/krezzy88/sochat/blob/main/apps/api/src/http/semantic.ts"
click node_repository "https://github.com/krezzy88/sochat/blob/main/apps/api/src/http/repository.ts"
click node_hybrid "https://github.com/krezzy88/sochat/blob/main/apps/api/src/extraction/hybrid.ts"
click node_provider "https://github.com/krezzy88/sochat/blob/main/apps/api/src/extraction/provider.ts"
click node_extraction_store "https://github.com/krezzy88/sochat/blob/main/apps/api/src/extraction/store.ts"
click node_postgres "https://github.com/krezzy88/sochat/blob/main/apps/api/src/db/repositories.ts"
click node_tenant "https://github.com/krezzy88/sochat/blob/main/apps/api/src/db/tenant.ts"
click node_parser "https://github.com/krezzy88/sochat/blob/main/packages/parser/src/index.ts"
click node_amounts "https://github.com/krezzy88/sochat/blob/main/packages/parser/src/amounts.ts"
click node_dates "https://github.com/krezzy88/sochat/blob/main/packages/parser/src/dates.ts"
click node_classification "https://github.com/krezzy88/sochat/blob/main/packages/parser/src/classify.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_workspace,node_chat,node_ledger_ui,node_analytics,node_budgets,node_goals,node_assistant_ui,node_semantic_ui,node_settings,node_api_client,node_person toneBlue
class node_http_api,node_revision,node_assistant,node_semantic,node_repository,node_hybrid,node_provider toneAmber
class node_extraction_store,node_postgres,node_tenant toneMint
class node_parser,node_amounts,node_dates,node_classification toneRose
class node_gemini toneIndigo
```

## Components

### Finance workspace

- [Finance workspace](https://github.com/krezzy88/sochat/blob/main/apps/web/src/App.tsx): `apps/web/src/App.tsx`
- [Chat and drafts](https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Chat.tsx): `apps/web/src/pages/Chat.tsx`
- [Ledger management](https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Transactions.tsx): `apps/web/src/pages/Transactions.tsx`
- [Analytics dashboard](https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Dashboard.tsx): `apps/web/src/pages/Dashboard.tsx`
- [Category budgets](https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Budgets.tsx): `apps/web/src/pages/Budgets.tsx`
- [Savings goals](https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Goals.tsx): `apps/web/src/pages/Goals.tsx`
- [Ledger assistant](https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/QueryPanel.tsx): `apps/web/src/pages/QueryPanel.tsx`
- [Semantic search](https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/SemanticSearch.tsx): `apps/web/src/pages/SemanticSearch.tsx`
- [Account settings](https://github.com/krezzy88/sochat/blob/main/apps/web/src/pages/Settings.tsx): `apps/web/src/pages/Settings.tsx`
- [JSON API client](https://github.com/krezzy88/sochat/blob/main/apps/web/src/api.ts): `apps/web/src/api.ts`

### API and extraction

- [HTTP application](https://github.com/krezzy88/sochat/blob/main/apps/api/src/http/app.ts): `apps/api/src/http/app.ts`
- [Draft revision](https://github.com/krezzy88/sochat/blob/main/apps/api/src/http/revision.ts): `apps/api/src/http/revision.ts`
- [Question interpretation](https://github.com/krezzy88/sochat/blob/main/apps/api/src/http/assistant.ts): `apps/api/src/http/assistant.ts`
- [Semantic endpoints](https://github.com/krezzy88/sochat/blob/main/apps/api/src/http/semantic.ts): `apps/api/src/http/semantic.ts`
- [Finance operations](https://github.com/krezzy88/sochat/blob/main/apps/api/src/http/repository.ts): `apps/api/src/http/repository.ts`
- [Hybrid extraction](https://github.com/krezzy88/sochat/blob/main/apps/api/src/extraction/hybrid.ts): `apps/api/src/extraction/hybrid.ts`
- [Gemini adapter](https://github.com/krezzy88/sochat/blob/main/apps/api/src/extraction/provider.ts): `apps/api/src/extraction/provider.ts`

### Ledger and providers

- [Extraction records](https://github.com/krezzy88/sochat/blob/main/apps/api/src/extraction/store.ts): `apps/api/src/extraction/store.ts`
- [PostgreSQL ledger](https://github.com/krezzy88/sochat/blob/main/apps/api/src/db/repositories.ts): `apps/api/src/db/repositories.ts`
- [Tenant sessions](https://github.com/krezzy88/sochat/blob/main/apps/api/src/db/tenant.ts): `apps/api/src/db/tenant.ts`

### Language processing

- [Vietnamese parser](https://github.com/krezzy88/sochat/blob/main/packages/parser/src/index.ts): `packages/parser/src/index.ts`
- [Amount parsing](https://github.com/krezzy88/sochat/blob/main/packages/parser/src/amounts.ts): `packages/parser/src/amounts.ts`
- [Date resolution](https://github.com/krezzy88/sochat/blob/main/packages/parser/src/dates.ts): `packages/parser/src/dates.ts`
- [Category classification](https://github.com/krezzy88/sochat/blob/main/packages/parser/src/classify.ts): `packages/parser/src/classify.ts`

### Other components

- **Finance user**
- **Google Gemini**

## Connections

- Finance user → Finance workspace: uses (evidence: `README.md`)
- Finance workspace → Chat and drafts: opens (evidence: `apps/web/src/App.tsx`)
- Finance workspace → Ledger management: opens (evidence: `apps/web/src/App.tsx`)
- Finance workspace → Analytics dashboard: opens (evidence: `apps/web/src/App.tsx`)
- Finance workspace → Category budgets: opens (evidence: `README.md`)
- Finance workspace → Savings goals: opens (evidence: `README.md`)
- Finance workspace → Account settings: opens (evidence: `apps/web/src/App.tsx`)
- Chat and drafts → JSON API client: requests (evidence: `apps/web/src/pages/Chat.tsx`)
- Ledger management → JSON API client: requests (evidence: `README.md`)
- Analytics dashboard → JSON API client: requests (evidence: `README.md`)
- Category budgets → JSON API client: requests (evidence: `README.md`)
- Savings goals → JSON API client: requests (evidence: `apps/web/src/pages/Goals.tsx`)
- Ledger assistant → JSON API client: requests (evidence: `apps/web/src/pages/QueryPanel.tsx`)
- Semantic search → JSON API client: requests (evidence: `apps/web/src/pages/SemanticSearch.tsx`)
- Account settings → JSON API client: requests (evidence: `README.md`)
- JSON API client → HTTP application: calls (evidence: `apps/web/src/api.ts`)
- HTTP application → Tenant sessions: scopes requests (evidence: `apps/api/src/http/app.ts`)
- HTTP application → Hybrid extraction: extracts drafts (evidence: `apps/api/src/http/app.ts`)
- HTTP application → Draft revision: revises drafts (evidence: `apps/api/src/http/app.ts`)
- HTTP application → Question interpretation: interprets questions (evidence: `apps/api/src/http/app.ts`)
- HTTP application → Semantic endpoints: routes search (evidence: `apps/api/src/http/app.ts`)
- HTTP application → Finance operations: serves ledger (evidence: `README.md`)
- Hybrid extraction → Vietnamese parser: parses rules (evidence: `apps/api/src/extraction/hybrid.ts`)
- Hybrid extraction → Gemini adapter: requests extraction (evidence: `apps/api/src/extraction/hybrid.ts`)
- Hybrid extraction → Extraction records: checks limits (evidence: `apps/api/src/extraction/hybrid.ts`)
- Gemini adapter → Google Gemini: calls API (evidence: `README.md`)
- Semantic endpoints → Extraction records: uses embeddings (evidence: `apps/api/src/http/semantic.ts`)
- Finance operations → PostgreSQL ledger: reads and writes (evidence: `README.md`)
- Vietnamese parser → Amount parsing: extracts amounts (evidence: `packages/parser/src/index.ts`)
- Vietnamese parser → Date resolution: resolves dates (evidence: `packages/parser/src/index.ts`)
- Vietnamese parser → Category classification: classifies items (evidence: `packages/parser/src/index.ts`)
- Ledger assistant → HTTP application: asks ledger (evidence: `README.md`)
- Semantic search → HTTP application: searches notes (evidence: `README.md`)
