fix(db): add migration 0020 for UNIQUE(name) + align admin seed ON CONFLICT

Problem:
- Schema change in eacf8ab added .unique() to services.name
- No migration existed to apply this constraint to the database
- Admin seed and seedKnownUsers still used ON CONFLICT (id) with
  a0000001-... IDs, inconsistent with main seed's b0000001-... IDs
  and ON CONFLICT (name)

Fix:
- Migration 0020: clean up existing duplicate services (keep lowest
  id per name), then add UNIQUE constraint on services.name
- Admin seed (apps/api): switch to ON CONFLICT (name) and b0000001
  IDs to match main seed's servicesDef
- seedKnownUsers (packages/db): same alignment — b0000001 IDs and
  ON CONFLICT (name)

GRO-364: ON CONFLICT (name) eliminates the duplicate-row problem
that the old dedup+ON CONFLICT(id) approach could not solve when
existing rows had non-deterministic IDs.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
groombook-engineer[bot]
2026-04-01 13:41:18 +00:00
parent eacf8abc3b
commit 84c8236227
5 changed files with 2091 additions and 15 deletions
@@ -0,0 +1,7 @@
-- Clean up existing duplicate services before adding unique constraint.
-- Keep the row with the lowest id per name; delete all others.
DELETE FROM services WHERE id NOT IN (
SELECT (MIN(id::text))::uuid FROM services GROUP BY name
);
ALTER TABLE "services" ADD CONSTRAINT "services_name_unique" UNIQUE("name");