feat(13-01): widen SourceType to open union, add NormalizedTenderFields.fingerprint

SourceType now covers 'doe-opendata' | 'ai-netserver' | 'cosinex-dtvp'
(13-RESEARCH Pattern 1) so the Plan 13-04/05 adapters can register
without further type-contract changes. NormalizedTenderFields gains an
optional fingerprint field for the SCHEMA-03 dedup resolver (Plan
13-03) to populate later. tsc --noEmit clean; full API suite green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-23 08:38:59 +02:00
parent 447fb74e0c
commit c2a60212fe
+14 -3
View File
@@ -8,10 +8,13 @@
/**
* Identifies which upstream source a raw record originated from.
* Only 'doe-opendata' exists in this phase (Phase 10); scraping/RSS/email
* sources are added in later phases (13/14) without changing this contract.
* Extended in Phase 13 (13-RESEARCH Pattern 1) from a single-literal type
* to an open union so the NetServer (Plan 13-04) and cosinex/DTVP
* (Plan 13-05) adapters can be added without further breaking changes.
* This union widening is the only breaking type change in Plan 13-01,
* and it's contained locally (no runtime behavior change here).
*/
export type SourceType = 'doe-opendata';
export type SourceType = 'doe-opendata' | 'ai-netserver' | 'cosinex-dtvp';
/**
* A single notice as fetched and lightly parsed from a source, before
@@ -80,4 +83,12 @@ export interface NormalizedTenderFields {
/** sha256(title + deadlineAt + estimatedValue + status) — SCHEMA-02 change-detection hook. */
contentHash: string;
publishedAt: Date;
/**
* SCHEMA-03 (D-04) — cross-source dedup key, computed by tenderFingerprint()
* (Plan 13-01 Task 1). Optional here: the normalizer does not set it yet
* (that wiring lands in Plan 13-03's dedup resolver) — kept optional so
* this additive field doesn't break the Phase-10/11 normalizer contract
* before the resolver exists.
*/
fingerprint?: string;
}