feat(properties): add parent_id for sub-property hierarchy
Phase 1 of the parent/child rollup feature. Self-FK on properties with ON DELETE RESTRICT, plus a CHECK that blocks self-reference at the DB level. Service-layer helpers (getDescendantIds, getAncestorIds, assertNoCycle) walk the tree via recursive CTEs and guard against cycles and cross-company parents. softDeleteProperty now refuses to delete a property with live children. No UI yet — readers and roll-up routes land in Phase 2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE "properties" ADD COLUMN "parent_id" uuid;--> statement-breakpoint
|
||||
ALTER TABLE "properties" ADD CONSTRAINT "properties_parent_id_properties_id_fk" FOREIGN KEY ("parent_id") REFERENCES "public"."properties"("id") ON DELETE restrict ON UPDATE no action;--> statement-breakpoint
|
||||
CREATE INDEX "properties_by_parent" ON "properties" USING btree ("company_id","parent_id");
|
||||
@@ -0,0 +1,7 @@
|
||||
-- A property cannot be its own parent. Deeper cycle prevention (e.g.
|
||||
-- A→B→A) is enforced in the service layer because Postgres can't express
|
||||
-- recursive CHECK constraints; the assertNoCycle helper in
|
||||
-- src/lib/server/services/properties.ts walks ancestors before save.
|
||||
ALTER TABLE "properties"
|
||||
ADD CONSTRAINT "properties_parent_not_self"
|
||||
CHECK (parent_id IS NULL OR parent_id <> id);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -113,6 +113,20 @@
|
||||
"when": 1776932900000,
|
||||
"tag": "0015_expenses_updated_at_trigger",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 16,
|
||||
"version": "7",
|
||||
"when": 1777268853483,
|
||||
"tag": "0016_property_parent_id",
|
||||
"breakpoints": true
|
||||
},
|
||||
{
|
||||
"idx": 17,
|
||||
"version": "7",
|
||||
"when": 1777268853484,
|
||||
"tag": "0017_property_parent_check",
|
||||
"breakpoints": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user