db: Foreign Keys für blocker- und Tageseintrag-Verweise (Migration 0017)
Bisher reine uuid-Spalten ohne referenzielle Integritaet -> Orphan-Risiko, wenn das Ziel geloescht wird. Jetzt echte FKs mit ON DELETE SET NULL: - day_entry.blocker_id -> blocker - blocker.area_id -> area - blocker.project_id -> project Migration bereinigt vorab verwaiste IDs (UPDATE ... SET NULL), damit ADD CONSTRAINT auf Altdaten nicht bricht. Verifiziert: alle 18 Migrationen laufen gegen frische Postgres 16 durch, FKs angelegt. (todo.bezug_id / time_entry.bezug_id bleiben FK-frei: echt polymorph ueber bezug_kind project/deal/campaign — kein einzelner FK moeglich.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
ff0a15b94e
commit
9bae1702aa
4 files changed
+3362
-3
No files matched your search
@@ -0,0 +1,8 @@
|
||||
-- Verwaiste Verweise vor dem Setzen der Foreign Keys auf NULL bereinigen — sonst
|
||||
-- schlaegt ADD CONSTRAINT fehl, falls Altdaten auf geloeschte Zeilen zeigen.
|
||||
UPDATE "blocker" SET "area_id" = NULL WHERE "area_id" IS NOT NULL AND "area_id" NOT IN (SELECT "id" FROM "area");--> statement-breakpoint
|
||||
UPDATE "blocker" SET "project_id" = NULL WHERE "project_id" IS NOT NULL AND "project_id" NOT IN (SELECT "id" FROM "project");--> statement-breakpoint
|
||||
UPDATE "day_entry" SET "blocker_id" = NULL WHERE "blocker_id" IS NOT NULL AND "blocker_id" NOT IN (SELECT "id" FROM "blocker");--> statement-breakpoint
|
||||
ALTER TABLE "blocker" ADD CONSTRAINT "blocker_area_id_area_id_fk" FOREIGN KEY ("area_id") REFERENCES "public"."area"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "blocker" ADD CONSTRAINT "blocker_project_id_project_id_fk" FOREIGN KEY ("project_id") REFERENCES "public"."project"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
ALTER TABLE "day_entry" ADD CONSTRAINT "day_entry_blocker_id_blocker_id_fk" FOREIGN KEY ("blocker_id") REFERENCES "public"."blocker"("id") ON DELETE set null ON UPDATE no action;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -120,6 +120,13 @@
|
||||
"when": 1780771242601,
|
||||
"tag": "0016_project_logo_url",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 17,
|
||||
"version": "7",
|
||||
"when": 1780826387755,
|
||||
"tag": "0017_rare_oracle",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -231,7 +231,7 @@ export const dayEntry = pgTable(
|
||||
ampel: text('ampel', { enum: ['green', 'amber', 'red'] }),
|
||||
trend: text('trend', { enum: ['besser', 'gleich', 'schlechter'] }),
|
||||
url: text('url'),
|
||||
blockerId: uuid('blocker_id'),
|
||||
blockerId: uuid('blocker_id').references(() => blocker.id, { onDelete: 'set null' }),
|
||||
editLockedAt: timestamp('edit_locked_at', { withTimezone: true }),
|
||||
publishedAt: timestamp('published_at', { withTimezone: true }),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
|
||||
@@ -442,8 +442,8 @@ export const blocker = pgTable(
|
||||
.primaryKey(),
|
||||
title: text('title').notNull(),
|
||||
description: text('description'),
|
||||
areaId: uuid('area_id'),
|
||||
projectId: uuid('project_id'),
|
||||
areaId: uuid('area_id').references(() => area.id, { onDelete: 'set null' }),
|
||||
projectId: uuid('project_id').references(() => project.id, { onDelete: 'set null' }),
|
||||
ownerUserId: uuid('owner_user_id').references(() => user.id, { onDelete: 'set null' }),
|
||||
openedBy: uuid('opened_by')
|
||||
.notNull()
|
||||
|
||||
Reference in new issue
Block a user