Sangeetha-Grantha

Metadata Value
Status Ready — unblocked, cleanup pending
Version 1.1.0
Last Updated 2026-07-19
Author Sangeetha Grantha Team

2026-07-19 — unblocked. This track was paused waiting for the legacy payloads to drain from the corpus. The TRACK-093 re-import has done that: all 1,238 imported_krithis.parsed_payload rows are canonical (CanonicalExtractionDto), with zero legacy ScrapedKrithiMetadata.

SELECT CASE WHEN parsed_payload ? 'sections' THEN 'canonical'
            WHEN parsed_payload ? 'rawLyrics' OR parsed_payload ? 'scrapedAt' THEN 'legacy'
            ELSE 'other' END AS shape, COUNT(*)
FROM imported_krithis GROUP BY 1;
-- canonical | 1238

The remaining work is the deletion cleanup: remove ScrapedKrithiMetadata and the dual-format fallback branches now that nothing produces or reads the old shape. Re-run the query above immediately before deleting — the guarantee is “no legacy rows right now”, not a schema constraint, so a stray import between now and then would reintroduce one.

Goal

Converge on CanonicalExtractionDto as the single payload format for imported_krithis.parsed_payload and deprecate ScrapedKrithiMetadata. Eliminate the format schism that caused TRACK-094’s silent lyric persistence failure.

Background — The Format Schism

The import pipeline has two competing payload formats that evolved independently across different tracks:

Format Introduced Producer Location
ScrapedKrithiMetadata TRACK-001 (original bulk import) Kotlin WebScrapingService backend/api/.../services/WebScrapingService.kt
CanonicalExtractionDto TRACK-041 (enhanced sourcing) Python extraction worker shared/domain/.../import/CanonicalExtractionDto.kt

How the schism formed

  1. TRACK-001–013: Built the full import pipeline around ScrapedKrithiMetadata — Kotlin scrapes HTML, parses sections, stores in parsed_payload, LyricVariantPersistenceService reads it at approval time
  2. TRACK-041: Introduced CanonicalExtractionDto as the “universal output contract” for all extraction adapters. Defined in shared domain module.
  3. TRACK-064: Migrated extraction to Python worker. ExtractionResultProcessor stores CanonicalExtractionDto in parsed_payload.
  4. Gap: LyricVariantPersistenceService was never updated to read CanonicalExtractionDto. The old format deserialization failed silently.

Impact

Implementation Plan

Phase 1: Audit & Document (current state)

Phase 2: Deprecate ScrapedKrithiMetadata

Phase 3: Remove Dead Kotlin Scraper from Active Code Paths

Phase 4: Cleanup

Decision Record

Decision: CanonicalExtractionDto is the single canonical format for extraction payloads going forward.

Rationale:

What NOT to do:

Related Tracks

Ref: application_documentation/10-implementations/track-096-payload-format-convergence.md