mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-06-30 12:55:02 +00:00
Merge pull request #307 from Hestia-Homes/feature/recommendations-migrations
Some checks failed
Test Suite / unit-tests (push) Has been cancelled
Some checks failed
Test Suite / unit-tests (push) Has been cancelled
Recommendations migrations #1: add plan_id to recommendation table and backfill
This commit is contained in:
commit
899ac432ea
10 changed files with 43076 additions and 3 deletions
3
src/app/db/migrations/0222_nifty_hellcat.sql
Normal file
3
src/app/db/migrations/0222_nifty_hellcat.sql
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
ALTER TABLE "recommendation" ADD COLUMN "plan_id" bigint;--> statement-breakpoint
|
||||
ALTER TABLE "recommendation" ADD CONSTRAINT "recommendation_plan_id_plan_id_fk" FOREIGN KEY ("plan_id") REFERENCES "public"."plan"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "idx_recommendation_plan_id" ON "recommendation" USING btree ("plan_id");
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
-- Guard: fail if any recommendation is linked to more than one plan.
|
||||
-- The spec asserts each recommendation belongs to exactly one plan; if real
|
||||
-- data violates that the backfill cannot pick deterministically and must not
|
||||
-- proceed silently.
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM plan_recommendations
|
||||
GROUP BY recommendation_id
|
||||
HAVING count(*) > 1
|
||||
) THEN
|
||||
RAISE EXCEPTION
|
||||
'plan_id backfill aborted: one or more recommendations appear in multiple '
|
||||
'plan_recommendations rows. Resolve cardinality before re-running.';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
UPDATE recommendation r
|
||||
SET plan_id = pr.plan_id
|
||||
FROM plan_recommendations pr
|
||||
WHERE pr.recommendation_id = r.id
|
||||
AND r.plan_id IS NULL;
|
||||
6
src/app/db/migrations/0224_busy_nitro.sql
Normal file
6
src/app/db/migrations/0224_busy_nitro.sql
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
ALTER TABLE "recommendation" ADD COLUMN "material_id" bigint;--> statement-breakpoint
|
||||
ALTER TABLE "recommendation" ADD COLUMN "material_quantity" real;--> statement-breakpoint
|
||||
ALTER TABLE "recommendation" ADD COLUMN "material_quantity_unit" "unit_quantity";--> statement-breakpoint
|
||||
ALTER TABLE "recommendation" ADD COLUMN "material_depth" real;--> statement-breakpoint
|
||||
ALTER TABLE "recommendation" ADD CONSTRAINT "recommendation_material_id_material_id_fk" FOREIGN KEY ("material_id") REFERENCES "public"."material"("id") ON DELETE set null ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "idx_recommendation_material_id" ON "recommendation" USING btree ("material_id");
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
-- Guard: fail if any recommendation maps to more than one material row.
|
||||
-- The modelled fabric measures never produce this; if real data violates it
|
||||
-- the backfill cannot pick deterministically and must not proceed silently.
|
||||
DO $$
|
||||
BEGIN
|
||||
IF EXISTS (
|
||||
SELECT 1
|
||||
FROM recommendation_materials
|
||||
GROUP BY recommendation_id
|
||||
HAVING count(*) > 1
|
||||
) THEN
|
||||
RAISE EXCEPTION
|
||||
'recommendation_material_id backfill aborted: one or more recommendations '
|
||||
'have multiple recommendation_materials rows. Resolve cardinality before re-running.';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
-- Backfill all four columns in a single pass.
|
||||
UPDATE recommendation r
|
||||
SET material_id = rm.material_id,
|
||||
material_quantity = rm.quantity,
|
||||
material_quantity_unit = rm.quantity_unit,
|
||||
material_depth = rm.depth
|
||||
FROM recommendation_materials rm
|
||||
WHERE rm.recommendation_id = r.id
|
||||
AND r.material_id IS NULL;
|
||||
10717
src/app/db/migrations/meta/0222_snapshot.json
Normal file
10717
src/app/db/migrations/meta/0222_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
10717
src/app/db/migrations/meta/0223_snapshot.json
Normal file
10717
src/app/db/migrations/meta/0223_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
10770
src/app/db/migrations/meta/0224_snapshot.json
Normal file
10770
src/app/db/migrations/meta/0224_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
10770
src/app/db/migrations/meta/0225_snapshot.json
Normal file
10770
src/app/db/migrations/meta/0225_snapshot.json
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1548,6 +1548,34 @@
|
|||
"when": 1780566543108,
|
||||
"tag": "0221_nice_sumo",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 222,
|
||||
"version": "7",
|
||||
"when": 1780647165601,
|
||||
"tag": "0222_nifty_hellcat",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 223,
|
||||
"version": "7",
|
||||
"when": 1780647248894,
|
||||
"tag": "0223_recommendation_plan_id_backfill",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 224,
|
||||
"version": "7",
|
||||
"when": 1780653770494,
|
||||
"tag": "0224_busy_nitro",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 225,
|
||||
"version": "7",
|
||||
"when": 1780654800000,
|
||||
"tag": "0225_recommendation_material_id_backfill",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -60,6 +60,9 @@ export const measureTypeEnum = pgEnum("measure_type", [
|
|||
"sealing_open_fireplace",
|
||||
]);
|
||||
|
||||
export const unitQuantity: [string, ...string[]] = ["m2", "part", "kwp"];
|
||||
export const unitQuantityEnum = pgEnum("unit_quantity", unitQuantity);
|
||||
|
||||
export const recommendation = pgTable(
|
||||
"recommendation",
|
||||
{
|
||||
|
|
@ -67,6 +70,16 @@ export const recommendation = pgTable(
|
|||
propertyId: bigint("property_id", { mode: "bigint" })
|
||||
.notNull()
|
||||
.references(() => property.id),
|
||||
planId: bigint("plan_id", { mode: "bigint" }).references(() => plan.id, {
|
||||
onDelete: "cascade",
|
||||
}),
|
||||
materialId: bigint("material_id", { mode: "bigint" }).references(
|
||||
() => material.id,
|
||||
{ onDelete: "set null" }
|
||||
),
|
||||
materialQuantity: real("material_quantity"),
|
||||
materialQuantityUnit: unitQuantityEnum("material_quantity_unit"),
|
||||
materialDepth: real("material_depth"),
|
||||
createdAt: timestamp("created_at").notNull().defaultNow(),
|
||||
type: text("type").notNull(),
|
||||
measureType: text("measure_type"),
|
||||
|
|
@ -92,6 +105,7 @@ export const recommendation = pgTable(
|
|||
},
|
||||
(table) => [
|
||||
index("recommendation_property_id_idx").on(table.propertyId),
|
||||
index("idx_recommendation_plan_id").on(table.planId),
|
||||
index("idx_recommendation_active_defaults")
|
||||
.on(table.id)
|
||||
.where(
|
||||
|
|
@ -103,12 +117,11 @@ export const recommendation = pgTable(
|
|||
.where(
|
||||
sql`${table.default} = true AND ${table.alreadyInstalled} = false`,
|
||||
),
|
||||
|
||||
index("idx_recommendation_material_id").on(table.materialId),
|
||||
],
|
||||
);
|
||||
|
||||
export const unitQuantity: [string, ...string[]] = ["m2", "part", "kwp"];
|
||||
export const unitQuantityEnum = pgEnum("unit_quantity", unitQuantity);
|
||||
|
||||
export const recommendationMaterials = pgTable(
|
||||
"recommendation_materials",
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue