- Engine: Add ppa_revenue_cr, mcp_revenue_cr, tariff, units to PnLRow - Engine: Split PPA vs MCP revenue in P&L computation - Web: Collapsible rows for PPA/MCP Revenue and Opex - Web: Highlighted rows (Total Revenue, EBITDA, EBIT, PBT, PAT) - Web: Units above Tariff in breakdown, bg-blue-50 highlight - Fix sticky column z-index for horizontal scroll - CLAUDE.md: Add project documentation Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
534 lines
No EOL
20 KiB
Markdown
534 lines
No EOL
20 KiB
Markdown
# REmodel Codebase Investigation Report
|
||
|
||
**Date:** 2026-05-07
|
||
**Investigator:** Claude (Agentic exploration)
|
||
|
||
---
|
||
|
||
## 1. Executive Summary
|
||
|
||
REmodel is a **full-stack hybrid renewable energy (Solar + Wind + BESS) project finance modeling platform** built in Python with a FastAPI backend and Next.js frontend. The project is designed to replace an Excel-macro workflow used for bid preparation at ReNew Power in India, targeting computation of optimal flat tariff and full 25-year project financials in under 30 seconds per scenario.
|
||
|
||
### Key Architecture
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ packages/engine │
|
||
│ Python calculation engine (pip-installable) │
|
||
│ • Generation (solar, wind, BESS) │
|
||
│ • Capex + IDC calculation │
|
||
│ • Financial model (P&L, CFS, BS) │
|
||
│ • Debt sizing + scheduling │
|
||
│ • Tariff solver (brentq) │
|
||
│ • CLI driver (Typer) │
|
||
└─────────────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ packages/api │
|
||
│ FastAPI + Arq async workers (Redis-backed) │
|
||
│ • REST endpoints (scenarios, templates) │
|
||
│ • Background task processing │
|
||
│ • SQLite + Parquet storage │
|
||
│ • SSE for real-time progress │
|
||
│ • Excel export │
|
||
└─────────────────────────────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────────────────────┐
|
||
│ packages/web │
|
||
│ Next.js 14 App Router + shadcn/ui + Tailwind │
|
||
│ • Scenario list + wizard │
|
||
│ • Results dashboard │
|
||
│ • KPI visualizations (Recharts) │
|
||
│ • Compare scenarios view │
|
||
│ • DataGrid (AG Grid) │
|
||
└─────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 2. Codebase Structure
|
||
|
||
### 2.1 Root Directory
|
||
|
||
```
|
||
/Users/manohar_air/MyProjects/REModel/
|
||
├── PROJECT.md # Master specification document
|
||
├── README.md # Quick reference
|
||
├── docker-compose.yml # Redis service
|
||
├── Makefile # Common commands
|
||
├── .pre-commit-config.yaml
|
||
├── .github/workflows/ # CI/CD
|
||
├── packages/ # Monorepo structure
|
||
│ ├── engine/ # Python calculation engine
|
||
│ ├── api/ # FastAPI backend
|
||
│ └── web/ # Next.js frontend
|
||
└── sprints/ # Sprint documentation (SPRINT_00-08)
|
||
```
|
||
|
||
---
|
||
|
||
## 3. Packages/Engine Analysis
|
||
|
||
### 3.1 Module Structure (42 Python files)
|
||
|
||
```
|
||
packages/engine/src/remodel_engine/
|
||
├── __init__.py
|
||
├── cli.py # Typer CLI (simulate-gen, compute-idc, solve-tariff)
|
||
│
|
||
├── schemas/ # Pydantic models (single source of truth)
|
||
│ ├── __init__.py
|
||
│ ├── scenario.py # ScenarioInput, ScenarioResult, KpiSummary
|
||
│ ├── capex.py # CostItem, CapexConfig, PhasingCurve, DrawdownCurve
|
||
│ ├── debt.py # DebtConfig, DebtYearRow, IRRMetrics
|
||
│ ├── financial.py # CommercialConfig, OpexConfig, TaxConfig, Financials
|
||
│ └── generation.py # SolarConfig, WindConfig, BessConfig
|
||
│
|
||
├── catalog/ # Defaults and profile loaders
|
||
│ ├── __init__.py
|
||
│ ├── defaults.py # Constants: PROJECT_LIFE=25, HOURS=8760
|
||
│ ├── loader.py # Solar/wind profile CSV loader (RJ, KA, GJ)
|
||
│ └── profiles/ # Bundled 8760-hour CSV files
|
||
│
|
||
├── generation/ # 25-year generation simulation
|
||
│ ├── __init__.py
|
||
│ ├── solar.py # DC→AC→clipping→availability→soiling→degradation
|
||
│ ├── wind.py # Power curve lookup→shear→wake→availability
|
||
│ └── bess_state.py # Degradation + augmentation capacity model
|
||
│
|
||
├── dispatch/ # Hybrid RTC dispatch
|
||
│ ├── __init__.py
|
||
│ ├── hybrid_rtc.py # Per-hour charge/discharge logic
|
||
│ └── mcp_settlement.py # Merchant sale at MCP
|
||
│
|
||
├── capex/ # Capital expenditure
|
||
│ ├── __init__.py
|
||
│ ├── cost_items.py # CostItem catalog → total capex
|
||
│ ├── phasing.py # Construction phasing matrix
|
||
│ └── idc.py # Interest During Construction (fixed-point)
|
||
│
|
||
├── commercial/ # Revenue and DSM
|
||
│ ├── __init__.py
|
||
│ └── ppa.py # Generation aggregation, receivables/payables
|
||
│
|
||
├── financial/ # 3-statement model
|
||
│ ├── __init__.py
|
||
│ ├── pnl.py # Revenue → OpEx → EBITDA → Depr → EBIT → Tax → PAT
|
||
│ ├── cfs.py # Cash Flow Statement (CFO/CFI/CFF)
|
||
│ ├── bs.py # Balance Sheet (reconciliation)
|
||
│ ├── depreciation.py # Book SLM + tax WDV schedules
|
||
│ ├── tax.py # 115BAA (India) tax computation
|
||
│ └── working_capital.py # Receivables, payables, inventory
|
||
│
|
||
├── debt/ # Debt financing
|
||
│ ├── __init__.py
|
||
│ ├── sizing.py # Fixed-point debt sizing (D:E, DSCR constraints)
|
||
│ └── schedule.py # Repayment shapes (equal principal, EMI, sculpted, balloon)
|
||
│
|
||
├── irr/ # Financial metrics
|
||
│ └── metrics.py # IRR, NPV, LCOE, DSCR, LLCR, PLCR, payback
|
||
│
|
||
├── solver/ # Solver logic
|
||
│ └── tariff.py # Brentq solver for tariff→IRR target
|
||
│
|
||
├── scenarios/ # Scenario orchestration
|
||
│ ├── __init__.py
|
||
│ ├── runner.py # Full pipeline (generation→financial→debt→IRR)
|
||
│ └── sweep.py # Sensitivity analysis
|
||
│
|
||
└── io/ # Data export
|
||
└── excel_export.py # .xlsx workbook generation
|
||
```
|
||
|
||
### 3.2 Key Schema Definitions
|
||
|
||
#### ScenarioInput (Top-level input)
|
||
```python
|
||
class ScenarioInput(BaseModel):
|
||
project: ProjectInfo # name, state, capacities, COD
|
||
solar: SolarConfig | None # location, DC/AC, losses, degradation
|
||
wind: WindConfig | None # location, MW, hub-height
|
||
bess: BessConfig | None # MWh, power, RTE, DoD
|
||
rtc: RtcConfig | None # contracted RTC MW, MCP toggle
|
||
commercial: CommercialConfig # tariff, losses, working capital
|
||
capex: CapexConfig # cost items, phasing curves, drawdowns
|
||
opex: OpexConfig # O&M, insurance, land lease
|
||
debt: DebtConfig # rate, tenor, DSCR constraints
|
||
tax: TaxConfig # 115BAA rates
|
||
solver: SolverConfig # solve_tariff or fixed_tariff mode
|
||
```
|
||
|
||
#### ScenarioResult (Full output)
|
||
```python
|
||
class ScenarioResult(BaseModel):
|
||
inputs: ScenarioInput
|
||
status: Literal["queued","running","success","failed"]
|
||
solved_tariff: float | None
|
||
kpis: KpiSummary # equity_irr, project_irr, DSCR, capex, LCOE, etc.
|
||
financials: Financials # pnl_25y, cfs_25y, bs_25y
|
||
debt_schedule: list[DebtYearRow]
|
||
irr_metrics: IRRMetrics
|
||
warnings: list[str]
|
||
runtime_s: float
|
||
generation_by_year: list[dict]
|
||
idc_phasing: dict
|
||
```
|
||
|
||
### 3.3 Financial Model Flow
|
||
|
||
The 3-statement model computes:
|
||
|
||
1. **P&L (Profit & Loss)**
|
||
- Revenue: generation_MWh × tariff × (1 - losses) / 10^7 → Cr
|
||
- OpEx: O&M + insurance + land_lease + AM_fee + misc
|
||
- EBITDA = Revenue - OpEx
|
||
- Depreciation: Book SLM by asset class
|
||
- EBIT = EBITDA - Depreciation
|
||
- Interest: From debt schedule
|
||
- PBT = EBIT - Interest
|
||
- Tax: 115BAA (25.17%) current + deferred
|
||
- PAT = PBT - Tax
|
||
|
||
2. **CFS (Cash Flow Statement)**
|
||
- CFO = PAT + Depreciation - ΔWC
|
||
- CFI = 0 (capex in year 0)
|
||
- CFF = Debt drawdown - Debt repayment + Equity injection
|
||
- Net = CFO + CFI + CFF
|
||
|
||
3. **BS (Balance Sheet)**
|
||
- Assets = Net block + Cash + Receivables
|
||
- Liabilities = Equity + Reserves + LT Debt + Payables + DTL
|
||
- Reconciliation enforced (≤₹0.05 Cr difference)
|
||
|
||
### 3.4 Debt Sizing Algorithm
|
||
|
||
The debt sizing module (`debt/sizing.py`) implements a fixed-point iteration that satisfies three constraints:
|
||
|
||
1. **D:E Ratio Cap:** `debt ≤ total_capex × de_ratio / (1 + de_ratio)`
|
||
2. **Min DSCR Constraint:** `debt ≤ max satisfying min(DSCR) ≥ min_dscr`
|
||
3. **Avg DSCR Constraint:** `debt ≤ max satisfying avg(DSCR) ≥ avg_dscr`
|
||
|
||
The binding constraint determines the final debt amount.
|
||
|
||
### 3.5 Repayment Schedule Shapes
|
||
|
||
Five debt schedule shapes are supported (in `debt/schedule.py`):
|
||
|
||
1. **equal_principal:** Fixed principal each year in repayment period
|
||
2. **equal_installment:** EMI (level annuity)
|
||
3. **dscr_sculpted:** Principal sculpted so DSCR = avg_dscr each year
|
||
4. **balloon:** Interest-only then principal at end
|
||
5. **custom_pct_vector:** Caller supplies repayment % per year
|
||
|
||
### 3.6 Tariff Solver
|
||
|
||
The solver (`solver/tariff.py`) uses Brent's method (scipy.optimize.brentq) to find the tariff that achieves target equity IRR:
|
||
|
||
- Bracket: [2.0, 8.0] INR/kWh
|
||
- Convergence tolerance: 1e-4
|
||
- Max iterations: 50
|
||
|
||
### 3.7 Generation Models
|
||
|
||
**Solar (`generation/solar.py`):**
|
||
- Input: irradiance × capacity_dc → DC power → DC losses
|
||
- Inverter efficiency → AC pre-clip
|
||
- Clipping at MW_AC (DC/AC ratio > 1)
|
||
- Availability × soiling × degradation
|
||
- Output: 25 years × 8760 hours = 219,000 rows
|
||
|
||
Model chain:
|
||
```
|
||
irradiance → DC power → DC losses → inverter → AC losses
|
||
→ clipping at MW_AC → availability → soiling → degradation
|
||
```
|
||
|
||
**Wind (`generation/wind.py`):**
|
||
- Wind speed at reference → hub-height correction (power law shear)
|
||
- Power curve lookup → normalized power (0-1)
|
||
- Wake losses × electrical losses × availability × degradation
|
||
|
||
**BESS (`generation/bess_state.py`):**
|
||
- Degradation: `SOH = max(eol_soh, 1 - cum_cycles/design_cycles × (1 - eol_soh))`
|
||
- Usable MWh = (nameplate + augmentation) × SOH
|
||
- Augmentation steps add capacity at specified years
|
||
|
||
### 3.8 Hybrid RTC Dispatch
|
||
|
||
The dispatch module (`dispatch/hybrid_rtc.py`) implements hourly charge/discharge:
|
||
|
||
```
|
||
For each hour h:
|
||
gen = solar[h] + wind[h]
|
||
surplus = gen - target (positive = excess, negative = deficit)
|
||
|
||
If surplus ≥ 0:
|
||
- Charge BESS with min(surplus, bess_mw, headroom)
|
||
- Curtail excess
|
||
Else:
|
||
- Discharge BESS with min(deficit, available)
|
||
- Shortfall = deficit - discharge
|
||
```
|
||
|
||
### 3.9 CLI Commands
|
||
|
||
```bash
|
||
# Simulate 25-year solar + wind generation
|
||
remodel simulate-gen --input scenario.json --output gen.parquet
|
||
|
||
# Compute IDC (Interest During Construction)
|
||
remodel compute-idc --input capex.json --output idc.json
|
||
|
||
# Run full scenario pipeline
|
||
remodel solve-tariff --input scenario.json --output result.json
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Packages/API Analysis
|
||
|
||
### 4.1 Module Structure
|
||
|
||
```
|
||
packages/api/src/remodel_api/
|
||
├── __init__.py
|
||
├── main.py # FastAPI app, CORS, lifespan
|
||
├── config.py # Settings (environment config)
|
||
├── db/
|
||
│ ├── __init__.py
|
||
│ ├── session.py # SQLAlchemy async session
|
||
│ └── models.py # Scenario ORM model
|
||
├── routers/
|
||
│ ├── __init__.py
|
||
│ ├── scenarios.py # CRUD + run + results + SSE + Excel export
|
||
│ └── templates.py # Scenario templates
|
||
└── workers/
|
||
├── __init__.py
|
||
├── main.py # Arq worker setup
|
||
└── tasks.py # Background scenario execution
|
||
```
|
||
|
||
### 4.2 API Endpoints
|
||
|
||
| Method | Endpoint | Description |
|
||
|--------|----------|-------------|
|
||
| POST | `/api/scenarios` | Create scenario, queue for execution |
|
||
| GET | `/api/scenarios` | List scenarios |
|
||
| GET | `/api/scenarios/{id}` | Get scenario details |
|
||
| PATCH | `/api/scenarios/{id}/inputs` | Update inputs, re-queue |
|
||
| DELETE | `/api/scenarios/{id}` | Archive scenario |
|
||
| GET | `/api/scenarios/{id}/kpis` | Get KPI results |
|
||
| GET | `/api/scenarios/{id}/statements` | Get P&L, CFS, BS |
|
||
| GET | `/api/scenarios/{id}/export/excel` | Export .xlsx |
|
||
| GET | `/api/scenarios/{id}/events` | SSE progress events |
|
||
|
||
### 4.3 Database Schema
|
||
|
||
```python
|
||
class Scenario(Base):
|
||
id: str (UUID, primary key)
|
||
name: str
|
||
status: str ("queued", "running", "success", "failed")
|
||
inputs_json: Text (JSON string of ScenarioInput)
|
||
kpis_json: Text (JSON string of KpiSummary)
|
||
statements_json: Text (JSON string of pnl/cfs/bs)
|
||
debt_schedule_json: Text
|
||
timeseries_path: str
|
||
error_message: str
|
||
runtime_s: float
|
||
created_at: datetime
|
||
archived_at: datetime | None
|
||
```
|
||
|
||
### 4.4 Background Processing
|
||
|
||
- Uses **Arq** (async Redis-backed task queue)
|
||
- **ThreadPoolExecutor** runs CPU-bound engine in separate thread
|
||
- Progress published via Redis pub/sub
|
||
- SSE endpoint polls progress
|
||
|
||
---
|
||
|
||
## 5. Packages/WEB Analysis
|
||
|
||
### 5.1 Module Structure
|
||
|
||
```
|
||
packages/web/
|
||
├── app/
|
||
│ ├── page.tsx # Scenario list + wizard
|
||
│ ├── layout.tsx # Root layout
|
||
│ ├── providers.tsx # React Query, etc.
|
||
│ ├── globals.css # Tailwind
|
||
│ ├── scenarios/
|
||
│ │ └── [id]/
|
||
│ │ └── page.tsx # Scenario detail view
|
||
│ ├── compare/
|
||
│ │ └── page.tsx # Scenario comparison
|
||
│ └── api-types/ # Auto-generated OpenAPI types
|
||
├── components/
|
||
│ ├── ui/ # shadcn/ui components
|
||
│ ├── DataGrid/ # AG Grid wrapper
|
||
│ ├── ScenarioWizard/ # Input wizard form
|
||
│ ├── Charts/ # Recharts visualizations
|
||
│ └── KpiCard/ # KPI display card
|
||
└── lib/
|
||
└── api.ts # TypeScript API client
|
||
```
|
||
|
||
### 5.2 Frontend Tech Stack
|
||
|
||
- **Next.js 14** App Router
|
||
- **TypeScript** (strict mode)
|
||
- **shadcn/ui** + Tailwind CSS
|
||
- **TanStack Query** (React Query)
|
||
- **AG Grid Community** (DataGrid)
|
||
- **Recharts** (KPIs)
|
||
- **Zustand** (lightweight state)
|
||
|
||
---
|
||
|
||
## 6. Domain Context (Indian RE Bidding)
|
||
|
||
### 6.1 Key Concepts
|
||
|
||
- **PPA:** Power Purchase Agreement at tariff (₹/kWh)
|
||
- **RTC CUF:** Round-the-clock capacity factor developer commits to
|
||
- **DSM:** Deviation Settlement Mechanism penalties
|
||
- **IDC:** Interest During Construction
|
||
- **115BAA:** Indian tax regime (22% + cess = 25.17%)
|
||
- **DSCR:** Debt Service Coverage Ratio
|
||
- **D:E:** Debt-to-Equity ratio (typically 75:25)
|
||
|
||
### 6.2 Currency
|
||
|
||
- **Crore (Cr)** = 10 million INR (1 Cr = 1,00,00,000)
|
||
- **Lakh** = 100 thousand INR
|
||
- Capex quoted in Cr/MW or INR/Wp
|
||
|
||
---
|
||
|
||
## 7. Sprint Status
|
||
|
||
| Sprint | Goal | Status |
|
||
|--------|------|--------|
|
||
| S0 | Repo setup, CI, API/Web skeleton | Complete |
|
||
| S1 | Solar + Wind + BESS generation | Complete |
|
||
| S2 | Capex + IDC calculation | In Progress |
|
||
| S3 | 3-statement financial model | Pending |
|
||
| S4 | Debt sizing + scheduling | Pending |
|
||
| S5 | IRR/tariff solver | Pending |
|
||
| S6 | Full scenario runner | Pending |
|
||
| S7 | Excel parity gate | Pending |
|
||
| S8 | Sensitivity sweeps | Pending |
|
||
|
||
---
|
||
|
||
## 8. Technical Constraints & Decisions
|
||
|
||
### 8.1 Working Agreements (from PROJECT.md)
|
||
|
||
1. Engine is UI-agnostic (pip-installable package)
|
||
2. CostItem table model (not flat fields)
|
||
3. Three nested iterations: tariff → debt → IDC
|
||
4. IDC has independent equity/debt drawdowns
|
||
5. Two DSCR compliance knobs
|
||
6. Sync-async hybrid: all runs through Arq queue
|
||
7. SQLite v0, Parquet for timeseries
|
||
8. **Excel parity is sacred** — must match user Excel within 0.1%
|
||
9. Coverage ≥85%
|
||
10. mypy strict mode
|
||
11. One DataGrid component (shared across 5+ places)
|
||
|
||
### 8.2 Testing
|
||
|
||
- Unit tests for every public function
|
||
- Integration tests for modules
|
||
- **Parity gate** — tests against user's Excel gold scenarios
|
||
- Location: `packages/engine/tests/`
|
||
- Fixtures: `packages/engine/tests/fixtures/`
|
||
|
||
---
|
||
|
||
## 9. Observations & Potential Issues
|
||
|
||
### 9.1 Strong Points
|
||
|
||
1. **Clean architecture** — engine/API/web separation well-enforced
|
||
2. **Pydantic schemas** — single source of truth for types
|
||
3. **Comprehensive financial model** — 3-statement + depreciation + tax
|
||
4. **Multiple debt schedule shapes** — flexible repayment
|
||
5. **Production-ready** — Ruff, mypy, pytest, coverage
|
||
6. **Async backend** — Redis queue for scaling
|
||
7. **TypeScript types** — auto-generated from OpenAPI
|
||
|
||
### 9.2 Potential Concerns
|
||
|
||
1. **IDC fixed-point** — may need more robust convergence handling
|
||
2. **Parity gate** — not yet validated against user Excel
|
||
3. **Multi-user** — SQLite v0, needs Postgres for v2
|
||
4. **Test coverage gaps** — some modules newly added
|
||
5. **Wind power curve** — generic, may need calibration
|
||
6. **Solar profiles** — only 3 locations (RJ, KA, GJ)
|
||
|
||
### 9.3 Missing/Incomplete (from git status)
|
||
|
||
The git status shows many new untracked files:
|
||
- `packages/engine/src/remodel_engine/capex/` (existing, modified)
|
||
- New modules for dispatch, commercial, debt, financial, irr, solver, scenarios, io
|
||
- `packages/web/app/compare/` (new page)
|
||
- Various test updates
|
||
|
||
---
|
||
|
||
## 10. Recommendations for Discussion
|
||
|
||
1. **Validation Priority:** Run the Excel parity gate with user-supplied gold scenario to verify model accuracy before proceeding to next sprints
|
||
|
||
2. **Test Coverage:** Some newly-added modules (dispatch, commercial, irr) have limited test coverage — prioritize before shipping
|
||
|
||
3. **DataGrid Usage:** Single AG Grid component exists but needs verification across all 5+ use cases
|
||
|
||
4. **Database Migration:** SQLite works for v0, but PostgreSQL planning would help architecture decisions
|
||
|
||
5. **Wind Profile Calibration:** Generic wind power curve may need location-specific calibration for Indian sites
|
||
|
||
6. **Performance:** 30-second target may be achievable, but needs benchmarking with realistic scenarios
|
||
|
||
---
|
||
|
||
## 11. File Locations Reference
|
||
|
||
### Key Source Files
|
||
|
||
| Component | Path |
|
||
|-----------|------|
|
||
| Scenario input schema | `packages/engine/src/remodel_engine/schemas/scenario.py` |
|
||
| Generation simulation | `packages/engine/src/remodel_engine/generation/solar.py` |
|
||
| Wind simulation | `packages/engine/src/remodel_engine/generation/wind.py` |
|
||
| BESS model | `packages/engine/src/remodel_engine/generation/bess_state.py` |
|
||
| RTC dispatch | `packages/engine/src/remodel_engine/dispatch/hybrid_rtc.py` |
|
||
| Capex calculation | `packages/engine/src/remodel_engine/capex/cost_items.py` |
|
||
| IDC calculation | `packages/engine/src/remodel_engine/capex/idc.py` |
|
||
| P&L | `packages/engine/src/remodel_engine/financial/pnl.py` |
|
||
| CFS | `packages/engine/src/remodel_engine/financial/cfs.py` |
|
||
| Balance Sheet | `packages/engine/src/remodel_engine/financial/bs.py` |
|
||
| Depreciation | `packages/engine/src/remodel_engine/financial/depreciation.py` |
|
||
| Tax | `packages/engine/src/remodel_engine/financial/tax.py` |
|
||
| Debt sizing | `packages/engine/src/remodel_engine/debt/sizing.py` |
|
||
| Debt schedule | `packages/engine/src/remodel_engine/debt/schedule.py` |
|
||
| IRR metrics | `packages/engine/src/remodel_engine/irr/metrics.py` |
|
||
| Tariff solver | `packages/engine/src/remodel_engine/solver/tariff.py` |
|
||
| Scenario runner | `packages/engine/src/remodel_engine/scenarios/runner.py` |
|
||
| CLI | `packages/engine/src/remodel_engine/cli.py` |
|
||
| API main | `packages/api/src/remodel_api/main.py` |
|
||
| Scenario endpoints | `packages/api/src/remodel_api/routers/scenarios.py` |
|
||
| Background tasks | `packages/api/src/remodel_api/workers/tasks.py` |
|
||
| Web API client | `packages/web/lib/api.ts` |
|
||
| Main page | `packages/web/app/page.tsx` |
|
||
|
||
---
|
||
|
||
*End of investigation report.* |