From 062bdbd16e8b8d2c129f95249d6c9e1c386e807b Mon Sep 17 00:00:00 2001 From: kennyboy55 Date: Fri, 7 Aug 2026 11:01:27 +0200 Subject: [PATCH] Add support for Brands: introduce prisma migrate --- .gitea/workflows/test-build.yaml | 1 + Dockerfile | 3 +- migrate.sh | 3 + prisma/migrations/0_init/migration.sql | 245 ++++++++++++++++++ .../20260804164733_add_brand/migration.sql | 28 ++ prisma/migrations/migration_lock.toml | 3 + prisma/schema.prisma | 9 + schema.zmodel | 15 ++ 8 files changed, 306 insertions(+), 1 deletion(-) create mode 100644 migrate.sh create mode 100644 prisma/migrations/0_init/migration.sql create mode 100644 prisma/migrations/20260804164733_add_brand/migration.sql create mode 100644 prisma/migrations/migration_lock.toml diff --git a/.gitea/workflows/test-build.yaml b/.gitea/workflows/test-build.yaml index c66791b..5ee2881 100644 --- a/.gitea/workflows/test-build.yaml +++ b/.gitea/workflows/test-build.yaml @@ -4,6 +4,7 @@ on: push: branches: - main + - feature/* workflow_dispatch: jobs: diff --git a/Dockerfile b/Dockerfile index 677ff92..1b0e86a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,9 +13,10 @@ COPY . . ENV NODE_ENV=production ENV DATABASE_URL="REQUIRED" +RUN chmod +x ./migrate.sh RUN npx zenstack generate EXPOSE 3000 VOLUME /usr/src/app/public -CMD ["/bin/sh", "-c", "npx prisma db push && npm start"] \ No newline at end of file +CMD ["/bin/sh", "-c", "./migrate.sh && npm start"] \ No newline at end of file diff --git a/migrate.sh b/migrate.sh new file mode 100644 index 0000000..e5b5931 --- /dev/null +++ b/migrate.sh @@ -0,0 +1,3 @@ +#!/bin/sh +npx prisma migrate resolve --applied 0_init +npx prisma migrate deploy \ No newline at end of file diff --git a/prisma/migrations/0_init/migration.sql b/prisma/migrations/0_init/migration.sql new file mode 100644 index 0000000..dc72d92 --- /dev/null +++ b/prisma/migrations/0_init/migration.sql @@ -0,0 +1,245 @@ +-- CreateEnum +CREATE TYPE "ContainerType" AS ENUM ('BeerBottle', 'WineBottle', 'PlasticBottle', 'Can', 'Carton', 'Keg'); + +-- CreateEnum +CREATE TYPE "DrinkType" AS ENUM ('Drink', 'Beer', 'Wine', 'Soda', 'Cocktail'); + +-- CreateEnum +CREATE TYPE "UserType" AS ENUM ('User', 'Scanner', 'Admin'); + +-- CreateTable +CREATE TABLE "Beer" ( + "id" INTEGER NOT NULL, + "style_id" INTEGER NOT NULL, + "ibu" DOUBLE PRECISION, + "glass" BOOLEAN NOT NULL DEFAULT false, + + CONSTRAINT "Beer_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "BeerStyle" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + "color" TEXT NOT NULL, + + CONSTRAINT "BeerStyle_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Cocktail" ( + "id" INTEGER NOT NULL, + "mix" BOOLEAN NOT NULL, + + CONSTRAINT "Cocktail_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Container" ( + "id" SERIAL NOT NULL, + "barcode" TEXT, + "drink_id" INTEGER NOT NULL, + "section_id" INTEGER NOT NULL, + "type" "ContainerType" NOT NULL, + "volume" INTEGER NOT NULL, + "portions" INTEGER, + "price" DOUBLE PRECISION NOT NULL DEFAULT 0.0, + "inventory" INTEGER NOT NULL DEFAULT 0, + "lastAdded" TIMESTAMP(3), + + CONSTRAINT "Container_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Country" ( + "code" TEXT NOT NULL, + "name" TEXT NOT NULL, + + CONSTRAINT "Country_pkey" PRIMARY KEY ("code") +); + +-- CreateTable +CREATE TABLE "Drink" ( + "id" SERIAL NOT NULL, + "slug" TEXT NOT NULL, + "manufacturer_id" INTEGER NOT NULL, + "type" "DrinkType" NOT NULL, + "name" TEXT NOT NULL, + "description" TEXT NOT NULL, + "abv" DOUBLE PRECISION NOT NULL, + "image" TEXT, + "link" TEXT, + "gluten" BOOLEAN NOT NULL, + "lactose" BOOLEAN NOT NULL, + "organic" BOOLEAN NOT NULL, + "sugar" BOOLEAN NOT NULL DEFAULT true, + "addedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "Drink_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "History" ( + "id" SERIAL NOT NULL, + "container_id" INTEGER NOT NULL, + "checkoutAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "inventoryAfter" INTEGER NOT NULL, + + CONSTRAINT "History_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Manufacturer" ( + "id" SERIAL NOT NULL, + "country_id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "description" TEXT, + "image" TEXT, + + CONSTRAINT "Manufacturer_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Report" ( + "id" SERIAL NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "dateStart" TIMESTAMP(3) NOT NULL, + "dateEnd" TIMESTAMP(3) NOT NULL, + "file" TEXT, + "name" TEXT NOT NULL, + + CONSTRAINT "Report_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Section" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + + CONSTRAINT "Section_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Session" ( + "id" TEXT NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "user_id" INTEGER, + "data" TEXT NOT NULL, + + CONSTRAINT "Session_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Soda" ( + "id" INTEGER NOT NULL, + "carbonated" BOOLEAN NOT NULL, + + CONSTRAINT "Soda_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Suggestion" ( + "id" SERIAL NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "name" TEXT, + "content" TEXT NOT NULL, + "resolved" BOOLEAN NOT NULL DEFAULT false, + + CONSTRAINT "Suggestion_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "User" ( + "id" SERIAL NOT NULL, + "username" TEXT NOT NULL, + "password" TEXT NOT NULL, + "type" "UserType" NOT NULL, + + CONSTRAINT "User_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "Wine" ( + "id" INTEGER NOT NULL, + "style_id" INTEGER NOT NULL, + "heavy_score" INTEGER, + "tannine_score" INTEGER, + "dry_score" INTEGER, + "fresh_score" INTEGER, + "notes" TEXT, + + CONSTRAINT "Wine_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "WineStyle" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + "color" TEXT NOT NULL, + + CONSTRAINT "WineStyle_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "BeerStyle_name_key" ON "BeerStyle"("name" ASC); + +-- CreateIndex +CREATE UNIQUE INDEX "Container_barcode_key" ON "Container"("barcode" ASC); + +-- CreateIndex +CREATE UNIQUE INDEX "Drink_name_key" ON "Drink"("name" ASC); + +-- CreateIndex +CREATE UNIQUE INDEX "Drink_slug_key" ON "Drink"("slug" ASC); + +-- CreateIndex +CREATE UNIQUE INDEX "Manufacturer_name_key" ON "Manufacturer"("name" ASC); + +-- CreateIndex +CREATE UNIQUE INDEX "Report_name_key" ON "Report"("name" ASC); + +-- CreateIndex +CREATE UNIQUE INDEX "Section_name_key" ON "Section"("name" ASC); + +-- CreateIndex +CREATE UNIQUE INDEX "User_username_key" ON "User"("username" ASC); + +-- CreateIndex +CREATE UNIQUE INDEX "WineStyle_name_key" ON "WineStyle"("name" ASC); + +-- AddForeignKey +ALTER TABLE "Beer" ADD CONSTRAINT "Beer_id_fkey" FOREIGN KEY ("id") REFERENCES "Drink"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Beer" ADD CONSTRAINT "Beer_style_id_fkey" FOREIGN KEY ("style_id") REFERENCES "BeerStyle"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Cocktail" ADD CONSTRAINT "Cocktail_id_fkey" FOREIGN KEY ("id") REFERENCES "Drink"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Container" ADD CONSTRAINT "Container_drink_id_fkey" FOREIGN KEY ("drink_id") REFERENCES "Drink"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Container" ADD CONSTRAINT "Container_section_id_fkey" FOREIGN KEY ("section_id") REFERENCES "Section"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Drink" ADD CONSTRAINT "Drink_manufacturer_id_fkey" FOREIGN KEY ("manufacturer_id") REFERENCES "Manufacturer"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "History" ADD CONSTRAINT "History_container_id_fkey" FOREIGN KEY ("container_id") REFERENCES "Container"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Manufacturer" ADD CONSTRAINT "Manufacturer_country_id_fkey" FOREIGN KEY ("country_id") REFERENCES "Country"("code") ON DELETE RESTRICT ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Session" ADD CONSTRAINT "Session_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Soda" ADD CONSTRAINT "Soda_id_fkey" FOREIGN KEY ("id") REFERENCES "Drink"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Wine" ADD CONSTRAINT "Wine_id_fkey" FOREIGN KEY ("id") REFERENCES "Drink"("id") ON DELETE CASCADE ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Wine" ADD CONSTRAINT "Wine_style_id_fkey" FOREIGN KEY ("style_id") REFERENCES "WineStyle"("id") ON DELETE RESTRICT ON UPDATE CASCADE; + diff --git a/prisma/migrations/20260804164733_add_brand/migration.sql b/prisma/migrations/20260804164733_add_brand/migration.sql new file mode 100644 index 0000000..681b534 --- /dev/null +++ b/prisma/migrations/20260804164733_add_brand/migration.sql @@ -0,0 +1,28 @@ +/* + Warnings: + + - Added the required column `brand_id` to the `Drink` table without a default value. This is not possible if the table is not empty. + +*/ +-- CreateTable +CREATE TABLE "Brand" ( + "id" SERIAL NOT NULL, + "name" TEXT NOT NULL, + "image" TEXT, + + CONSTRAINT "Brand_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Brand_name_key" ON "Brand"("name"); + +-- Add default brand +INSERT INTO "Brand" ("name") VALUES ('Default'); + +-- AlterTable +ALTER TABLE "Drink" ADD COLUMN "brand_id" INTEGER; +UPDATE "Drink" SET "brand_id" = (SELECT "id" FROM "Brand" WHERE "name" = 'Default'); +ALTER TABLE "Drink" ALTER COLUMN "brand_id" SET NOT NULL; + +-- AddForeignKey +ALTER TABLE "Drink" ADD CONSTRAINT "Drink_brand_id_fkey" FOREIGN KEY ("brand_id") REFERENCES "Brand"("id") ON DELETE RESTRICT ON UPDATE CASCADE; diff --git a/prisma/migrations/migration_lock.toml b/prisma/migrations/migration_lock.toml new file mode 100644 index 0000000..044d57c --- /dev/null +++ b/prisma/migrations/migration_lock.toml @@ -0,0 +1,3 @@ +# Please do not edit this file manually +# It should be added in your version-control system (e.g., Git) +provider = "postgresql" diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 5f2b3a2..689855e 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -40,6 +40,8 @@ model Drink { slug String @unique() manufacturer_id Int manufacturer Manufacturer @relation(fields: [manufacturer_id], references: [id]) + brand_id Int + brand Brand @relation(fields: [brand_id], references: [id]) type DrinkType name String @unique() description String @@ -137,6 +139,13 @@ model Manufacturer { drinks Drink[] } +model Brand { + id Int @id() @default(autoincrement()) + name String @unique() + image String? + drinks Drink[] +} + model Country { code String @id() name String diff --git a/schema.zmodel b/schema.zmodel index 5dff8a2..dc808b1 100644 --- a/schema.zmodel +++ b/schema.zmodel @@ -40,6 +40,9 @@ model Drink { manufacturer_id Int manufacturer Manufacturer @relation(fields: [manufacturer_id], references: [id]) + brand_id Int + brand Brand @relation(fields: [brand_id], references: [id]) + type DrinkType name String @unique @@ -177,6 +180,18 @@ model Manufacturer { @@allow('all', auth().type == Admin) } +model Brand { + id Int @id @default(autoincrement()) + + name String @unique + image String? + + drinks Drink[] + + @@allow('read', true) + @@allow('all', auth().type == Admin) +} + model Country { code String @id name String