Files
LabWise/server/src/db/schema.sql
pulipakaa24 c124e20ccc
All checks were successful
Deploy to Server / deploy (push) Successful in 32s
nullable name fix
2026-04-10 21:50:54 -05:00

131 lines
3.6 KiB
SQL

-- Better Auth tables
CREATE TABLE IF NOT EXISTS "user" (
"id" TEXT NOT NULL PRIMARY KEY,
"name" TEXT NOT NULL,
"email" TEXT NOT NULL UNIQUE,
"emailVerified" BOOLEAN NOT NULL,
"image" TEXT,
"createdAt" TIMESTAMP NOT NULL,
"updatedAt" TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS "session" (
"id" TEXT NOT NULL PRIMARY KEY,
"expiresAt" TIMESTAMP NOT NULL,
"token" TEXT NOT NULL UNIQUE,
"createdAt" TIMESTAMP NOT NULL,
"updatedAt" TIMESTAMP NOT NULL,
"ipAddress" TEXT,
"userAgent" TEXT,
"userId" TEXT NOT NULL REFERENCES "user"("id") ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS "account" (
"id" TEXT NOT NULL PRIMARY KEY,
"accountId" TEXT NOT NULL,
"providerId" TEXT NOT NULL,
"userId" TEXT NOT NULL REFERENCES "user"("id") ON DELETE CASCADE,
"accessToken" TEXT,
"refreshToken" TEXT,
"idToken" TEXT,
"accessTokenExpiresAt" TIMESTAMP,
"refreshTokenExpiresAt" TIMESTAMP,
"scope" TEXT,
"password" TEXT,
"createdAt" TIMESTAMP NOT NULL,
"updatedAt" TIMESTAMP NOT NULL
);
CREATE TABLE IF NOT EXISTS "verification" (
"id" TEXT NOT NULL PRIMARY KEY,
"identifier" TEXT NOT NULL,
"value" TEXT NOT NULL,
"expiresAt" TIMESTAMP NOT NULL,
"createdAt" TIMESTAMP,
"updatedAt" TIMESTAMP
);
-- Chemical inventory, scoped per user
CREATE TABLE IF NOT EXISTS chemicals (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT NOT NULL,
-- Required fields
pi_first_name TEXT NOT NULL,
physical_state TEXT NOT NULL,
chemical_name TEXT NOT NULL,
bldg_code TEXT NOT NULL,
lab TEXT NOT NULL,
storage_location TEXT NOT NULL,
storage_device TEXT NOT NULL,
number_of_containers TEXT NOT NULL,
amount_per_container TEXT NOT NULL,
unit_of_measure TEXT NOT NULL,
cas_number TEXT NOT NULL,
-- Optional fields
chemical_formula TEXT,
molecular_weight TEXT,
vendor TEXT,
catalog_number TEXT,
found_in_catalog TEXT,
po_number TEXT,
receipt_date TEXT,
open_date TEXT,
max_on_hand TEXT,
expiration_date DATE,
contact TEXT,
comments TEXT,
permit_number TEXT,
barcode TEXT,
concentration TEXT,
chemical_number TEXT,
lot_number TEXT,
multiple_cas TEXT,
msds TEXT,
percentage_full NUMERIC(5,2),
needs_manual_entry TEXT[],
scanned_image TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS chemicals_user_id_idx ON chemicals(user_id);
CREATE INDEX IF NOT EXISTS chemicals_cas_number_idx ON chemicals(cas_number);
-- Protocols with JSONB analysis results
CREATE TABLE IF NOT EXISTS protocols (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT NOT NULL,
title TEXT NOT NULL,
content TEXT NOT NULL DEFAULT '',
file_url TEXT,
analysis_results JSONB,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS protocols_user_id_idx ON protocols(user_id);
-- User profile — lab defaults pre-filled on chemical entries
CREATE TABLE IF NOT EXISTS user_profile (
user_id TEXT NOT NULL PRIMARY KEY REFERENCES "user"("id") ON DELETE CASCADE,
pi_first_name TEXT,
bldg_code TEXT,
lab TEXT,
contact TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Allow existing deployments to have nullable profile fields.
-- DROP NOT NULL on an already-nullable column is a no-op in Postgres.
ALTER TABLE user_profile ALTER COLUMN pi_first_name DROP NOT NULL;
ALTER TABLE user_profile ALTER COLUMN bldg_code DROP NOT NULL;
ALTER TABLE user_profile ALTER COLUMN lab DROP NOT NULL;
-- Allow name to be cleared (set to null).
ALTER TABLE "user" ALTER COLUMN "name" DROP NOT NULL;