-- 004_admin_queue.sql -- Admin users, order queue management, and audit log. BEGIN; -- Admin users (password stored as bcrypt hash) CREATE TABLE IF NOT EXISTS admin_users ( id SERIAL PRIMARY KEY, username TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL, display_name TEXT, email TEXT, active BOOLEAN DEFAULT TRUE, last_login_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT now() ); -- Order audit log — tracks every state change and admin action CREATE TABLE IF NOT EXISTS order_audit_log ( id SERIAL PRIMARY KEY, -- Which order (supports both formation_orders and general orders) order_type TEXT NOT NULL CHECK (order_type IN ('formation', 'service', 'quote')), order_id INTEGER NOT NULL, order_number TEXT, -- What happened action TEXT NOT NULL, -- 'status_change', 'note_added', 'manual_filing', 'document_uploaded', 'assigned', 'escalated', 'refunded' from_status TEXT, to_status TEXT, -- Who did it actor_type TEXT NOT NULL CHECK (actor_type IN ('system', 'admin', 'worker', 'customer')), actor_id INTEGER, -- admin_users.id if actor_type = 'admin' actor_name TEXT, -- Details note TEXT, metadata JSONB, -- flexible: file paths, error details, automation output, etc. -- Timestamp created_at TIMESTAMPTZ DEFAULT now() ); CREATE INDEX IF NOT EXISTS idx_audit_order ON order_audit_log(order_type, order_id); CREATE INDEX IF NOT EXISTS idx_audit_action ON order_audit_log(action); CREATE INDEX IF NOT EXISTS idx_audit_created ON order_audit_log(created_at DESC); -- Add queue management columns to formation_orders ALTER TABLE formation_orders ADD COLUMN IF NOT EXISTS assigned_to INTEGER REFERENCES admin_users(id); ALTER TABLE formation_orders ADD COLUMN IF NOT EXISTS priority TEXT DEFAULT 'normal' CHECK (priority IN ('low', 'normal', 'high', 'urgent')); ALTER TABLE formation_orders ADD COLUMN IF NOT EXISTS automation_status TEXT DEFAULT 'pending' CHECK (automation_status IN ('pending', 'running', 'succeeded', 'failed', 'manual')); ALTER TABLE formation_orders ADD COLUMN IF NOT EXISTS automation_error TEXT; ALTER TABLE formation_orders ADD COLUMN IF NOT EXISTS automation_attempts INTEGER DEFAULT 0; ALTER TABLE formation_orders ADD COLUMN IF NOT EXISTS admin_notes TEXT; ALTER TABLE formation_orders ADD COLUMN IF NOT EXISTS last_activity_at TIMESTAMPTZ DEFAULT now(); CREATE INDEX IF NOT EXISTS idx_formation_automation ON formation_orders(automation_status); CREATE INDEX IF NOT EXISTS idx_formation_assigned ON formation_orders(assigned_to); CREATE INDEX IF NOT EXISTS idx_formation_priority ON formation_orders(priority); -- Add similar columns to general orders table ALTER TABLE orders ADD COLUMN IF NOT EXISTS assigned_to INTEGER REFERENCES admin_users(id); ALTER TABLE orders ADD COLUMN IF NOT EXISTS priority TEXT DEFAULT 'normal'; ALTER TABLE orders ADD COLUMN IF NOT EXISTS admin_notes TEXT; COMMIT;