10 KiB
10 KiB
0. 문서 상태
이 문서의 현재 상태와 식별 정보를 기록한다.
- 상태: confirmed
- 문서 ID: sdlc-002_20260423_service-token-user-based
- 이슈명: service-token user-based 소유권
- 참조 Implementation: docs/sdlc/sdlc-002_20260423_service-token-user-based/4_implementation.md
- 작성 시각(KST): 2026-04-23
- 마지막 갱신 시각(KST): 2026-04-23
1. Implementation 인계 요약
Implementation에서 완료된 핵심 내용을 요약한다. 원본은 4_implementation.md를 참조하며, 이 섹션은 Verification 작업의 입력 기준선이 된다.
이슈 목적
bot_principals / auth_audit_logs 테이블을 제거하고, service token을 auth_tokens 단일 엔티티로 직접 발급하도록 재구현한다. CLI pfhub service-token issue <name> --user <username> 명령으로 사용자 기반 소유권을 명확히 한다.
구현 완료 태스크
| ID | 태스크 제목 | 변경 파일/함수 | 완료 조건(DoD) |
|---|---|---|---|
| T-1 | DB 마이그레이션 파일 작성 | migrations/versions/20260423_0013_remove_bot_principals_service_tokens.py |
alembic upgrade head 후 bot_principals/auth_audit_logs DROP, token_type 보정, UNIQUE INDEX 생성. downgrade 복원 가능 |
| T-2 | 도메인/스키마/인터페이스 정리 | app/domain/models.py, app/schemas/auth.py, app/repositories/portfolio_repository.py |
BotPrincipal 미존재, ServiceTokenIssueCliResponse import 가능, bot 메서드 미존재 |
| T-3 | postgres.py 구현체 정리 | app/repositories/postgres.py |
ensure_schema() 재실행 후 bot_principals/auth_audit_logs 미생성, get_service_token_by_name() 존재 |
| T-4 | AuthContext/security.py 변경 | app/core/auth.py, app/core/security.py |
AuthContext.token_type 사용 가능, bot_principal_id 없음, build_audit_event ImportError |
| T-5 | AuthService 재구현 | app/services/auth_service.py |
issue_service_token() 시그니처 존재, bot 메서드 미존재 |
| T-6 | API 경로 정리 | app/api/auth_routes.py |
/auth/bots, /auth/me/bots 경로 미노출 |
| T-7 | CLI 재구현 | app/cli/commands/service_tokens.py (신규), app/cli/core/output.py, app/cli/main.py |
pfhub service-token issue --help에 NAME, --user 노출, bot 문자열 없음 |
| T-8 | 테스트 업데이트 | tests/test_auth.py, tests/test_cli.py, tests/test_portfolio_ownership.py, tests/test_users.py |
pytest 결과 0 failures, 0 errors, service token 시나리오 테스트 포함 |
| T-9 | 기술 문서 업데이트 | docs/technical/auth-and-token-lifecycle.md, docs/technical/api-contracts.md, docs/technical/management-cli-operations.md, README.md |
4개 문서에서 bot_principal/bot token 잔류 참조 없음, pfhub service-token 예제 포함 |
이월된 오픈 질문 / 리스크
없음. Implementation 단계에서 모든 OQ 해소 완료.
2. 검증 계획
Discovery # 7 성공 기준(S-N)을 기반으로 Verification 항목을 정의한다.
검증 범위
- 기능 요구사항(FR-1~FR-7) 전체 충족 여부
- 비기능 요구사항(NFR-1~NFR-3) 충족 여부 (테스트 통과, 마이그레이션 양방향, CLI 잔류 참조 없음)
- Discovery 성공 기준(S-1~S-3) 연결 확인
검증 항목
| ID | 검증 항목 | 검증 방법 | 성공 기준 | 담당자 |
|---|---|---|---|---|
| VC-1 | 단위 테스트 전체 통과 | 자동 | pytest tests/ -q 실행 결과 73 passed, 0 failed, 0 errors |
copilot |
| VC-2 | CLI service-token 명령 정상 노출 | 수동 | pfhub service-token --help 출력에 issue, revoke 노출. NAME, --user 인수 표시. "bot" 문자열 없음 |
copilot |
| VC-3 | bot 관련 코드 잔류 없음 | 자동 | grep -r "BotPrincipal|bot_principal_id|bot_principals" app/ 결과 0건 (마이그레이션 파일 제외) |
copilot |
| VC-4 | service token 발급 시 user_id 직접 저장 | 자동 | test_issue_service_token_defaults_to_365_days 통과. 발급 토큰의 user_id가 users.id와 일치 | copilot |
| VC-5 | service token name 중복 시 오류 반환 | 자동 | app/services/auth_service.py L144~145에 psycopg.errors.UniqueViolation catch 존재 확인. 코드 리뷰로 처리 경로 확인. DB 제약 강제는 VC-8(migration UNIQUE INDEX)이 담당 |
copilot |
| VC-6 | --user 필수 옵션 강제 | 자동 | pfhub service-token issue nightly (--user 생략) 실행 시 exit code != 0 |
copilot |
| VC-7 | /auth/bots 경로 미노출 확인 | 자동 | FastAPI openapi.json에 /auth/bots, /auth/me/bots 경로 미포함 |
copilot |
| VC-8 | 마이그레이션 파일 upgrade 실행 가능 확인 | 수동 | alembic upgrade head 실행 오류 없음. bot_principals, auth_audit_logs 테이블 DROP 확인 |
Justin |
| VC-9 | 마이그레이션 downgrade 복원 가능 확인 | 수동 | alembic downgrade -1 실행 오류 없음. bot_principals 테이블 재생성 확인 |
Justin |
| VC-10 | auth_tokens.user_id FK 정합성 확인 | 수동 | 마이그레이션 후 SELECT COUNT(*) FROM auth_tokens WHERE user_id NOT IN (SELECT id FROM users) 결과 0건 |
Justin |
성공 기준 연결
Discovery의 성공 기준(S-N)과 검증 항목(VC-N)의 연결을 명시한다.
- S-1 (pytest 전체 통과) → VC-1, VC-4, VC-5, VC-6
- S-2 (CLI service-token 명령 정상 노출) → VC-2, VC-6
- S-3 (마이그레이션 후 auth_tokens.user_id FK 정합성) → VC-8, VC-9, VC-10
FR/NFR 연결:
- FR-1 (bot 관련 코드/테이블 제거) → VC-3, VC-7, VC-8
- FR-2 (user_id 직접 저장) → VC-4, VC-10
- FR-3 (마이그레이션 user_id 보정) → VC-8, VC-10
- FR-4 (get_token_principal 단순화) → VC-1, VC-3
- FR-5 (service token name 유니크) → VC-5
- FR-6 (--user username 조회, 없으면 오류) → VC-4, VC-5
- FR-7 (--user 필수) → VC-6
- NFR-1 (기존 테스트 통과) → VC-1
- NFR-2 (마이그레이션 양방향) → VC-8, VC-9
- NFR-3 (CLI bot 참조 없음) → VC-2, VC-3
3. 검증 결과
검증 수행 후 각 항목의 결과를 기록한다.
| ID | 검증 항목 | 결과 | 비고 |
|---|---|---|---|
| VC-1 | 단위 테스트 전체 통과 | 통과 | pytest tests/ -q: 73 passed, 0 failed, 0 errors |
| VC-2 | CLI service-token 명령 정상 노출 | 통과 | pfhub service-token issue --help: NAME, --user 노출. "bot" 문자열 없음 |
| VC-3 | bot 관련 코드 잔류 없음 | 통과 | grep -r "BotPrincipal|bot_principal_id|bot_principals" app/ 결과 0건 |
| VC-4 | service token 발급 시 user_id 직접 저장 | 통과 | test_issue_service_token_defaults_to_365_days 포함 73 passed |
| VC-5 | service token name 중복 시 오류 반환 | 통과 | auth_service.py L144~145 UniqueViolation catch 코드 리뷰 확인. DB 제약은 VC-8(upgrade 검증) 의존 |
| VC-6 | --user 필수 옵션 강제 | 통과 | pfhub service-token issue nightly (--user 생략): exit code 2, "Missing option '--user'" |
| VC-7 | /auth/bots 경로 미노출 확인 | 통과 | OpenAPI paths에 bot 포함 경로 0건 확인 |
| VC-8 | 마이그레이션 파일 upgrade 실행 가능 확인 | 미완료 | 라이브 DB 환경 필요 |
| VC-9 | 마이그레이션 downgrade 복원 가능 확인 | 미완료 | 라이브 DB 환경 필요 |
| VC-10 | auth_tokens.user_id FK 정합성 확인 | 미완료 | 라이브 DB 환경 필요 |
전체 검증 결과
- 통과: 7 / 10
- 실패/블로킹: 0
- 미완료(수동/DB 필요): 3 (VC-8, VC-9, VC-10)
- 검증 완료 여부: false (VC-8~VC-10 수동 검증 대기)
4. 결함 및 재작업 사항
검증 중 발견된 결함과 재작업이 필요한 항목을 기록한다.
- BUG-1: 없음
5. 리스크 및 오픈 질문
Verification 단계에서 새로 식별된 리스크와 오픈 질문을 기록한다.
리스크
- R-1 (High, 이월): 마이그레이션 upgrade 전
bot_principals.owner_user_id IS NULL행 존재 시 FK 위반 — upgrade() 사전 검사로 차단. 운영 DB 실행 전 NULL 행 수 확인 권장. - R-2 (Medium, 이월): VC-8~VC-10은 실제 DB 환경(Docker Compose)이 필요한 수동 검증 항목이다 — 로컬 Docker Compose 환경 기동 후 검증 수행.
오픈 질문
없음.
6. Release로 넘기기 전 확인 체크
Release 단계로 넘기기 전에 무엇이 완료되어야 하는지 확인한다.
- 모든 검증 항목(VC-N) 통과
- 기준: VC-1~VC-10 모든 항목이 "통과" 상태여야 한다
- 결함(BUG)
Open상태 없음- 기준: BUG 목록에
Open상태 항목이 0개여야 한다
- 기준: BUG 목록에
- 성공 기준(S-N) 전체 충족
- 기준: S-1(VC-1), S-2(VC-2, VC-6), S-3(VC-8, VC-10) 모두 통과
- 모든 오픈 질문(OQ)
Open상태 없음 확인- 기준: OQ 목록에
Open상태 항목이 0개 — 현재 없음
- 기준: OQ 목록에
- Freeze 확정 담당자(CONFIRMED_BY) 지정
- 기준: 담당자 Justin 지정 완료 — 문서 서명 대기
7. 파일 처리 결과
이 Verification 문서 생성/갱신 결과와 참조 문서를 기록한다.
- 처리 결과: 생성
- 생성 경로: docs/sdlc/sdlc-002_20260423_service-token-user-based/5_verification.md
- 참조 문서:
- docs/sdlc/sdlc-002_20260423_service-token-user-based/4_implementation.md
- docs/sdlc/sdlc-002_20260423_service-token-user-based/1_discovery.md
8. 사용자 결정 필요 항목 요약
사용자나 승인자가 결정해야 하는 항목만 모아 정리한다.
DECIDE
없음.
CONFIRM
- Freeze 확정 담당자(
CONFIRMED_BY): Justin — confirm-verification 단계에서 처리
DATA
- VC-8~VC-10 수동 검증은 로컬 Docker Compose DB 환경(
docker compose -f docker-compose.local-test.yml up -d) 기동 후 수행 - 운영 DB 마이그레이션 전
SELECT COUNT(*) FROM bot_principals WHERE owner_user_id IS NULL결과 0건 확인 권장 (R-1)
9. Verification Freeze
Release 인계 시점의 확정 플래그와 섹션 참조만 기록한다.
섹션 참조
- 검증 계획: # 2. 검증 계획
- 검증 결과: # 3. 검증 결과
- 결함/재작업: # 4. 결함 및 재작업 사항
확정 플래그
- Handoff Decision: 승인
- Handoff Rationale: 검증 완료 및 결함 없음 확인 후 Release로 인계
- Ready for Release: true
- Confirmed By: Justin
- Confirmed At (KST): 2026-04-23