-- W1 거버넌스/RBAC. 멱등. db/apply-local-ddl.sh 로 실행 DB 비파괴 적용.
-- 기존 데이터(전원 role='USER') 호환 — 추가만, 파괴 없음.

-- 1) users.role 값집합 확장 (CHECK 멱등 추가)
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'users_role_check') THEN
        ALTER TABLE "users"
            ADD CONSTRAINT "users_role_check"
            CHECK ("role" IN ('ADMIN', 'SUBADMIN', 'USER'));
    END IF;
END
$$;

-- 2) users.permissions_epoch (세션 권한 전파 버전 스탬프)
ALTER TABLE "users"
    ADD COLUMN IF NOT EXISTS "permissions_epoch" bigint DEFAULT 0 NOT NULL;
COMMENT ON COLUMN "users"."permissions_epoch" IS
    'RBAC 권한 변경 버전. 변경 시 +1 → 세션 캐시 epoch 와 mismatch 시 권한 재로딩(회수 즉시성, 결정4)';

-- 3) permissions (권한 카탈로그)
CREATE SEQUENCE IF NOT EXISTS "permissions_id_seq";
CREATE TABLE IF NOT EXISTS "permissions" (
    "id"             bigint DEFAULT nextval('permissions_id_seq'::regclass) NOT NULL,
    "permission_key" character varying(50) NOT NULL,
    "display_name"   character varying(100) NOT NULL,
    "is_active"      boolean DEFAULT true NOT NULL,
    "created_at"     timestamp with time zone DEFAULT now() NOT NULL,
    PRIMARY KEY ("id")
);
ALTER SEQUENCE "permissions_id_seq" OWNED BY "permissions"."id";
CREATE UNIQUE INDEX IF NOT EXISTS "ux_permissions_key"
    ON "permissions" ("permission_key");

-- 4) user_permissions (SUBADMIN 개별 권한 join)
CREATE SEQUENCE IF NOT EXISTS "user_permissions_id_seq";
CREATE TABLE IF NOT EXISTS "user_permissions" (
    "id"             bigint DEFAULT nextval('user_permissions_id_seq'::regclass) NOT NULL,
    "user_id"        bigint NOT NULL,
    "permission_key" character varying(50) NOT NULL,
    "granted_by"     bigint,
    "created_at"     timestamp with time zone DEFAULT now() NOT NULL,
    PRIMARY KEY ("id")
);
ALTER SEQUENCE "user_permissions_id_seq" OWNED BY "user_permissions"."id";
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'user_permissions_user_id_fkey') THEN
        ALTER TABLE "user_permissions"
            ADD CONSTRAINT "user_permissions_user_id_fkey"
            FOREIGN KEY ("user_id") REFERENCES "users" ("id");
    END IF;
END
$$;
CREATE UNIQUE INDEX IF NOT EXISTS "ux_user_permissions_user_key"
    ON "user_permissions" ("user_id", "permission_key");
CREATE INDEX IF NOT EXISTS "idx_user_permissions_user"
    ON "user_permissions" ("user_id");

-- 5) rbac_audit_log (감사로그 — 임명/강등/토글 대칭 기록)
CREATE SEQUENCE IF NOT EXISTS "rbac_audit_log_id_seq";
CREATE TABLE IF NOT EXISTS "rbac_audit_log" (
    "id"            bigint DEFAULT nextval('rbac_audit_log_id_seq'::regclass) NOT NULL,
    "actor_id"      bigint NOT NULL,
    "target_id"     bigint NOT NULL,
    "action"        character varying(30) NOT NULL,
    "permission_key" character varying(50),
    "created_at"    timestamp with time zone DEFAULT now() NOT NULL,
    PRIMARY KEY ("id")
);
ALTER SEQUENCE "rbac_audit_log_id_seq" OWNED BY "rbac_audit_log"."id";
DO $$
BEGIN
    IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'rbac_audit_log_action_check') THEN
        ALTER TABLE "rbac_audit_log"
            ADD CONSTRAINT "rbac_audit_log_action_check"
            CHECK ("action" IN ('APPOINT', 'DEMOTE', 'GRANT', 'REVOKE'));
    END IF;
END
$$;
