diff --git a/docs/dolt-integration-plan.md b/docs/dolt-integration-plan.md index abf477e..da753c1 100644 --- a/docs/dolt-integration-plan.md +++ b/docs/dolt-integration-plan.md @@ -97,7 +97,11 @@ record the conclusion in this doc. them, not as derived quarters:** duration facts (revenue, net income, diluted EPS, CFO, capex, EBITDA inputs) retain the filing's normalized **cumulative YTD/FY** value for the (period_start → period_end) span; balance-sheet facts (cash+ST - investments, total debt, diluted shares) are **period-end** values. **Nothing + investments, total debt, shares outstanding) are **period-end** values. + ``shares_outstanding`` is a point-in-time count + (``dei:EntityCommonStockSharesOutstanding``), not the weighted-average diluted + share count — both consumers (est. market cap, YoY dilution) want a + point-in-time value. **Nothing derived is frozen into a row:** discrete quarters (10-Q YTD deltas, Q4 = FY − Q1..Q3), TTM, YoY and the quarter-tape series are all computed **at read time** by picking the newest valid accepted_at snapshot for *each* required period — so @@ -128,7 +132,9 @@ record the conclusion in this doc. ## Import framework Every importer: idempotent per revision (same Dolt commit / archive checksum → -`no_op`, zero row changes); staging tables first; promotion in one transaction; +`no_op`, zero row changes); stage into a representation outside the live tables +first (in-memory for the small workstream-A sources; a file/table handle is fine +if workstream B ever needs it); promotion in one transaction; safe to retry; a failed or unchanged run leaves the current dataset untouched. Record every attempt in `data_import_runs`. @@ -193,7 +199,7 @@ Workstream A: cached fundamental scores stale. **Sources differ per field** — do not assume all five come from SEC: `pe_ratio` and `market_cap` from the newest valid snapshots × latest PostgreSQL close, each with its own formula — `pe_ratio` = latest close / - TTM diluted EPS; `market_cap` = issuer-wide diluted shares × latest close; + TTM diluted EPS; `market_cap` = issuer-wide shares outstanding × latest close; `revenue_growth` from the snapshots alone; `earnings_surprise` and `next_earnings_date` from `earnings_events` (the Dolt earnings feed — these two do not exist in SEC facts). Before activation the job imports snapshots only @@ -234,16 +240,19 @@ that scoring already reads, refreshed daily by step (c) after activation. | FCF margin | (TTM CFO − capex) / revenue | snapshot | | Net cash / net debt | cash + ST investments − total debt | snapshot | | Net debt / EBITDA | net debt / TTM EBITDA | snapshot | -| Share count Δ YoY | diluted shares vs year ago | snapshot | +| Share count Δ YoY | shares outstanding vs year ago | snapshot | | Trailing P/E | price / TTM diluted EPS | request time | | FCF yield | TTM FCF / est. market cap | request time | -| Est. market cap | issuer-wide diluted shares × ticker price | request time | +| Est. market cap | issuer-wide shares outstanding × ticker price | request time | | Earnings surprise history | last 4+ from `earnings_events` | query | -**Market cap is an estimate** (issuer-wide diluted shares × one ticker's price — -approximate for multi-class issuers). Label it "est." in the UI and round -aggressively rather than withholding it; false precision is the failure mode, not -the approximation. +**Market cap is an estimate** (issuer-wide shares outstanding × one ticker's price — +approximate for multi-class issuers). For a multi-class issuer, derive the +issuer-wide share count **either** from the consolidated cover-page figure **or** +by summing the class-specific `dei:EntityCommonStockSharesOutstanding` facts +(GOOG + GOOGL) — **never both**, or the count double-counts. Label it "est." in the +UI and round aggressively rather than withholding it; false precision is the failure +mode, not the approximation. **Units follow existing app conventions:** percentages are percentage points (21.0 = 21%), P/E and net-debt/EBITDA are multiples, market cap and net debt are