> ## Documentation Index
> Fetch the complete documentation index at: https://docs.forii.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> Four layers: crawlers, Postgres, compute, serving — and the rules that hold them together.

## The four layers

```
  crawlers            postgres              compute               serve
┌───────────┐   ┌──────────────┐   ┌───────────────┐   ┌──────────────┐
│ instruments│   │ instruments  │   │ metric        │   │ FastAPI      │
│ historical │──▶│ daily_candles│──▶│ registry       │──▶│ 1:1 REST     │
│ (Kite API) │   │ company_info │   │ (@metric,     │   │ + Python     │
└───────────┘   │ financial_   │   │  dual-tag)     │   │   library    │
                │   data      │   │ panels/*.csv   │   └──────┬───────┘
                └──────────────┘   └───────┬───────┘          │
                                          ▼                  ▼
                                   ML pipeline          dashboards /
                                   (rank stocks)       notebooks / Lean
```

## The packages

| package | role | contents |
| - | - | - |
| `db-interface` | shared DB layer | models, session, settings — no duplicates anywhere |
| `instruments-crawler` | ingest | NSE instruments from Kite |
| `historical-crawler` | ingest | 25 years of daily candles |
| `predictors` | compute | CSV staging, metric registry, panel builder |
| `market-api` | serve | Python library + thin 1:1 REST + one CLI |
| `sector-tree`, `index-constituents` | reference | sector hierarchy, index membership |

## Rules

1. The metric registry is the single source of predictor truth — serving layers
   import it, never duplicate it.
2. `MetricContext` is the lookahead firewall: metric functions only see data
   with `period_end <= t - asof_lag`.
3. Panels are batch artifacts — built on a schedule by
   `python -m market_api.cli build-panel --all`, read back by `get_panel()`,
   never computed on the request path.
4. The REST layer maps endpoint → library function, converts exceptions to
   HTTP codes (`LookupError → 404`, `ValueError → 400`), and does nothing else.
5. Production code budget: `predictors` stays under 500 lines.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.