-- #303: operator-uploaded font families (ADR 0016 ยง#303). -- The bytes live on disk under CUSTOM_FONTS_DIR; these rows record only what -- the upload form stated, because the api never parses the font file. CREATE TABLE "custom_fonts" ( "id" TEXT NOT NULL, "family" TEXT NOT NULL, "slug" TEXT NOT NULL, "category" TEXT NOT NULL, "licence" TEXT NOT NULL, "licence_url" TEXT, "uploaded_by" TEXT NOT NULL, "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP(3) NOT NULL, CONSTRAINT "custom_fonts_pkey" PRIMARY KEY ("id") ); -- Both unique: `family` keeps `fonts..family` in pond settings -- unambiguous, `slug` owns a directory under CUSTOM_FONTS_DIR. CREATE UNIQUE INDEX "custom_fonts_family_key" ON "custom_fonts"("family"); CREATE UNIQUE INDEX "custom_fonts_slug_key" ON "custom_fonts"("slug"); ALTER TABLE "custom_fonts" ADD CONSTRAINT "custom_fonts_uploaded_by_fkey" FOREIGN KEY ("uploaded_by") REFERENCES "users"("id") ON DELETE RESTRICT ON UPDATE CASCADE; CREATE TABLE "custom_font_weights" ( "id" TEXT NOT NULL, "font_id" TEXT NOT NULL, "weight" INTEGER NOT NULL, "has_woff" BOOLEAN NOT NULL DEFAULT false, "byte_size" INTEGER NOT NULL, CONSTRAINT "custom_font_weights_pkey" PRIMARY KEY ("id") ); CREATE UNIQUE INDEX "custom_font_weights_font_id_weight_key" ON "custom_font_weights"("font_id", "weight"); -- Deleting a family takes its weights with it; the files on disk are removed -- by the service in the same operation. ALTER TABLE "custom_font_weights" ADD CONSTRAINT "custom_font_weights_font_id_fkey" FOREIGN KEY ("font_id") REFERENCES "custom_fonts"("id") ON DELETE CASCADE ON UPDATE CASCADE;