krona-staff/migrations/0008_employee_access.up.sql

32 lines
1.7 KiB
SQL

-- Temporary standalone identity mapping. Core remains the owner of users and SSO in platform mode.
-- Raw access tokens are never stored; only a SHA-256 digest and a short non-secret hint are kept.
CREATE TABLE staff_standalone_employee_access (
id VARCHAR(26) PRIMARY KEY CHECK (id ~ '^[0-9A-HJKMNP-TV-Z]{26}$'),
tenant_id VARCHAR(26) NOT NULL CHECK (tenant_id ~ '^[0-9A-HJKMNP-TV-Z]{26}$'),
employee_id VARCHAR(26) NOT NULL,
subject_id VARCHAR(26) NOT NULL CHECK (subject_id ~ '^[0-9A-HJKMNP-TV-Z]{26}$'),
token_hash CHAR(64) NOT NULL CHECK (token_hash ~ '^[0-9a-f]{64}$'),
token_hint VARCHAR(8) NOT NULL,
created_by VARCHAR(26) NOT NULL CHECK (created_by ~ '^[0-9A-HJKMNP-TV-Z]{26}$'),
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
rotated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
UNIQUE (tenant_id, id),
UNIQUE (tenant_id, employee_id),
UNIQUE (tenant_id, subject_id),
UNIQUE (tenant_id, token_hash),
FOREIGN KEY (tenant_id, employee_id) REFERENCES staff_employees (tenant_id, id) ON DELETE CASCADE
);
ALTER TABLE staff_standalone_employee_access ENABLE ROW LEVEL SECURITY;
ALTER TABLE staff_standalone_employee_access FORCE ROW LEVEL SECURITY;
CREATE POLICY staff_standalone_employee_access_tenant_isolation
ON staff_standalone_employee_access
USING (tenant_id = current_setting('app.tenant_id', true))
WITH CHECK (tenant_id = current_setting('app.tenant_id', true));
GRANT SELECT, INSERT, UPDATE, DELETE ON staff_standalone_employee_access TO krona_staff_app;
ALTER TABLE staff_payroll_ledger ADD COLUMN external_key TEXT;
CREATE UNIQUE INDEX staff_payroll_ledger_external_key_idx
ON staff_payroll_ledger (tenant_id, external_key) WHERE external_key IS NOT NULL;