mirror of
https://gh-proxy.org/https://github.com/klinsmaya/multica.git
synced 2026-11-08 01:16:45 +08:00
main now carries 583 and 584, so the admin console migrations move past the numbers reserved by the open-connector work (590-599). Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01FrVjAFWeckYV69HS51xUhy
38 lines
1.6 KiB
SQL
38 lines
1.6 KiB
SQL
-- Platform admin console: platform-level roles, an append-only audit log, and
|
|
-- persisted account suspension. Relationships (user ids) are validated in
|
|
-- application code; no foreign keys by project rule.
|
|
--
|
|
-- Primary keys are attached in 585/587 from the indexes built CONCURRENTLY in
|
|
-- 584/586 (repo convention, see 574-575).
|
|
CREATE TABLE IF NOT EXISTS platform_admin (
|
|
user_id UUID NOT NULL,
|
|
role TEXT NOT NULL CHECK (role IN ('super_admin', 'operator', 'viewer')),
|
|
granted_by UUID,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS admin_audit_log (
|
|
id UUID NOT NULL DEFAULT gen_random_uuid(),
|
|
actor_user_id UUID NOT NULL,
|
|
action TEXT NOT NULL,
|
|
target_type TEXT NOT NULL DEFAULT '',
|
|
target_id TEXT NOT NULL DEFAULT '',
|
|
reason TEXT NOT NULL DEFAULT '',
|
|
payload JSONB NOT NULL DEFAULT '{}'::jsonb CHECK (jsonb_typeof(payload) = 'object'),
|
|
ip TEXT NOT NULL DEFAULT '',
|
|
user_agent TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- Persisted suspension replaces the hardcoded denylist in
|
|
-- internal/auth/temporary_disabled_users.go.
|
|
ALTER TABLE "user"
|
|
ADD COLUMN IF NOT EXISTS disabled_at TIMESTAMPTZ,
|
|
ADD COLUMN IF NOT EXISTS disabled_reason TEXT NOT NULL DEFAULT '';
|
|
|
|
-- Carry the former hardcoded denylist over so those accounts stay suspended.
|
|
UPDATE "user" SET disabled_at = now(), disabled_reason = 'migrated from emergency denylist'
|
|
WHERE disabled_at IS NULL
|
|
AND (id IN ('514492f7-b30f-4147-bd33-c0e8ce5d6d4f', '1d542296-17c6-484a-9914-dcee589be116')
|
|
OR lower(email) IN ('[email protected]', '[email protected]'));
|