Files

52 lines
2.2 KiB
SQL
Raw Permalink Normal View History

2026-09-13 20:21:31 +01:00
-- Users table
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(100) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
role VARCHAR(20) NOT NULL DEFAULT 'user' CHECK (role IN ('admin', 'user')),
mfa_secret VARCHAR(255),
mfa_enabled BOOLEAN DEFAULT FALSE,
must_change_password BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Field definitions table (dynamic fields configured by admin)
CREATE TABLE IF NOT EXISTS field_definitions (
id SERIAL PRIMARY KEY,
field_key VARCHAR(100) UNIQUE NOT NULL, -- internal key e.g. "first_name"
label VARCHAR(200) NOT NULL, -- display label e.g. "First Name"
field_type VARCHAR(20) NOT NULL DEFAULT 'text' CHECK (field_type IN ('text', 'number', 'phone', 'email')),
required BOOLEAN DEFAULT FALSE,
sort_order INTEGER DEFAULT 0,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Contracts table with JSONB data (fully dynamic)
CREATE TABLE IF NOT EXISTS mobile_contracts (
id SERIAL PRIMARY KEY,
data JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Audit log table
CREATE TABLE IF NOT EXISTS audit_log (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
action VARCHAR(100) NOT NULL,
details TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Seed default fields
INSERT INTO field_definitions (field_key, label, field_type, required, sort_order) VALUES
('first_name', 'First Name', 'text', TRUE, 1),
('last_name', 'Last Name', 'text', TRUE, 2),
('phone_number', 'Phone Number', 'phone', FALSE, 3),
('mobile_contract_number', 'Mobile Contract Number', 'text', FALSE, 4),
('monthly_fixed_cost', 'Monthly Fixed Cost', 'number', FALSE, 5),
('monthly_available_data', 'Monthly Available Data', 'number', FALSE, 6)
ON CONFLICT (field_key) DO NOTHING;