--- title: '05 — Building Block View' description: 'Explain the static structure: modules, components, services and their relationships.' status: draft --- # 05 — Building Block View ## Architecture overview This overview complements [architecture](README.md) with a high-level map of CalMiner's module layout and request flow. Refer to the detailed architecture chapters in `docs/architecture/`: - Module map & components: [Building Block View](05_building_block_view.md) - Request flow & runtime interactions: [Runtime View](06_runtime_view.md) - Simulation roadmap & strategy: [Solution Strategy](04_solution_strategy.md) ## System Components ### Backend - **FastAPI application** (`main.py`): entry point that configures routers, middleware, and startup/shutdown events. - **Routers** (`routes/`): modular route handlers for scenarios, parameters, costs, consumption, production, equipment, maintenance, simulations, and reporting. Each router defines RESTful endpoints, request/response schemas, and orchestrates service calls. - leveraging a shared dependency module (`routes/dependencies.get_db`) for SQLAlchemy session management. - **Models** (`models/`): SQLAlchemy ORM models representing database tables and relationships, encapsulating domain entities like Scenario, CapEx, OpEx, Consumption, ProductionOutput, Equipment, Maintenance, and SimulationResult. - **Services** (`services/`): business logic layer that processes data, performs calculations, and interacts with models. Key services include reporting calculations and Monte Carlo simulation scaffolding. - `services/settings.py`: manages application settings backed by the `application_setting` table, including CSS variable defaults, persistence, and environment-driven overrides that surface in both the API and UI. - **Database** (`config/database.py`): sets up the SQLAlchemy engine and session management for PostgreSQL interactions. ### Frontend - **Templates** (`templates/`): Jinja2 templates for server-rendered HTML views, extending a shared base layout with a persistent sidebar for navigation. - **Static Assets** (`static/`): CSS and JavaScript files for styling and interactivity. Shared CSS variables in `static/css/main.css` define the color palette, while page-specific JS modules in `static/js/` handle dynamic behaviors. - **Reusable partials** (`templates/partials/components.html`): macro library that standardises select inputs, feedback/empty states, and table wrappers so pages remain consistent while keeping DOM hooks stable for existing JavaScript modules. - `templates/settings.html`: Settings hub that renders theme controls and environment override tables using metadata provided by `routes/ui.py`. - `static/js/settings.js`: applies client-side validation, form submission, and live CSS updates for theme changes, respecting environment-managed variables returned by the API. ### Middleware & Utilities - **Middleware** (`middleware/validation.py`): applies JSON validation before requests reach routers. - **Testing** (`tests/unit/`): pytest suite covering route and service behavior, including UI rendering checks and negative-path router validation tests to ensure consistent HTTP error semantics. Playwright end-to-end coverage is planned for core smoke flows (dashboard load, scenario inputs, reporting) and will attach in CI once scaffolding is completed. ### Component Diagram # System Architecture — Mermaid Diagram ```mermaid graph LR %% Direction %% LR = left-to-right for a wide architecture view %% === Clients === U["User (Browser)"] %% === Frontend === subgraph FE[Frontend] TPL["Jinja2 Templates\n(templates/)\n• base layout + sidebar"] PARTS["Reusable Partials\n(templates/partials/components.html)\n• inputs • empty states • table wrappers"] STATIC["Static Assets\n(static/)\n• CSS: static/css/main.css (palette via CSS vars)\n• JS: static/js/*.js (page modules)"] SETPAGE["Settings View\n(templates/settings.html)"] SETJS["Settings Logic\n(static/js/settings.js)\n• validation • submit • live CSS updates"] end %% === Backend === subgraph BE[Backend FastAPI] MAIN["FastAPI App\n(main.py)\n• routers • middleware • startup/shutdown"] subgraph ROUTES[Routers] R_SCN["scenarios"] R_PAR["parameters"] R_CST["costs"] R_CONS["consumption"] R_PROD["production"] R_EQP["equipment"] R_MNT["maintenance"] R_SIM["simulations"] R_REP["reporting"] R_UI["ui.py (metadata for UI)"] DEP["dependencies.get_db\n(shared SQLAlchemy session)"] end subgraph SRV[Services] S_BLL["Business Logic Layer\n• orchestrates models + calc"] S_REP["Reporting Calculations"] S_SIM["Monte Carlo\n(simulation scaffolding)"] S_SET["Settings Manager\n(services/settings.py)\n• defaults via CSS vars\n• persistence in DB\n• env overrides\n• surfaces to API & UI"] end subgraph MOD[Models] M_SCN["Scenario"] M_CAP["CapEx"] M_OPEX["OpEx"] M_CONS["Consumption"] M_PROD["ProductionOutput"] M_EQP["Equipment"] M_MNT["Maintenance"] M_SIMR["SimulationResult"] end subgraph DB[Database Layer] CFG["config/database.py\n(SQLAlchemy engine & sessions)"] PG[("PostgreSQL")] APPSET["application_setting table"] end end %% === Middleware & Utilities === subgraph MW[Middleware & Utilities] VAL["JSON Validation Middleware\n(middleware/validation.py)"] end subgraph TEST[Testing] UNIT["pytest unit tests\n(tests/unit/)\n• routes • services • UI rendering\n• negative-path validation"] E2E["Playwright E2E (planned)\n• dashboard • scenario inputs • reporting\n• attach in CI"] end %% ===================== Edges / Flows ===================== %% User to Frontend/Backend U -->|HTTP GET| MAIN U --> TPL TPL -->|server-rendered HTML| U STATIC --> U PARTS --> TPL SETPAGE --> U SETJS --> U %% Frontend to Routers (AJAX/form submits) SETJS -->|fetch/POST| R_UI TPL -->|form submit / fetch| ROUTES %% FastAPI app wiring and middleware VAL --> MAIN MAIN --> ROUTES %% Routers to Services ROUTES -->|calls| SRV R_REP -->|calc| S_REP R_SIM -->|run| S_SIM R_UI -->|read/write settings meta| S_SET %% Services to Models & DB SRV --> MOD MOD --> CFG CFG --> PG %% Settings manager persistence path S_SET -->|persist/read| APPSET APPSET --- PG %% Shared DB session dependency DEP -. provides .-> ROUTES DEP -. session .-> SRV %% Model entities mapping S_BLL --> M_SCN & M_CAP & M_OPEX & M_CONS & M_PROD & M_EQP & M_MNT & M_SIMR %% Testing coverage UNIT --> ROUTES UNIT --> SRV UNIT --> TPL UNIT --> VAL E2E --> U E2E --> MAIN %% Legend classDef store fill:#fff,stroke:#555,stroke-width:1px; class PG store; ``` --- **Notes** - Arrows represent primary data/command flow. Dashed arrows denote shared dependencies (injected SQLAlchemy session). - The settings pipeline shows how environment overrides and DB-backed defaults propagate to both API and UI. ``` ``` ## Module Map (code) - `scenario.py`: central scenario entity with relationships to cost, consumption, production, equipment, maintenance, and simulation results. - `capex.py`, `opex.py`: financial expenditures tied to scenarios. - `consumption.py`, `production_output.py`: operational data tables. - `equipment.py`, `maintenance.py`: asset management models. - `simulation_result.py`: stores Monte Carlo iteration outputs. - `application_setting.py`: persists editable application configuration, currently focused on theme variables but designed to store future settings categories. ## Service Layer - `reporting.py`: computes aggregates (count, min/max, mean, median, percentiles, standard deviation, variance, tail-risk metrics) from simulation results. - `simulation.py`: scaffolds Monte Carlo simulation logic (currently in-memory; persistence planned). - `currency.py`: handles currency normalization for cost tables. - `utils.py`: shared helper functions (e.g., statistical calculations). - `validation.py`: JSON schema validation middleware. - `database.py`: SQLAlchemy engine and session setup. - `dependencies.py`: FastAPI dependency injection for DB sessions.