# vexolmer/life_dash architecture

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

- Interactive diagram: https://gitdiagram.com/vexolmer/life_dash
- Repository: https://github.com/vexolmer/life_dash

## Overview

#### Purpose and entry points
Local FastAPI application that treats an Obsidian vault’s Markdown/YAML notes as the source of truth, synchronizes them into SQLite, and renders analytics/records server-side. Web startup is `src/main.py`; command-line access is `cli.py`. Persistent local state is `data/db.sqlite`.

#### Application composition
The application is split into content modules with the same layered shape: SQLModel schema, repository, service, transformer, and FastAPI router.
- Books: `src/modules/books/models.py`, `src/modules/books/service.py`, `src/modules/books/router.py`
- Games: `src/modules/games/models.py`, `src/modules/games/service.py`, `src/modules/games/router.py`
- Daily notes, including daily records and time-log relationships: `src/modules/daily/models.py`, `src/modules/daily/service.py`, `src/modules/daily/router.py`

This boundary isolates module-specific note formats, validation, persistence, and analytics.

#### Synchronization / ETL boundary
Parsing is a one-way import from Obsidian files to the local database; the web UI does not edit source content. `src/parser/engine.py` scans vault directories and file modification metadata. `src/parser/sync.py` orchestrates module syncs, decides whether records require update, invokes module transformers, skips invalid inputs, and returns synchronization statistics for the UI.

Module transformers convert frontmatter and Markdown bodies into SQLModel-ready records:
`src/modules/books/transformer.py`, `src/modules/games/transformer.py`, and `src/modules/daily/transformer.py`. The Daily transformer is materially distinct because it regex-parses structured sleep, health, and time-tracking sections and produces parent/child daily-log data.

#### Persistence and migration model
SQLite is accessed through SQLModel/SQLAlchemy infrastructure in `src/core/database.py`. Repositories encapsulate queries and upserts rather than exposing database operations to routers:
`src/modules/books/repository.py`, `src/modules/games/repository.py`, `src/modules/daily/repository.py`.

Schema evolution is managed by Alembic under `migrations/env.py` and `migrations/versions/`. Daily persistence has the important ownership boundary: a `DailyNote` and its time logs are synchronized together, supporting replacement/cascade behavior.

#### Request, analytics, and rendering flow
FastAPI routers call services, which obtain records through repositories and compute presentation-ready metrics such as filters, aggregates, reading/game progress, ISO-week calculations, and daily averages. Routes render Jinja templates rather than serving a separate frontend API. The shared landing/dashboard route is `src/web/router.py`; module pages are rooted in their module routers.

Templates establish the presentation boundary:
`src/web/templates/layout.html`,
`src/web/templates/pages/books/`,
`src/web/templates/pages/daily/`, and
`src/web/templates/pages/games/`.
HTMX enables partial interactions such as sync reporting via `src/web/templates/components/sync_report.html`.

#### Core runtime infrastructure
Configuration, including vault/database paths, is centralized in `src/core/config.py`; logging is configured in `src/core/logger.py`; dashboard/statistical caching is in `src/core/cache.py`. Operational failures during parsing are intended to be logged while malformed files are excluded from persistence. Shared base CRUD behavior resides in `src/common/base.py`.

#### External technologies and boundaries
Runtime dependencies are FastAPI, SQLModel with local SQLite, Pydantic Settings, python-frontmatter, and Loguru. The UI is server-rendered Jinja2 with HTMX and static styling in `src/web/static/css/style.css`; browser-side charts use Chart.js. Obsidian vault files are the upstream external data source; no separate database server or write-back integration is implied. `scripts/mass_update_daily_notes.py` is an offline vault-maintenance utility, outside the application request path.

