93 lines
3.5 KiB
SQL
93 lines
3.5 KiB
SQL
-- Moon Base v0.1 — initial schema
|
|
-- Creates auth, audit log, and the garden plant registry.
|
|
|
|
-- Enums
|
|
CREATE TYPE "UserRole" AS ENUM ('ADMIN', 'MEMBER');
|
|
CREATE TYPE "PlantCategory" AS ENUM (
|
|
'CANOPY_TREE', 'UNDERSTORY_TREE', 'LARGE_SHRUB', 'SHRUB',
|
|
'HERB', 'GROUNDCOVER', 'VINE', 'ANNUAL', 'PERENNIAL',
|
|
'BULB', 'MUSHROOM', 'OTHER'
|
|
);
|
|
CREATE TYPE "PlantLogType" AS ENUM (
|
|
'OBSERVATION', 'CARE', 'HARVEST', 'TREATMENT', 'TRANSPLANT', 'DIED'
|
|
);
|
|
|
|
-- User
|
|
CREATE TABLE "User" (
|
|
"id" TEXT NOT NULL,
|
|
"email" TEXT NOT NULL,
|
|
"username" TEXT,
|
|
"name" TEXT NOT NULL,
|
|
"passwordHash" TEXT NOT NULL,
|
|
"role" "UserRole" NOT NULL DEFAULT 'MEMBER',
|
|
"active" BOOLEAN NOT NULL DEFAULT true,
|
|
"mustChangePassword" BOOLEAN NOT NULL DEFAULT false,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
|
);
|
|
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
|
CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
|
|
|
|
-- AuditEvent
|
|
CREATE TABLE "AuditEvent" (
|
|
"id" TEXT NOT NULL,
|
|
"action" TEXT NOT NULL,
|
|
"entityId" TEXT,
|
|
"actorId" TEXT,
|
|
"payload" JSONB,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
CONSTRAINT "AuditEvent_pkey" PRIMARY KEY ("id")
|
|
);
|
|
CREATE INDEX "AuditEvent_entityId_idx" ON "AuditEvent"("entityId");
|
|
CREATE INDEX "AuditEvent_createdAt_idx" ON "AuditEvent"("createdAt");
|
|
|
|
-- Plant
|
|
CREATE TABLE "Plant" (
|
|
"id" TEXT NOT NULL,
|
|
"commonName" TEXT NOT NULL,
|
|
"species" TEXT,
|
|
"variety" TEXT,
|
|
"category" "PlantCategory" NOT NULL,
|
|
"zone" TEXT,
|
|
"plantedAt" TIMESTAMP(3),
|
|
"source" TEXT,
|
|
"notes" TEXT,
|
|
"active" BOOLEAN NOT NULL DEFAULT true,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
CONSTRAINT "Plant_pkey" PRIMARY KEY ("id")
|
|
);
|
|
CREATE INDEX "Plant_category_idx" ON "Plant"("category");
|
|
CREATE INDEX "Plant_zone_idx" ON "Plant"("zone");
|
|
CREATE INDEX "Plant_active_idx" ON "Plant"("active");
|
|
|
|
-- PlantLog
|
|
CREATE TABLE "PlantLog" (
|
|
"id" TEXT NOT NULL,
|
|
"plantId" TEXT NOT NULL,
|
|
"type" "PlantLogType" NOT NULL,
|
|
"date" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"notes" TEXT,
|
|
"quantity" TEXT,
|
|
"actorId" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
CONSTRAINT "PlantLog_pkey" PRIMARY KEY ("id"),
|
|
CONSTRAINT "PlantLog_plantId_fkey" FOREIGN KEY ("plantId") REFERENCES "Plant"("id") ON DELETE RESTRICT ON UPDATE CASCADE
|
|
);
|
|
CREATE INDEX "PlantLog_plantId_idx" ON "PlantLog"("plantId");
|
|
CREATE INDEX "PlantLog_date_idx" ON "PlantLog"("date");
|
|
|
|
-- Provision admin accounts (bonna + tony)
|
|
-- Passwords are bcrypt hashes of temporary values — change on first login.
|
|
-- bonna: moonbase! | tony: moonbase!
|
|
INSERT INTO "User" ("id", "email", "username", "name", "passwordHash", "role", "active", "mustChangePassword", "createdAt", "updatedAt")
|
|
VALUES
|
|
('cluser0000000bonna', 'bonna@moonbase.local', 'bonna', 'Bonna Moon',
|
|
'$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'ADMIN', true, true,
|
|
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
|
|
('cluser0000000tony0', 'tony@moonbase.local', 'tony', 'Tony Moon',
|
|
'$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', 'ADMIN', true, true,
|
|
CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
|
ON CONFLICT ("username") DO UPDATE SET "updatedAt" = CURRENT_TIMESTAMP;
|