Skip to content

Waste importer upsert is SELECT-then-INSERT with no DB uniqueness and a non-atomic topic flow #61

Description

@tkowalczyk

Summary

The importer's documented idempotency key (household_id, type=waste_collection, config.address) exists only in app code — there is no DB unique index. Two concurrent runs (or a run racing the UI create) both see "no existing source" and both insert → duplicate sources, topics, notifications. The insert→createForumTopic→update(topicId) sequence is also not atomic: if updateSource fails after the topic is created, the next run creates a second topic.

Evidence

  • packages/data-ops/scripts/import-waste-schedule/db-deps.ts:26-48findExistingSource matches config->>'address' then inserts; .limit(1) with no ORDER BY.
  • …/importer.ts:61-110 — non-transactional multi-step.
  • packages/data-ops/src/drizzle/schema.ts:81-101 — no unique index on (household_id, type, (config->>'address')).

Proposed failing tests (TDD)

  • db-deps.db.test.ts (PGLite) — a partial unique index rejects a second waste_collection row with the same (household, address).
  • importer.test.ts — a store mutated between find and insert does not produce a duplicate (retries as update / surfaces conflict).

Fix direction

Add the partial unique index and use ON CONFLICT … DO UPDATE; wrap the topic flow so a failed update is retried/compensated.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    audit/2026-06Filed from June 2026 deep auditbugSomething isn't workingseverity/mediumMedium severity security or reliability risk

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions