8.8 KiB
8.8 KiB
title, description, status
| title | description | status |
|---|---|---|
| 05 — Building Block View | Explain the static structure: modules, components, services and their relationships. | draft |
05 — Building Block View
Architecture overview
This overview complements architecture 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
- Request flow & runtime interactions: Runtime View
- Simulation roadmap & strategy: Solution Strategy
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.
- leveraging a shared dependency module (
- 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 theapplication_settingtable, 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 instatic/css/main.cssdefine the color palette, while page-specific JS modules instatic/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 byroutes/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.
Level 1 Overview
graph LR
U["User (Browser)"]
subgraph FE[Frontend]
FE_TPL["Templates (Jinja2)"]
FE_STATIC["Static Assets (CSS/JS)"]
FE_PARTS["Reusable Partials"]
FE_SETTINGS["Settings View & JS"]
end
subgraph BE[Backend — FastAPI]
BE_APP["FastAPI App (main.py)"]
BE_ROUTES["Routers"]
BE_SERVICES["Services"]
BE_MODELS["Models (SQLAlchemy)"]
BE_DB["Database Layer"]
end
subgraph MW[Middleware & Utilities]
MW_VAL["JSON Validation Middleware"]
end
subgraph QA[Testing]
QA_UNIT["Unit Tests (pytest)"]
QA_E2E["E2E (Playwright, planned)"]
end
%% High-level flows
U -->|HTTP| BE_APP
U --> FE
FE --> BE_ROUTES
BE_APP --> BE_ROUTES
BE_ROUTES --> BE_SERVICES
BE_SERVICES --> BE_MODELS
BE_MODELS --> BE_DB
MW_VAL --> BE_APP
QA_UNIT --> BE_ROUTES
QA_UNIT --> BE_SERVICES
QA_UNIT --> FE
QA_UNIT --> MW_VAL
QA_E2E --> U
QA_E2E --> BE_APP
Level 2 Overview
graph LR
%% Direction
%% LR = left-to-right for a wide architecture view
%% === Clients ===
U["User (Browser)"]
%% === Frontend ===
subgraph FE[Frontend]
TPL["Jinja2 Templates
(templates/)
• base layout + sidebar"]
PARTS["Reusable Partials
(templates/partials/components.html)
• inputs • empty states • table wrappers"]
STATIC["Static Assets
(static/)
• CSS: static/css/main.css (palette via CSS vars)
• JS: static/js/*.js (page modules)"]
SETPAGE["Settings View
(templates/settings.html)"]
SETJS["Settings Logic
(static/js/settings.js)
• validation • submit • live CSS updates"]
end
%% === Backend ===
subgraph BE[Backend — FastAPI]
MAIN["FastAPI App
(main.py)
• 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
(shared SQLAlchemy session)"]
end
subgraph SRV[Services]
S_BLL["Business Logic Layer
• orchestrates models + calc"]
S_REP["Reporting Calculations"]
S_SIM["Monte Carlo
(simulation scaffolding)"]
S_SET["Settings Manager
(services/settings.py)
• defaults via CSS vars
• persistence in DB
• env overrides
• 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
(SQLAlchemy engine & sessions)"]
PG[("PostgreSQL")]
APPSET["application_setting table"]
end
end
%% === Middleware & Utilities ===
subgraph MW[Middleware & Utilities]
VAL["JSON Validation Middleware
(middleware/validation.py)"]
end
subgraph TEST[Testing]
UNIT["pytest unit tests
(tests/unit/)
• routes • services • UI rendering
• negative-path validation"]
E2E["Playwright E2E (planned)
• dashboard • scenario inputs • reporting
• 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;
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.