feat: add organization policy center

This commit is contained in:
xz
2026-09-01 13:22:04 +08:00
parent a9c8eea271
commit 1d4154dd20
12 changed files with 1565 additions and 12 deletions
+43
View File
@@ -501,6 +501,40 @@ CREATE TABLE IF NOT EXISTS organization_entitlements (
UNIQUE (organization_id, entitlement_key)
);
CREATE TABLE IF NOT EXISTS organization_policies (
id TEXT PRIMARY KEY,
organization_id TEXT NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
policy_key TEXT NOT NULL,
category TEXT NOT NULL DEFAULT 'production',
label TEXT NOT NULL,
description TEXT NOT NULL DEFAULT '',
status TEXT NOT NULL DEFAULT 'enforced' CHECK (status IN ('draft', 'enforced', 'monitor', 'disabled')),
enforcement TEXT NOT NULL DEFAULT 'block' CHECK (enforcement IN ('block', 'approval', 'warn', 'off')),
severity TEXT NOT NULL DEFAULT 'high' CHECK (severity IN ('critical', 'high', 'medium', 'low')),
value_json TEXT NOT NULL DEFAULT '{}',
applies_to_json TEXT NOT NULL DEFAULT '[]',
approval_required INTEGER NOT NULL DEFAULT 0,
updated_by TEXT REFERENCES users(id),
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL,
UNIQUE (organization_id, policy_key)
);
CREATE TABLE IF NOT EXISTS organization_policy_evaluations (
id TEXT PRIMARY KEY,
organization_id TEXT NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
workspace_id TEXT REFERENCES workspaces(id) ON DELETE SET NULL,
project_id TEXT REFERENCES projects(id) ON DELETE SET NULL,
policy_key TEXT NOT NULL,
subject_type TEXT NOT NULL DEFAULT 'generation_request',
subject_id TEXT NOT NULL DEFAULT '',
result TEXT NOT NULL DEFAULT 'pass' CHECK (result IN ('pass', 'warn', 'approval_required', 'block')),
reason TEXT NOT NULL DEFAULT '',
evidence_json TEXT NOT NULL DEFAULT '{}',
created_by TEXT REFERENCES users(id),
created_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS commercial_approval_requests (
id TEXT PRIMARY KEY,
organization_id TEXT NOT NULL REFERENCES organizations(id) ON DELETE CASCADE,
@@ -574,6 +608,8 @@ CREATE INDEX IF NOT EXISTS idx_organization_invoices_org_status ON organization_
CREATE INDEX IF NOT EXISTS idx_invoice_lines_invoice_sort ON invoice_lines(invoice_id, sort_order, created_at);
CREATE INDEX IF NOT EXISTS idx_subscription_plan_templates_status ON subscription_plan_templates(status, tier_key);
CREATE INDEX IF NOT EXISTS idx_organization_entitlements_org_category ON organization_entitlements(organization_id, category, entitlement_key);
CREATE INDEX IF NOT EXISTS idx_organization_policies_org_category ON organization_policies(organization_id, category, policy_key);
CREATE INDEX IF NOT EXISTS idx_organization_policy_evaluations_scope ON organization_policy_evaluations(organization_id, workspace_id, project_id, result, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_commercial_approvals_org_status ON commercial_approval_requests(organization_id, status, updated_at DESC);
CREATE INDEX IF NOT EXISTS idx_commercial_approvals_requester ON commercial_approval_requests(requester_user_id, status, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_commercial_approvals_target ON commercial_approval_requests(organization_id, request_type, target_key, status);
@@ -1035,6 +1071,13 @@ CREATE TABLE IF NOT EXISTS generation_jobs (
updated_at TEXT NOT NULL
);
CREATE TRIGGER IF NOT EXISTS trg_policy_evaluations_after_job_delete
AFTER DELETE ON generation_jobs
BEGIN
DELETE FROM organization_policy_evaluations
WHERE subject_type = 'generation_job' AND subject_id = OLD.id;
END;
CREATE TABLE IF NOT EXISTS job_attempts (
id TEXT PRIMARY KEY,
job_id TEXT NOT NULL REFERENCES generation_jobs(id) ON DELETE CASCADE,