Buyer / data-model gap
Protected develop@622e5e6c3d534f230c390f10e3832efadfc01825 persists transformed synchronous ETL output as one text value assembled by EtlService:
The implementation intentionally preserves commas and colons inside values, e.g. NAME:A:B,C,, and nested arrays/objects are embedded as compact JSON. Because the outer representation has no escaping, length-prefixing, schema, or canonical parser contract, the stored text is not uniquely reversible: a downstream consumer cannot distinguish field delimiters from legitimate value commas/colons without reconstructing Java-specific transformation knowledge.
docs/etl/bounded-atomic-batches.md already calls typed target schemas a separate milestone. This issue makes that buyer-visible gap explicit rather than treating processed_data.data as a durable interoperable schema.
Status: known_gap. Do not overlap current #198/#199 EtlService amount-integrity writer; implementation should start only after that source lane is stable/integrated.
RCA
- Immediate cause: transformed fields are concatenated with
: and , delimiters while arbitrary string values may contain those same characters.
- Technical root cause:
processed_data.data is a historical display-like serialization rather than a versioned typed storage/event contract.
- Control failure: current tests prove that comma/colon values are preserved, but they do not prove a unique round trip from persisted representation back to the original transformed field map.
- Acquisition/interoperability risk: data lineage, schema evolution, replay/export, downstream SQL/analytics, connector handoff, and independent clients must reverse-engineer implementation details; different records can have ambiguous textual interpretations.
Bounded architecture options
- Preferred — versioned typed canonical representation. Define a schema-versioned JSON/JSONB or normalized relational representation for transformed records with deterministic field semantics, explicit version identity, size bounds, migration/compatibility rules, and a lossless round-trip test. Choose the physical form only after consumer inventory and PostgreSQL query/index requirements are known.
- Alternative — explicit length-prefixed/escaped text codec. Feasible but inferior for external interoperability and schema evolution unless compatibility requirements force text storage.
- Reject — continue undocumented delimiter parsing. Preserving delimiters without an unambiguous codec is not a data contract.
- Reject — silently rewrite existing rows in place. Historical records require source/consumer inventory, migration rehearsal, rollback/forward-recovery, and integrity verification.
TDD / migration acceptance
- inventory every repository/external consumer of
processed_data.data before physical migration;
- fail-first round-trip tests with commas, colons, Unicode, empty/null values, nested arrays/objects, and field-name normalization collisions;
- define one versioned machine-readable transformed-record schema and compatibility policy;
- representative PostgreSQL migration rehearsal for existing rows, explicitly classifying rows that cannot be unambiguously decoded from the legacy format rather than guessing;
- new writes are lossless and deterministic under the selected representation;
- old/new application compatibility and rollback/forward-recovery are explicit;
- no raw payload or PII is copied into logs merely for migration diagnostics;
- ERD/data model, API/event/connector contracts, data governance/retention, Operability, Traceability and CHANGELOG agree with the integrated physical state;
- descriptive multi-word snake_case for any new owned database objects;
- exact source, realistic database, non-vacuous coverage, security/SBOM/provenance and independent review gates pass before protected integration.
Relationships: #159 canonical documentation; #183/#184 Flyway schema authority; #188 recovery; #198/#199 amount integrity; #165 release/provenance.
Buyer / data-model gap
Protected
develop@622e5e6c3d534f230c390f10e3832efadfc01825persists transformed synchronous ETL output as one text value assembled byEtlService:The implementation intentionally preserves commas and colons inside values, e.g.
NAME:A:B,C,, and nested arrays/objects are embedded as compact JSON. Because the outer representation has no escaping, length-prefixing, schema, or canonical parser contract, the stored text is not uniquely reversible: a downstream consumer cannot distinguish field delimiters from legitimate value commas/colons without reconstructing Java-specific transformation knowledge.docs/etl/bounded-atomic-batches.mdalready calls typed target schemas a separate milestone. This issue makes that buyer-visible gap explicit rather than treatingprocessed_data.dataas a durable interoperable schema.Status:
known_gap. Do not overlap current #198/#199EtlServiceamount-integrity writer; implementation should start only after that source lane is stable/integrated.RCA
:and,delimiters while arbitrary string values may contain those same characters.processed_data.datais a historical display-like serialization rather than a versioned typed storage/event contract.Bounded architecture options
TDD / migration acceptance
processed_data.databefore physical migration;Relationships: #159 canonical documentation; #183/#184 Flyway schema authority; #188 recovery; #198/#199 amount integrity; #165 release/provenance.