|
|
|
|
@@ -43,9 +43,56 @@ Refer to the detailed architecture chapters in `docs/architecture/`:
|
|
|
|
|
- **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
|
|
|
|
|
### Level 1 Overview
|
|
|
|
|
|
|
|
|
|
# System Architecture — Mermaid Diagram
|
|
|
|
|
```mermaid
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
```mermaid
|
|
|
|
|
graph LR
|
|
|
|
|
@@ -57,16 +104,28 @@ graph LR
|
|
|
|
|
|
|
|
|
|
%% === 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"]
|
|
|
|
|
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\n(main.py)\n• routers • middleware • startup/shutdown"]
|
|
|
|
|
subgraph BE[Backend — FastAPI]
|
|
|
|
|
MAIN["FastAPI App
|
|
|
|
|
(main.py)
|
|
|
|
|
• routers • middleware • startup/shutdown"]
|
|
|
|
|
|
|
|
|
|
subgraph ROUTES[Routers]
|
|
|
|
|
R_SCN["scenarios"]
|
|
|
|
|
@@ -79,14 +138,22 @@ graph LR
|
|
|
|
|
R_SIM["simulations"]
|
|
|
|
|
R_REP["reporting"]
|
|
|
|
|
R_UI["ui.py (metadata for UI)"]
|
|
|
|
|
DEP["dependencies.get_db\n(shared SQLAlchemy session)"]
|
|
|
|
|
DEP["dependencies.get_db
|
|
|
|
|
(shared SQLAlchemy session)"]
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
subgraph SRV[Services]
|
|
|
|
|
S_BLL["Business Logic Layer\n• orchestrates models + calc"]
|
|
|
|
|
S_BLL["Business Logic Layer
|
|
|
|
|
• 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"]
|
|
|
|
|
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]
|
|
|
|
|
@@ -101,7 +168,8 @@ graph LR
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
subgraph DB[Database Layer]
|
|
|
|
|
CFG["config/database.py\n(SQLAlchemy engine & sessions)"]
|
|
|
|
|
CFG["config/database.py
|
|
|
|
|
(SQLAlchemy engine & sessions)"]
|
|
|
|
|
PG[("PostgreSQL")]
|
|
|
|
|
APPSET["application_setting table"]
|
|
|
|
|
end
|
|
|
|
|
@@ -109,12 +177,18 @@ graph LR
|
|
|
|
|
|
|
|
|
|
%% === Middleware & Utilities ===
|
|
|
|
|
subgraph MW[Middleware & Utilities]
|
|
|
|
|
VAL["JSON Validation Middleware\n(middleware/validation.py)"]
|
|
|
|
|
VAL["JSON Validation Middleware
|
|
|
|
|
(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"]
|
|
|
|
|
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 =====================
|
|
|
|
|
@@ -170,17 +244,6 @@ graph LR
|
|
|
|
|
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.
|
|
|
|
|
|