Main entry points: [`src/web/router.py`](https://github.com/vexolmer/life_dash/blob/main/src/web/router.py) (FastAPI routes), [`src/parser/sync.py`](https://github.com/vexolmer/life_dash/blob/main/src/parser/sync.py) (Sync orchestrator), [`src/core/database.py`](https://github.com/vexolmer/life_dash/blob/main/src/core/database.py) (SQLite database), [`src/parser/engine.py`](https://github.com/vexolmer/life_dash/blob/main/src/parser/engine.py) (Vault scanner)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["Entry Points"]
  node_main["FastAPI startup<br/>Python app<br/>[main.py]"]
  node_cli["CLI<br/>command entry<br/>[cli.py]"]
end

subgraph group_sync["Vault Synchronization"]
  node_vault["Obsidian vault<br/>upstream Markdown/YAML"]
  node_engine["Vault scanner<br/>parser engine<br/>[engine.py]"]
  node_syncer["Sync orchestrator<br/>ETL coordinator<br/>[sync.py]"]
end

subgraph group_modules["Content Modules"]
  node_book_transformer["Books transformer<br/>note transformer<br/>[transformer.py]"]
  node_game_transformer["Games transformer<br/>note transformer<br/>[transformer.py]"]
  node_daily_transformer["Daily transformer<br/>note transformer<br/>[transformer.py]"]
  node_book_module["Books module<br/>[models.py]"]
  node_game_module["Games module<br/>[models.py]"]
  node_daily_module["Daily module<br/>[models.py]"]
end

subgraph group_platform["Platform"]
  node_config["Configuration<br/>settings<br/>[config.py]"]
  node_database[("SQLite database<br/>SQLModel / SQLAlchemy<br/>[database.py]")]
  node_sqlite_file[("Local database file<br/>SQLite storage<br/>[db.sqlite]")]
  node_migrations["Alembic migrations<br/>schema evolution<br/>[env.py]"]
  node_logging["Operational logging<br/>Loguru<br/>[logger.py]"]
  node_cache["Dashboard cache<br/>statistical cache<br/>[cache.py]"]
end

subgraph group_web["Server Rendering"]
  node_routers["FastAPI routes<br/>module and dashboard routers<br/>[router.py]"]
  node_templates["Jinja templates<br/>server-rendered views<br/>[layout.html]"]
  node_browser["Browser UI<br/>[style.css]"]
end

node_main -->|"serves"| node_routers
node_cli -->|"runs sync"| node_syncer
node_config -.->|"vault path"| node_engine
node_config -.->|"database path"| node_database
node_vault -->|"scan notes"| node_engine
node_engine -->|"file metadata"| node_syncer
node_syncer -->|"book notes"| node_book_transformer
node_syncer -->|"game notes"| node_game_transformer
node_syncer -->|"daily notes"| node_daily_transformer
node_book_transformer -->|"records"| node_book_module
node_game_transformer -->|"records"| node_game_module
node_daily_transformer -->|"daily notes and logs"| node_daily_module
node_syncer -.->|"invalid input failures"| node_logging
node_book_module -->|"repository upserts and queries"| node_database
node_game_module -->|"repository upserts and queries"| node_database
node_daily_module -->|"cascade replacement"| node_database
node_database -->|"persists"| node_sqlite_file
node_migrations -->|"evolves schema"| node_database
node_routers -->|"book analytics"| node_book_module
node_routers -->|"game analytics"| node_game_module
node_routers -->|"daily analytics"| node_daily_module
node_routers -->|"sync action"| node_syncer
node_routers -->|"dashboard statistics"| node_cache
node_routers -->|"render context"| node_templates
node_templates -->|"HTML and HTMX partials"| node_browser

click node_main "https://github.com/vexolmer/life_dash/blob/main/src/main.py"
click node_cli "https://github.com/vexolmer/life_dash/blob/main/cli.py"
click node_engine "https://github.com/vexolmer/life_dash/blob/main/src/parser/engine.py"
click node_syncer "https://github.com/vexolmer/life_dash/blob/main/src/parser/sync.py"
click node_book_transformer "https://github.com/vexolmer/life_dash/blob/main/src/modules/books/transformer.py"
click node_game_transformer "https://github.com/vexolmer/life_dash/blob/main/src/modules/games/transformer.py"
click node_daily_transformer "https://github.com/vexolmer/life_dash/blob/main/src/modules/daily/transformer.py"
click node_book_module "https://github.com/vexolmer/life_dash/blob/main/src/modules/books/models.py"
click node_game_module "https://github.com/vexolmer/life_dash/blob/main/src/modules/games/models.py"
click node_daily_module "https://github.com/vexolmer/life_dash/blob/main/src/modules/daily/models.py"
click node_config "https://github.com/vexolmer/life_dash/blob/main/src/core/config.py"
click node_database "https://github.com/vexolmer/life_dash/blob/main/src/core/database.py"
click node_sqlite_file "https://github.com/vexolmer/life_dash/blob/main/data/db.sqlite"
click node_migrations "https://github.com/vexolmer/life_dash/blob/main/migrations/env.py"
click node_logging "https://github.com/vexolmer/life_dash/blob/main/src/core/logger.py"
click node_cache "https://github.com/vexolmer/life_dash/blob/main/src/core/cache.py"
click node_routers "https://github.com/vexolmer/life_dash/blob/main/src/web/router.py"
click node_templates "https://github.com/vexolmer/life_dash/blob/main/src/web/templates/layout.html"
click node_browser "https://github.com/vexolmer/life_dash/blob/main/src/web/static/css/style.css"

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_main,node_cli toneBlue
class node_vault,node_engine,node_syncer toneAmber
class node_book_transformer,node_game_transformer,node_daily_transformer,node_book_module,node_game_module,node_daily_module toneMint
class node_config,node_database,node_sqlite_file,node_migrations,node_logging,node_cache toneRose
class node_routers,node_templates,node_browser toneIndigo
```

## Components

### Entry Points

- [FastAPI startup](https://github.com/vexolmer/life_dash/blob/main/src/main.py): Python app · `src/main.py`
- [CLI](https://github.com/vexolmer/life_dash/blob/main/cli.py): command entry · `cli.py`

### Vault Synchronization

- **Obsidian vault**: upstream Markdown/YAML · Authoritative content source.
- [Vault scanner](https://github.com/vexolmer/life_dash/blob/main/src/parser/engine.py): parser engine · Scans note directories and modification metadata. · `src/parser/engine.py`
- [Sync orchestrator](https://github.com/vexolmer/life_dash/blob/main/src/parser/sync.py): ETL coordinator · Determines updates, skips invalid files, and returns sync statistics. · `src/parser/sync.py`

### Content Modules

- [Books transformer](https://github.com/vexolmer/life_dash/blob/main/src/modules/books/transformer.py): note transformer · `src/modules/books/transformer.py`
- [Games transformer](https://github.com/vexolmer/life_dash/blob/main/src/modules/games/transformer.py): note transformer · `src/modules/games/transformer.py`
- [Daily transformer](https://github.com/vexolmer/life_dash/blob/main/src/modules/daily/transformer.py): note transformer · Parses structured health, sleep, and time-log sections into parent/child data. · `src/modules/daily/transformer.py`
- [Books module](https://github.com/vexolmer/life_dash/blob/main/src/modules/books/models.py): models / repository / service / router · Provides book validation, persistence, progress, and analytics. · `src/modules/books/models.py`
- [Games module](https://github.com/vexolmer/life_dash/blob/main/src/modules/games/models.py): models / repository / service / router · Provides game validation, persistence, progress, and analytics. · `src/modules/games/models.py`
- [Daily module](https://github.com/vexolmer/life_dash/blob/main/src/modules/daily/models.py): models / repository / service / router · Owns DailyNote and time-log replacement/cascade persistence. · `src/modules/daily/models.py`

### Platform

- [Configuration](https://github.com/vexolmer/life_dash/blob/main/src/core/config.py): settings · Centralizes vault and database paths. · `src/core/config.py`
- [SQLite database](https://github.com/vexolmer/life_dash/blob/main/src/core/database.py): SQLModel / SQLAlchemy · Local synchronized application state. · `src/core/database.py`
- [Local database file](https://github.com/vexolmer/life_dash/blob/main/data/db.sqlite): SQLite storage · `data/db.sqlite`
- [Alembic migrations](https://github.com/vexolmer/life_dash/blob/main/migrations/env.py): schema evolution · `migrations/env.py`
- [Operational logging](https://github.com/vexolmer/life_dash/blob/main/src/core/logger.py): Loguru · Records parser failures while malformed files are excluded. · `src/core/logger.py`
- [Dashboard cache](https://github.com/vexolmer/life_dash/blob/main/src/core/cache.py): statistical cache · `src/core/cache.py`

### Server Rendering

- [FastAPI routes](https://github.com/vexolmer/life_dash/blob/main/src/web/router.py): module and dashboard routers · Dashboard plus books, games, and daily page routes. · `src/web/router.py`
- [Jinja templates](https://github.com/vexolmer/life_dash/blob/main/src/web/templates/layout.html): server-rendered views · Includes module pages and HTMX sync-report partials. · `src/web/templates/layout.html`
- [Browser UI](https://github.com/vexolmer/life_dash/blob/main/src/web/static/css/style.css): Jinja / HTMX / Chart.js · Renders server pages, partial updates, and charts. · `src/web/static/css/style.css`

## Connections

- FastAPI startup → FastAPI routes: serves
- CLI → Sync orchestrator: runs sync
- Configuration → Vault scanner: vault path
- Configuration → SQLite database: database path
- Obsidian vault → Vault scanner: scan notes
- Vault scanner → Sync orchestrator: file metadata
- Sync orchestrator → Books transformer: book notes
- Sync orchestrator → Games transformer: game notes
- Sync orchestrator → Daily transformer: daily notes
- Books transformer → Books module: records
- Games transformer → Games module: records
- Daily transformer → Daily module: daily notes and logs
- Sync orchestrator → Operational logging: invalid input failures
- Books module → SQLite database: repository upserts and queries
- Games module → SQLite database: repository upserts and queries
- Daily module → SQLite database: cascade replacement
- SQLite database → Local database file: persists
- Alembic migrations → SQLite database: evolves schema
- FastAPI routes → Books module: book analytics
- FastAPI routes → Games module: game analytics
- FastAPI routes → Daily module: daily analytics
- FastAPI routes → Sync orchestrator: sync action
- FastAPI routes → Dashboard cache: dashboard statistics
- FastAPI routes → Jinja templates: render context
- Jinja templates → Browser UI: HTML and HTMX partials
