-- Migration autosuffisante : les extensions requises sont créées si absentes -- (la CI et tout environnement neuf n’ont pas notre init.sql). CREATE EXTENSION IF NOT EXISTS postgis; -- CreateEnum CREATE TYPE "CategoryKind" AS ENUM ('EQUIPMENT', 'COMPONENT_TYPE'); -- CreateEnum CREATE TYPE "AssetStatus" AS ENUM ('IN_SERVICE', 'OUT_OF_SERVICE', 'UNDER_MAINTENANCE'); -- AlterTable ALTER TABLE "User" ADD COLUMN "activationExpiresAt" TIMESTAMP(3), ADD COLUMN "activationToken" TEXT, ADD COLUMN "phone" TEXT; -- CreateTable CREATE TABLE "Category" ( "id" UUID NOT NULL, "kind" "CategoryKind" NOT NULL, "name" TEXT NOT NULL, "isActive" BOOLEAN NOT NULL DEFAULT true, CONSTRAINT "Category_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "Location" ( "id" UUID NOT NULL, "name" TEXT NOT NULL, "parentId" UUID, "address" TEXT, "city" TEXT, "guardianName" TEXT, "guardianPhone" TEXT, "latitude" DOUBLE PRECISION, "longitude" DOUBLE PRECISION, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "Location_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "Asset" ( "id" UUID NOT NULL, "reference" TEXT NOT NULL, "brand" TEXT NOT NULL, "model" TEXT, "serialNumber" TEXT, "commissionedAt" TIMESTAMP(3), "loadKg" INTEGER, "floors" INTEGER, "status" "AssetStatus" NOT NULL DEFAULT 'IN_SERVICE', "categoryId" UUID NOT NULL, "locationId" UUID NOT NULL, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP(3) NOT NULL, CONSTRAINT "Asset_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "AssetComponent" ( "id" UUID NOT NULL, "assetId" UUID NOT NULL, "typeId" UUID NOT NULL, "designation" TEXT, CONSTRAINT "AssetComponent_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "Team" ( "id" UUID NOT NULL, "name" TEXT NOT NULL, "description" TEXT, CONSTRAINT "Team_pkey" PRIMARY KEY ("id") ); -- CreateTable CREATE TABLE "_TeamToUser" ( "A" UUID NOT NULL, "B" UUID NOT NULL, CONSTRAINT "_TeamToUser_AB_pkey" PRIMARY KEY ("A","B") ); -- CreateIndex CREATE UNIQUE INDEX "Category_kind_name_key" ON "Category"("kind", "name"); -- CreateIndex CREATE INDEX "Location_parentId_idx" ON "Location"("parentId"); -- CreateIndex CREATE UNIQUE INDEX "Asset_reference_key" ON "Asset"("reference"); -- CreateIndex CREATE INDEX "Asset_locationId_idx" ON "Asset"("locationId"); -- CreateIndex CREATE INDEX "Asset_categoryId_idx" ON "Asset"("categoryId"); -- CreateIndex CREATE INDEX "AssetComponent_assetId_idx" ON "AssetComponent"("assetId"); -- CreateIndex CREATE UNIQUE INDEX "Team_name_key" ON "Team"("name"); -- CreateIndex CREATE INDEX "_TeamToUser_B_index" ON "_TeamToUser"("B"); -- CreateIndex CREATE UNIQUE INDEX "User_activationToken_key" ON "User"("activationToken"); -- AddForeignKey ALTER TABLE "Location" ADD CONSTRAINT "Location_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Location"("id") ON DELETE SET NULL ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "Asset" ADD CONSTRAINT "Asset_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "Category"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "Asset" ADD CONSTRAINT "Asset_locationId_fkey" FOREIGN KEY ("locationId") REFERENCES "Location"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "AssetComponent" ADD CONSTRAINT "AssetComponent_assetId_fkey" FOREIGN KEY ("assetId") REFERENCES "Asset"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "AssetComponent" ADD CONSTRAINT "AssetComponent_typeId_fkey" FOREIGN KEY ("typeId") REFERENCES "Category"("id") ON DELETE RESTRICT ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "_TeamToUser" ADD CONSTRAINT "_TeamToUser_A_fkey" FOREIGN KEY ("A") REFERENCES "Team"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- AddForeignKey ALTER TABLE "_TeamToUser" ADD CONSTRAINT "_TeamToUser_B_fkey" FOREIGN KEY ("B") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE; -- ————— PostGIS (hors périmètre Prisma, décision modèle R1) ————— -- Position générée depuis latitude/longitude : rien à synchroniser côté app, -- la colonne est prête pour les requêtes spatiales (affectation auto, backlog). ALTER TABLE "Location" ADD COLUMN "position" geography(Point, 4326) GENERATED ALWAYS AS (ST_SetSRID(ST_MakePoint("longitude", "latitude"), 4326)::geography) STORED; CREATE INDEX "Location_position_gix" ON "Location" USING GIST ("position");