2026-03-19 13:48:19 -05:00
|
|
|
-- 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
|
|
|
|
|
);
|
|
|
|
|
|
2026-03-19 05:42:11 +00:00
|
|
|
-- 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);
|