21- 22- 23-from sqlalchemy.orm import Session 24- 25-from app.adapters.base import ( 26- ProviderAdapter, ProviderAuthError, ProviderNotFoundError, ProviderRateLimitError, 27-) 28-from app.adapters.resolver import merge_statement_line_items, resolve_line_items 29:from app.adapters.validation import ValidationReport, validate_line_items 30-from app.core.config import get_settings 31-from app.core.db import SessionLocal 32-from app.core.logging import get_logger 33-from app.engines.identity import resolve_company_identity 34-from app.engines.reference_data import canonical_mic, exchange_for_mic 35-from app.models import ( 36- BalanceSheet, CashFlow, Company, Country, DataQuality, Estimate, Exchange, FinancialPeriod, 37- Industry, IncomeStatement, Price, Sector, Security, Shares, Source, 38-) 39-from app.workers.celery_app import celery_app 40- 41-logger = get_logger(__name__) -- 487- ) 488- secondary_tier = secondary_adapter.tier if (secondary_adapter is not None and li_b is not None) else None 489- 490- income = fp.income_statement or IncomeStatement(financial_period_id=fp.id) 491- resolved, conflicts = resolve_line_items( 492- li, li_b, _INCOME_FIELDS, adapter.tier, secondary_tier 493- ) 494- merged_report = ValidationReport() 495: resolved = validate_line_items( 496- resolved, 497- merged_report, 498- row_key=f"{ticker}:{p.period_end}:{p.period_type}:income", 499- ) 500- for field, value in resolved.items(): 501- setattr(income, field, value) 502- db.add(income) 503- if conflicts: 504- _record_conflicts(db, "income_statements", fp.id, conflicts, source, secondary_source) 505- 506- balance = fp.balance_sheet or BalanceSheet(financial_period_id=fp.id) 507- resolved, conflicts = resolve_line_items( 508- li, li_b, _BALANCE_FIELDS, adapter.tier, secondary_tier 509- ) 510- merged_report = ValidationReport() 511: resolved = validate_line_items( 512- resolved, 513- merged_report, 514- row_key=f"{ticker}:{p.period_end}:{p.period_type}:balance", 515- ) 516- for field, value in resolved.items(): 517- setattr(balance, field, value) 518- db.add(balance) 519- if conflicts: 520- _record_conflicts(db, "balance_sheets", fp.id, conflicts, source, secondary_source) 521- 522- cash_flow = fp.cash_flow or CashFlow(financial_period_id=fp.id) 523- resolved, conflicts = resolve_line_items( 524- li, li_b, _CASH_FLOW_FIELDS, adapter.tier, secondary_tier 525- ) 526- merged_report = ValidationReport() 527: resolved = validate_line_items( 528- resolved, 529- merged_report, 530- row_key=f"{ticker}:{p.period_end}:{p.period_type}:cash_flow", 531- ) 532- for field, value in resolved.items(): 533- setattr(cash_flow, field, value) 534- db.add(cash_flow) 535- if conflicts: 536- _record_conflicts(db, "cash_flows", fp.id, conflicts, source, secondary_source) 537- 538- shares = fp.shares or Shares(financial_period_id=fp.id) 539- resolved, conflicts = resolve_line_items( 540- li, li_b, _SHARES_FIELDS, adapter.tier, secondary_tier 541- ) 542- merged_report = ValidationReport() 543: resolved = validate_line_items( 544- resolved, 545- merged_report, 546- row_key=f"{ticker}:{p.period_end}:{p.period_type}:shares", 547- ) 548- for field, value in resolved.items(): 549- setattr(shares, field, value) 550- db.add(shares) 551- if conflicts: 552- _record_conflicts(db, "shares", fp.id, conflicts, source, secondary_source) 553- 554- # AUDIT FIX (final master pass, §21) — the fourth "engine built, never wired" defect. 555- # `ProviderAdapter.get_estimates()` is implemented by FMP and by the demo adapter,