CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; CREATE TABLE IF NOT EXISTS schema_migrations ( version BIGINT PRIMARY KEY, applied_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS users ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), username TEXT UNIQUE NOT NULL, password_hash TEXT NOT NULL, is_admin BOOLEAN NOT NULL DEFAULT false, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS refresh_tokens ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, token_hash TEXT NOT NULL, expires_at TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW(), revoked BOOLEAN NOT NULL DEFAULT false ); CREATE TABLE IF NOT EXISTS notes ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS note_versions ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), note_id UUID NOT NULL REFERENCES notes(id) ON DELETE CASCADE, title TEXT NOT NULL, content TEXT NOT NULL, version_number INT NOT NULL, content_hash TEXT NOT NULL, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE UNIQUE INDEX IF NOT EXISTS idx_users_username ON users(username); CREATE INDEX IF NOT EXISTS idx_refresh_tokens_user_id ON refresh_tokens(user_id); CREATE INDEX IF NOT EXISTS idx_refresh_tokens_expires_at ON refresh_tokens(expires_at); CREATE UNIQUE INDEX IF NOT EXISTS idx_note_version_unique ON note_versions(note_id, version_number); CREATE INDEX IF NOT EXISTS idx_note_versions_note ON note_versions(note_id); CREATE INDEX IF NOT EXISTS idx_note_versions_number ON note_versions(version_number DESC);