Files
portfolio-hub/docs/batches/bat-002_20260502_service-token-rotate-cli/verification.md
T
genichin b4d964253b feat(REQ-012): implement service token rotation CLI
- Add service token rotation CLI command with force flag support
- Implement token rotation in auth service with expiration handling
- Add portfolio repository helper for transaction/batch operations
- Add cascade delete support in postgres repository
- Add comprehensive CLI tests for service token operations
- Add REQ-012 specification for service token rotation
- Create BAT-002 delivery batch for token rotation implementation
- Update SRS and batch indexes
2026-05-02 12:43:43 +00:00

3.3 KiB

BAT-002 Verification

  • Status: verified
  • Batch: BAT-002
  • Profile: batch-lite
  • Verified: 2026-05-02

Included REQ

  • REQ-012: service-token rotate CLI 명령 구현

Architecture Impact

  • Design Gate (from planning.md): Design Required Before Implementation — no
  • Reason: DB 스키마 변경 없음. 기존 패턴(issue/revoke) 동일하게 적용. 결정 사항 없음.
  • Confirmed: 구조/인터페이스/런타임 흐름 변경 없음 — no architecture impact confirmed
  • Baseline Docs Update Required: no

Acceptance Mapping

REQ-012 AC-1

Given expires_at IS NULL인 유효한 service-token 이름, When pfhub service-token rotate <name> --force를 실행, Then DB 행의 token_hash, token_prefix, runtime_id가 새 값으로 변경되고 id, permission, expires_at(NULL)은 기존과 동일하다.

  • Evidence: test_cli_service_token_rotate_no_expiry_succeeds
    • rotated.token_prefix != "oldpref" 검증
    • rotated.runtime_id != "old-runtime-id" 검증
    • expires_at=None 유지 검증 (rotate 후 기존 token 조회 → expires_at 변경 없음)
  • Result: PASS

REQ-012 AC-2

Given rotate 성공, When CLI 출력, Then 새 token 원문이 화면에 1회 출력되고 "이 토큰은 지금 1회만 표시" 안내 메시지가 함께 표시된다.

  • Evidence: test_cli_service_token_rotate_no_expiry_succeeds
    • result.stdout에 "token:" 포함 확인
    • CLI 출력 패턴: ⚠ 갱신된 토큰 원문은 지금 1회만 표시됩니다. + token: <raw>
  • Result: PASS

REQ-012 AC-3

Given 존재하지 않는 token 이름, When rotate, Then 오류 메시지를 출력하고 종료 코드 1을 반환한다.

  • Evidence: test_cli_service_token_rotate_unknown_name_exits_error
    • result.exit_code == 1 검증
    • "nonexistent" in result.stdout 검증
  • Result: PASS

REQ-012 AC-4

Given revoked 상태의 token, When rotate, Then 오류 메시지를 출력하고 종료 코드 1을 반환한다.

  • Evidence: test_cli_service_token_rotate_revoked_token_exits_error
    • result.exit_code == 1 검증
    • "old-token" in result.stdout 검증
  • Result: PASS

REQ-012 AC-5

Given expires_at이 NULL이 아닌(만료일이 설정된) token, When rotate, Then "만료일이 설정된 토큰은 rotate할 수 없습니다" 오류를 출력하고 종료 코드 1을 반환한다.

  • Evidence: test_cli_service_token_rotate_with_expiry_exits_error
    • result.exit_code == 1 검증
    • "expiring" in result.stdout 검증
  • Result: PASS

REQ-012 AC-6

Given --force 없이 실행, When CLI, Then 확인 프롬프트를 표시하고 거절 시 변경 없이 종료한다.

  • Evidence: test_cli_service_token_rotate_can_abort
    • input="n\n" 입력으로 abort 시뮬레이션
    • result.exit_code == 0 검증
    • token.token_prefix == "pref" (변경 없음) 검증
  • Result: PASS

Test Summary

tests/test_cli.py — 37 passed (신규 5개 포함, 회귀 없음)

rotate 관련:
  test_cli_service_token_rotate_no_expiry_succeeds         PASSED
  test_cli_service_token_rotate_unknown_name_exits_error   PASSED
  test_cli_service_token_rotate_revoked_token_exits_error  PASSED
  test_cli_service_token_rotate_with_expiry_exits_error    PASSED
  test_cli_service_token_rotate_can_abort                  PASSED

Blocking Issues

없음.

Ready for Release

  • true