Cripple-Lee's picture
Sync from GitHub via hub-sync
5d5a5b6 verified
Raw History Blame Contribute Delete
3.64 kB
-- ============================================================================
-- Personal Assistant — authentication schema
-- ============================================================================
-- Run against your Postgres database, e.g.:
-- psql "$DATABASE_URL" -f db/schema.sql
--
-- The matching server code lives in:
-- src/web/auth.py (langgraph_sdk.Auth JWT verification)
-- src/web/login.py (/auth/signup, /auth/login custom routes)
-- ============================================================================
BEGIN;
-- ----------------------------------------------------------------------------
-- users
-- ----------------------------------------------------------------------------
-- One row per account. Passwords are stored as bcrypt hashes only — the
-- plaintext password never leaves the /auth/signup handler.
CREATE TABLE IF NOT EXISTS users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
username TEXT NOT NULL,
email TEXT,
password_hash TEXT NOT NULL,
display_name TEXT,
role TEXT NOT NULL DEFAULT 'user',
is_active BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
-- Case-insensitive uniqueness for usernames and emails.
CREATE UNIQUE INDEX IF NOT EXISTS users_username_lower_idx
ON users (lower(username));
CREATE UNIQUE INDEX IF NOT EXISTS users_email_lower_idx
ON users (lower(email))
WHERE email IS NOT NULL;
-- ----------------------------------------------------------------------------
-- updated_at trigger
-- ----------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION set_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS users_set_updated_at ON users;
CREATE TRIGGER users_set_updated_at
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE FUNCTION set_updated_at();
-- ----------------------------------------------------------------------------
-- token_usage
-- ----------------------------------------------------------------------------
-- One row per user per calendar month. ``period_start`` is always the first
-- day of the month (UTC); a new month simply gets a fresh row, which is how
-- the allowance "refreshes" on the first day of every month.
CREATE TABLE IF NOT EXISTS token_usage (
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
period_start DATE NOT NULL,
tokens_used BIGINT NOT NULL DEFAULT 0,
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (user_id, period_start)
);
DROP TRIGGER IF EXISTS token_usage_set_updated_at ON token_usage;
CREATE TRIGGER token_usage_set_updated_at
BEFORE UPDATE ON token_usage
FOR EACH ROW
EXECUTE FUNCTION set_updated_at();
COMMIT;
-- ============================================================================
-- Notes
-- ============================================================================
-- * Requires the pgcrypto extension for gen_random_uuid(). On Postgres 13+
-- it is built in; on older versions run:
-- CREATE EXTENSION IF NOT EXISTS pgcrypto;
-- * The application connects with the DATABASE_URL environment variable,
-- e.g.: postgresql://user:password@localhost:5432/personal_assistant
-- * JWT signing uses the JWT_SECRET environment variable (HS256).
-- ============================================================================