Batcher profile wiring + ingestion conflict resolution#98
Conversation
Sink now accepts (Place, *AccessibilityProfile) so the profile travels as a sibling through the pipeline rather than being embedded on Place. Batcher writes places first, then profiles using the UUIDs returned by flush. Counts profiles_written and components downgraded. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…onical pipeline runCanonical configures the batcher with UpsertProfileIngestion and a conflict resolution closure that demotes accessible components to limited on hard conflicts. Telemetry adds profiles_written and profiles_downgraded. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Cover three branches end-to-end against real Postgres+PostGIS: profile writes when tags present, component downgrade on hard conflict, and user_verified rows surviving an ingest unchanged. Also fix the Sink signature in the cross-binary integration test. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Document UpsertProfile/UpsertProfileIngestion in place repo README, v1 tag mapping table in OSM source README, widened Sink signature in sources README, and canonical pipeline description in CLAUDE.md. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Claude finished @koinsaari's task in 5m 16s —— View job PR Review — Batcher profile wiring + ingestion conflict resolution
No blocking issues. The architectural decisions are sound: profile as a 🟡 Nit 1 —
|
|
Claude finished @koinsaari's task in 2m 57s —— View job
PR Review — re-review after pushNo blocking issues. The push addresses Nit 3 from the previous review: Invariant checks (all pass):
🟡 Nit 1 —
|
|
Claude finished @koinsaari's task in 2m 4s —— View job
PR Review — re-review after 752fac4No blocking issues. Nit 3 (RowsAffected, fixed in a86cf06) and Nit 4 (batcher pairing guard, fixed in 752fac4) are both resolved. The guard at Invariant checks (all pass):
Two nits from prior reviews remain open, plus one new nit from this push. 🟡 Nit 1 —
|
…out downgradeProfile
752fac4 to
d46d2a8
Compare
|
Claude finished @koinsaari's task in 2m 9s —— View job
PR Review — re-review after d46d2a8No blocking issues. Nit 5 (unit test for Invariant checks (all pass):
🟡 Nit 1 —
|
This just for forward compatibility for new sources. Can ignore for now
Profile level status is intentionally untouched. this is by design. it's supposed to only touch component level status. |
Summary
sources.Sinkto carry(Place, *AccessibilityProfile)— profile travels as a sibling, never embedded on the place struct, avoiding any ORM cascade confusion(place, profile)pairs, writes places first viaUpsertBatch, then writes profiles using the UUIDs returned by flushrunCanonicalwires inUpsertProfileIngestionandresolveIngestionConflicts— hard conflicts from OSM tags demote the component tolimitedrather than rejecting (API path rejects; ingestion corrects)user_verifiedrow survives ingest unchangedTest plan
go test ./...— 293 unit tests passgo test -tags integration ./...— 389 tests pass including 2 new canonical pipeline testsPart of #10. Implements the ingestion-side conflict policy from #62 (component-level downgrade; profile-level
overall_statusintentionally untouched).🤖 Generated with Claude Code