v0.1.0 — Moon Base initial scaffold: auth, garden plant registry + log

This commit is contained in:
Bonna Moon
2026-06-15 16:14:48 -05:00
commit 99918fffbc
47 changed files with 2764 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
-- 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;