fix(fundamentals): API v1 review — multi-class pricing, reads contract, guards

1. Multi-class subject is priced by the REQUESTED ticker: the peer group's
   representative for the subject CIK is overridden to the requested ticker_id
   (other issuers pick a deterministic-by-symbol rep), so GOOGL's P/E uses
   GOOGL's price, not GOOG's. Differing-price GOOG/GOOGL test added.
2. reads matches the selected contract: header is null when there is no read;
   by_key is a fixed map over every metric key plus pe and fcf_yield, null when
   unavailable (was a sparse dict).
3. Earnings use the New York calendar date; same-day is UPCOMING (days_until 0),
   recent is strictly earlier.
4. Valuation is null when there is no usable price (> 0 required for P/E and
   market cap); when present, price_date is non-null.

Added a real router/API-envelope test with a seeded legacy record (the endpoint,
not just the schema merge). 6 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-22 21:49:17 +02:00
co-authored by Claude Opus 4.8
parent 459a925e36
commit b3dcf356a6
3 changed files with 124 additions and 38 deletions
+6 -3
View File
@@ -58,10 +58,13 @@ class Valuation(BaseModel):
class FundamentalsReads(BaseModel):
"""Deterministic text outputs, separate from the numeric metrics."""
"""Deterministic text outputs, separate from the numeric metrics.
header: str = ""
metrics: dict[str, str] = {} # {metric_key: read}
``by_key`` is a fixed map over every metric key plus ``pe`` and ``fcf_yield``,
each a read string or null. ``header`` is null when there is no read at all."""
header: str | None = None
by_key: dict[str, str | None] = {}
class FundamentalResponse(BaseModel):