Loading documentation...
Where `ingestBySourceId`, per-source adapters, and `loadSourceRegistry` live in the repo. Split from the former data_model inventory.
This document lists TypeScript entrypoints for moving data into fire_data. For pipeline semantics and triggers, see pipeline-slices-idempotency-and-triggers.md. For how /explore triggers ingest, see ../application-architecture/explore-fire-data-slice-probe-and-ingest.md.
ingestBySourceId)File: lib/data-model/adapters/_dispatch.ts
export type IngestGrain = 'yearly' | 'daily' export async function ingestBySourceId( supabase: FireDataClient, source_id: number, slices?: readonly unknown[], progress?: IngestProgressCb, runId?: string | null, grain: IngestGrain = 'yearly', ): Promise<IngestResult>
FireDataClient is local: SupabaseClient<FireDataDatabase, 'fire_data'>. When grain === 'daily':
source_id | Adapter forwarded to | Module |
|---|---|---|
1 (BRASK) | ingestBraskDaily | brask.daily.ts (per-month form fan-out) |
2 (BRIS Police) | ingestBrisDaily | bris.daily.ts (single-POST per tier) |
Any other source_id raises Error('Daily ingest not supported for source_id=X.'). Per-source sub-yearly capability is documented in taxonomy-and-eu-firestat-alignment.md and enforced upstream via sources.supports_subyear. See pipeline-slices-idempotency-and-triggers.md §10.4 for the BRIS Police daily tier model.
Types below use FireDataClient = SupabaseClient<FireDataDatabase, 'fire_data'>. Slice shapes, SliceResult, IngestResult, and IngestProgressCb live in lib/data-model/types.ts. YearlyPhaseEmitter is lib/data-model/adapters/_phaseEmit.ts (optional per-slice progress for yearly adapters).
Registry
File: lib/data-model/adapters/_registry.ts
export async function loadSourceRegistry( supabase: FireDataClient, source_id: number, ): Promise<SourceRegistry>
Also exported: catKey(dim_code: number, native_name: string): string.
BRIS
File: lib/data-model/adapters/bris.ts
Police /aggregate building-type requests are built in policeAggregateBuildingParams: Matrikkel leaf native_code → buildingTypeIdsOverride before any RESIDENTIAL → whole-Bolig fallback. Fire type and region slices already send a single native_code per slice. See adapter-mappings/filter-axes-native-to-filter-id.md («ETL rule — native wins»).
export async function ingestBrisSlice( supabase: FireDataClient, registry: SourceRegistry, rawSlice: BrisSlice, runId?: string | null, emitter?: YearlyPhaseEmitter, ): Promise<SliceResult> export async function ingestBrisSource( supabase: FireDataClient, sub: BrisSubSource, slices: readonly BrisSlice[], progress?: IngestProgressCb, runId?: string | null, ): Promise<IngestResult>
BRASK
File: lib/data-model/adapters/brask.ts
export async function ingestBraskSlice( supabase: FireDataClient, registry: SourceRegistry, slice: BraskSlice, runId?: string | null, emitter?: YearlyPhaseEmitter, ): Promise<SliceResult> export async function ingestBrask( supabase: FireDataClient, slices: readonly BraskSlice[], progress?: IngestProgressCb, runId?: string | null, ): Promise<IngestResult>
BRASK — daily grain
File: lib/data-model/adapters/brask.daily.ts
export async function ingestBraskDailySlice( supabase: FireDataClient, registry: SourceRegistry, slice: BraskDailySlice, runId?: string | null, progress?: IngestProgressCb, ): Promise<SliceResult> export async function ingestBraskDaily( supabase: FireDataClient, slices: readonly BraskDailySlice[], progress?: IngestProgressCb, runId?: string | null, ): Promise<IngestResult>
BRIS — daily grain (Police only)
File: lib/data-model/adapters/bris.daily.ts
export interface BrisDailySlice extends BrisSlice { date_start: string // YYYY-MM-DD inclusive date_end: string // YYYY-MM-DD inclusive } export async function ingestBrisDailySlice( supabase: FireDataClient, registry: SourceRegistry, slice: BrisDailySlice, runId?: string | null, progress?: IngestProgressCb, ): Promise<SliceResult> export async function ingestBrisDaily( supabase: FireDataClient, slices: readonly BrisDailySlice[], progress?: IngestProgressCb, runId?: string | null, ): Promise<IngestResult>
Slices must carry sub: 'POLICE'; Brigade/DSB are blocked at the BRIS endpoint and the entry guards against them. Internally walks the four-tier probe described in pipeline-slices-idempotency-and-triggers.md §10.4 and reuses the daily helpers shipped for BRASK (fact_daily_slice_ingest_prefetch, upsert_fact_daily_batch, dedupeByNaturalKeyDaily, classifyWritesForDailySlice, buildLedgerEventsDaily).
SSB
File: lib/data-model/adapters/ssb.ts
export async function ingestSsbSlice( supabase: FireDataClient, registry: SourceRegistry, slice: SsbSlice, emitter?: YearlyPhaseEmitter, ): Promise<SliceResult> export async function ingestSsb( supabase: FireDataClient, slices: readonly SsbSlice[], progress?: IngestProgressCb, ): Promise<IngestResult>
lib/data-model/adapters/)| File | Responsibility |
|---|---|
_registry.ts | loadSourceRegistry, catKey |
_dedupe.ts | Natural-key dedupe before upsert |
_validate.ts | Atom rows only (no x00 rollups) |
_factPrefetch.ts | Yearly/daily prefetch RPCs for drift tiers |
_factBulkUpsert.ts | upsert_fact_yearly_batch |
_factDailyBulkUpsert.ts | upsert_fact_daily_batch |
_ledger.ts | Ingest ledger / undo snapshots |
_writeStats.ts | Write classification stats |
_yearWindow.ts | Ingested year window aggregation |
_phaseEmit.ts | Yearly canonical_progress phase emitter |
_braskWebForms.ts | BRASK HTTP/form transport |
_braskWebForms.constants.ts | BRASK axis/URL constants |
brask-yearly-metrics.ts | BRASK tier-1/2 equality helpers |
ingestBySourceId is invoked from app/api/admin/ingest/route.ts (service role, after()), not from random Server Actions./explore still has user-facing app/(main)/explore/actions.ts: triggerSliceIngest inserts fire_data.ingest_runs, then fetches same-origin POST /api/admin/ingest inside after() with the ingest key — it does not import ingestBySourceId directly."use server" modules (app/actions.ts, …) handle auth or non-ETL reads.Only app/api/admin/ingest/route.ts imports ingestBySourceId among app/api/*/route.ts handlers.
When you add a source adapter or change dispatch, update this file and pipeline-slices-idempotency-and-triggers.md so cross-links stay accurate.