Files
website/drizzle/20261025190955_groceries_taxonomy_manual/migration.sql

60 lines
3.8 KiB
SQL

CREATE TABLE "groceries"."categories" (
"id" serial PRIMARY KEY,
"slug" text NOT NULL,
"name" text NOT NULL,
"parent_id" integer,
"icon" text,
"color" text,
"sort_order" integer DEFAULT 0 NOT NULL,
"is_food" boolean DEFAULT true NOT NULL,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "categories_slug_check" CHECK ("slug" ~ '^[a-z0-9][a-z0-9-]{0,62}$'),
CONSTRAINT "categories_name_check" CHECK (length(btrim("name")) > 0)
);
--> statement-breakpoint
CREATE TABLE "groceries"."manual_prices" (
"id" serial PRIMARY KEY,
"store_id" integer NOT NULL,
"group_id" integer,
"item_id" integer,
"price_cents" integer NOT NULL,
"promo" boolean DEFAULT false NOT NULL,
"size_text" text,
"unit" text,
"unit_amount" numeric(12,4),
"unit_price_cents" integer,
"observed_on" date DEFAULT now() NOT NULL,
"photo_url" text,
"note" text,
"created_at" timestamp with time zone DEFAULT now() NOT NULL,
"updated_at" timestamp with time zone DEFAULT now() NOT NULL,
CONSTRAINT "manual_prices_price_check" CHECK ("price_cents" > 0 AND "price_cents" < 1000000),
CONSTRAINT "manual_prices_target_check" CHECK ("group_id" IS NOT NULL OR "item_id" IS NOT NULL),
CONSTRAINT "manual_prices_unit_check" CHECK ("unit" IS NULL OR "unit" IN ('piece','kg','l'))
);
--> statement-breakpoint
ALTER TABLE "groceries"."groups" ADD COLUMN "category_id" integer;--> statement-breakpoint
ALTER TABLE "groceries"."items" ADD COLUMN "category_id" integer;--> statement-breakpoint
CREATE UNIQUE INDEX "categories_slug_key" ON "groceries"."categories" ("slug");--> statement-breakpoint
CREATE INDEX "categories_parent_idx" ON "groceries"."categories" ("parent_id");--> statement-breakpoint
CREATE INDEX "groups_category_id_idx" ON "groceries"."groups" ("category_id");--> statement-breakpoint
CREATE INDEX "items_category_id_idx" ON "groceries"."items" ("category_id");--> statement-breakpoint
CREATE INDEX "manual_prices_group_idx" ON "groceries"."manual_prices" ("group_id","observed_on");--> statement-breakpoint
CREATE INDEX "manual_prices_item_idx" ON "groceries"."manual_prices" ("item_id");--> statement-breakpoint
ALTER TABLE "groceries"."categories" ADD CONSTRAINT "categories_parent_id_categories_id_fkey" FOREIGN KEY ("parent_id") REFERENCES "groceries"."categories"("id") ON DELETE CASCADE;--> statement-breakpoint
ALTER TABLE "groceries"."groups" ADD CONSTRAINT "groups_category_id_categories_id_fkey" FOREIGN KEY ("category_id") REFERENCES "groceries"."categories"("id") ON DELETE SET NULL;--> statement-breakpoint
ALTER TABLE "groceries"."items" ADD CONSTRAINT "items_category_id_categories_id_fkey" FOREIGN KEY ("category_id") REFERENCES "groceries"."categories"("id") ON DELETE SET NULL;--> statement-breakpoint
ALTER TABLE "groceries"."manual_prices" ADD CONSTRAINT "manual_prices_store_id_stores_id_fkey" FOREIGN KEY ("store_id") REFERENCES "groceries"."stores"("id") ON DELETE CASCADE;--> statement-breakpoint
ALTER TABLE "groceries"."manual_prices" ADD CONSTRAINT "manual_prices_group_id_groups_id_fkey" FOREIGN KEY ("group_id") REFERENCES "groceries"."groups"("id") ON DELETE CASCADE;--> statement-breakpoint
ALTER TABLE "groceries"."manual_prices" ADD CONSTRAINT "manual_prices_item_id_items_id_fkey" FOREIGN KEY ("item_id") REFERENCES "groceries"."items"("id") ON DELETE SET NULL;--> statement-breakpoint
-- The category tree itself is synced from src/lib/server/groceries/taxonomy.ts by
-- applyTaxonomy() (nightly import, or `bun scripts/groceries-taxonomy.ts`).
DO $$
BEGIN
IF current_user = 'personal' AND EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'personal_app') THEN
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA groceries TO personal_app;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA groceries TO personal_app;
END IF;
END $$;