-- ============================================================================
-- V12 — 2차 인증(TOTP RFC6238) 완결: OTP 상태·로그인 실패 잠금 컬럼 멱등 정합.
-- 보안 불변(계약 §0-3): otp_secret 은 AES-256-GCM 암호화 저장(SecretCipher), API 응답/로그 노출 금지.
-- 주의: 아래 컬럼 다수는 V2/V7 에서 이미 생성됨 → 전부 IF NOT EXISTS 멱등 ALTER(재현·이관 안전).
-- ============================================================================

-- 신규: OTP 최초 활성(검증 완료) 시각 — 감사/마이페이지 상태 표시용.
ALTER TABLE app_user ADD COLUMN IF NOT EXISTS otp_verified_at timestamptz;

-- 기존 정합 재확인(멱등) — 신규 환경/부분 이관 대비.
ALTER TABLE app_user ADD COLUMN IF NOT EXISTS otp_secret         varchar(255);
ALTER TABLE app_user ADD COLUMN IF NOT EXISTS otp_enabled        boolean     NOT NULL DEFAULT false;
ALTER TABLE app_user ADD COLUMN IF NOT EXISTS verify_method      varchar(10) NOT NULL DEFAULT 'EMAIL';
ALTER TABLE app_user ADD COLUMN IF NOT EXISTS failed_login_count integer     NOT NULL DEFAULT 0;
ALTER TABLE app_user ADD COLUMN IF NOT EXISTS locked_until       timestamptz;

-- 암호문(enc:v1:base64) 수용을 위해 폭 확장(V2 는 varchar(96)) — 멱등.
ALTER TABLE app_user ALTER COLUMN otp_secret TYPE varchar(255);

COMMENT ON COLUMN app_user.otp_verified_at IS 'OTP 최초 활성(검증) 시각 — 감사/상태 표시';
COMMENT ON COLUMN app_user.otp_secret      IS 'TOTP 시크릿(AES-256-GCM 봉인, enc:v1:) — API 응답/로그 노출 금지(계약 §0-3)';

-- 잠금 만료 조회/스윕 최적화(부분 인덱스) — 멱등.
CREATE INDEX IF NOT EXISTS idx_app_user_locked_until ON app_user (locked_until) WHERE locked_until IS NOT NULL;
