Add history window controls and expand taxonomy pack support
- add 3Y/5Y/10Y financial history filtering and reorganize normalization details UI - add new fiscal taxonomy surface/income bridge/KPI packs and update Rust taxonomy loading - auto-detect Homebrew SQLite for native `sqlite-vec` in local dev/e2e with docs and env guidance
This commit is contained in:
@@ -15,10 +15,9 @@ The taxonomy system defines all financial surfaces, computed ratios, and KPIs us
|
||||
│ core.kpis.json - Sector-specific KPIs │
|
||||
│ core.income-bridge.json - Income statement mapping rules │
|
||||
│ │
|
||||
│ bank_lender.surface.json - Bank-specific surfaces │
|
||||
│ insurance.surface.json - Insurance-specific surfaces │
|
||||
│ reit_real_estate.surface.json - REIT-specific surfaces │
|
||||
│ broker_asset_manager.surface.json - Asset manager surfaces │
|
||||
│ *.surface.json - Core plus industry-specific packs │
|
||||
│ *.income-bridge.json - Pack-specific universal income maps │
|
||||
│ kpis/*.kpis.json - Pack KPI bundles │
|
||||
└──────────────────────────┬──────────────────────────────────────┘
|
||||
│
|
||||
┌─────────────────┼─────────────────┐
|
||||
@@ -67,21 +66,24 @@ rust/taxonomy/fiscal/v1/
|
||||
├── universal_income.surface.json
|
||||
│
|
||||
├── bank_lender.surface.json
|
||||
├── bank_lender.income-bridge.json
|
||||
├── bank_lender.kpis.json
|
||||
│
|
||||
├── insurance.surface.json
|
||||
├── insurance.income-bridge.json
|
||||
├── insurance.kpis.json
|
||||
│
|
||||
├── reit_real_estate.surface.json
|
||||
├── reit_real_estate.income-bridge.json
|
||||
├── reit_real_estate.kpis.json
|
||||
│
|
||||
├── broker_asset_manager.surface.json
|
||||
├── broker_asset_manager.income-bridge.json
|
||||
├── broker_asset_manager.kpis.json
|
||||
│
|
||||
├── agriculture.surface.json
|
||||
├── contractors_construction.surface.json
|
||||
├── contractors_federal_government.surface.json
|
||||
├── development_stage.surface.json
|
||||
├── entertainment_*.surface.json
|
||||
├── extractive_mining.surface.json
|
||||
├── mortgage_banking.surface.json
|
||||
├── title_plant.surface.json
|
||||
├── franchisors.surface.json
|
||||
├── not_for_profit.surface.json
|
||||
├── plan_defined_*.surface.json
|
||||
├── plan_health_welfare.surface.json
|
||||
├── real_estate_*.surface.json
|
||||
├── software.surface.json
|
||||
├── steamship.surface.json
|
||||
└── kpis/
|
||||
└── *.kpis.json
|
||||
|
||||
@@ -104,6 +106,7 @@ lib/generated/ # Auto-generated, gitignored
|
||||
## Surface Definitions
|
||||
|
||||
Surfaces represent canonical financial line items. Each surface maps XBRL concepts to a standardized key.
|
||||
Generated TypeScript statement catalogs are built from the deduped union of core plus unique non-core surfaces, with core definitions winning for shared universal keys.
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -124,17 +127,17 @@ Surfaces represent canonical financial line items. Each surface maps XBRL concep
|
||||
|
||||
### Surface Fields
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `surface_key` | string | Unique identifier (snake_case) |
|
||||
| `statement` | enum | `income`, `balance`, `cash_flow`, `equity`, `comprehensive_income` |
|
||||
| `label` | string | Human-readable label |
|
||||
| `category` | string | Grouping category |
|
||||
| `order` | number | Display order |
|
||||
| `unit` | enum | `currency`, `percent`, `ratio`, `shares`, `count` |
|
||||
| `rollup_policy` | string | How to aggregate: `direct_only`, `direct_or_formula`, `aggregate_children`, `formula_only` |
|
||||
| `allowed_source_concepts` | string[] | XBRL concepts that map to this surface |
|
||||
| `formula_fallback` | object | Optional formula when no direct mapping |
|
||||
| Field | Type | Description |
|
||||
| ------------------------- | -------- | ------------------------------------------------------------------------------------------ |
|
||||
| `surface_key` | string | Unique identifier (snake_case) |
|
||||
| `statement` | enum | `income`, `balance`, `cash_flow`, `equity`, `comprehensive_income` |
|
||||
| `label` | string | Human-readable label |
|
||||
| `category` | string | Grouping category |
|
||||
| `order` | number | Display order |
|
||||
| `unit` | enum | `currency`, `percent`, `ratio`, `shares`, `count` |
|
||||
| `rollup_policy` | string | How to aggregate: `direct_only`, `direct_or_formula`, `aggregate_children`, `formula_only` |
|
||||
| `allowed_source_concepts` | string[] | XBRL concepts that map to this surface |
|
||||
| `formula_fallback` | object | Optional formula when no direct mapping |
|
||||
|
||||
## Computed Definitions
|
||||
|
||||
@@ -143,16 +146,18 @@ Computed definitions describe ratios and derived metrics. They are split into tw
|
||||
### Phase 1: Filing-Derived (Rust computes)
|
||||
|
||||
Ratios computable from filing data alone:
|
||||
|
||||
- **Margins**: gross_margin, operating_margin, ebitda_margin, net_margin, fcf_margin
|
||||
- **Returns**: roa, roe, roic, roce
|
||||
- **Financial Health**: debt_to_equity, net_debt_to_ebitda, cash_to_debt, current_ratio
|
||||
- **Per-Share**: revenue_per_share, fcf_per_share, book_value_per_share
|
||||
- **Growth**: revenue_yoy, net_income_yoy, eps_yoy, fcf_yoy, *_cagr
|
||||
- **Growth**: revenue_yoy, net_income_yoy, eps_yoy, fcf_yoy, \*\_cagr
|
||||
|
||||
### Phase 2: Market-Derived (TypeScript computes)
|
||||
|
||||
Ratios requiring external price data:
|
||||
- **Valuation**: market_cap, enterprise_value, price_to_earnings, price_to_fcf, price_to_book, ev_to_*
|
||||
|
||||
- **Valuation**: market*cap, enterprise_value, price_to_earnings, price_to_fcf, price_to_book, ev_to*\*
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -186,13 +191,13 @@ Ratios requiring external price data:
|
||||
|
||||
### Computation Types
|
||||
|
||||
| Type | Fields | Description |
|
||||
|------|--------|-------------|
|
||||
| `ratio` | numerator, denominator | Simple division |
|
||||
| `yoy_growth` | source | Year-over-year percentage change |
|
||||
| `cagr` | source, years | Compound annual growth rate |
|
||||
| `per_share` | source, shares_key | Divide by share count |
|
||||
| `simple` | formula | Custom formula expression |
|
||||
| Type | Fields | Description |
|
||||
| ------------ | ---------------------- | -------------------------------- |
|
||||
| `ratio` | numerator, denominator | Simple division |
|
||||
| `yoy_growth` | source | Year-over-year percentage change |
|
||||
| `cagr` | source, years | Compound annual growth rate |
|
||||
| `per_share` | source, shares_key | Divide by share count |
|
||||
| `simple` | formula | Custom formula expression |
|
||||
|
||||
## Pack Inheritance
|
||||
|
||||
@@ -208,6 +213,8 @@ if !matches!(pack, FiscalPack::Core) {
|
||||
|
||||
This ensures consistency across packs while allowing sector-specific income statements.
|
||||
|
||||
Auto-classification remains conservative. Pack selection uses concept and role scoring, then falls back to `core` when the top match is weak or ambiguous.
|
||||
|
||||
## Build Pipeline
|
||||
|
||||
```bash
|
||||
@@ -223,22 +230,24 @@ bun run build
|
||||
|
||||
### package.json Scripts
|
||||
|
||||
| Script | Description |
|
||||
|--------|-------------|
|
||||
| `generate` | Run taxonomy generator |
|
||||
| `build:sidecar` | Build Rust binary |
|
||||
| `build` | Generate + Next.js build |
|
||||
| `lint` | Generate + TypeScript check |
|
||||
| Script | Description |
|
||||
| --------------- | --------------------------- |
|
||||
| `generate` | Run taxonomy generator |
|
||||
| `build:sidecar` | Build Rust binary |
|
||||
| `build` | Generate + Next.js build |
|
||||
| `lint` | Generate + TypeScript check |
|
||||
|
||||
## Validation
|
||||
|
||||
The generator validates:
|
||||
|
||||
1. No duplicate surface keys within the same statement
|
||||
2. All ratio numerators/denominators reference existing surfaces
|
||||
3. Required fields present on all definitions
|
||||
4. Valid statement/unit/category values
|
||||
|
||||
Run validation:
|
||||
|
||||
```bash
|
||||
bun run generate # Validates during generation
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user