# 0. 문서 상태 이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다. - 상태: confirmed - 문서 ID: sdlc-002_20260423_service-token-user-based - 이슈명: service-token user-based 소유권 - 참조 Verification: docs/sdlc/sdlc-002_20260423_service-token-user-based/5_verification.md - 작성 시각(KST): 2026-04-23 - 마지막 갱신 시각(KST): 2026-04-23 # 1. Verification 인계 요약 Verification에서 완료된 핵심 내용을 요약한다. 원본은 5_verification.md를 참조하며, 이 섹션은 Release 작업의 입력 기준선이 된다. ## 이슈 목적 `bot_principals` / `auth_audit_logs` 테이블을 제거하고, service token을 `auth_tokens` 단일 엔티티로 직접 발급하도록 재구현한다. CLI `pfhub service-token issue --user ` 명령으로 사용자 기반 소유권을 명확히 한다. ## 검증 결과 요약 - 검증 항목 수: 10개 - 전체 통과 여부: false (VC-8~VC-10 수동 DB 검증 미완료) - 자동 검증 통과: 7 / 10 (VC-1~VC-7) - 결함(BUG) 잔여: 0건 ## 이월된 오픈 질문 / 리스크 Verification에서 이월된 항목: - **VC-8 (이월)**: `alembic upgrade head` 실행 가능 여부 — 라이브 DB 환경 미기동으로 미검증. 배포 전 로컬 Docker Compose 환경에서 Justin이 수행해야 한다. - **VC-9 (이월)**: `alembic downgrade -1` 복원 가능 여부 — 동일. 배포 전 Justin이 수행. - **VC-10 (이월)**: `auth_tokens.user_id FK` 정합성 쿼리 — 동일. 배포 전 Justin이 수행. - **R-1 (이월, High)**: 운영 DB에 `bot_principals.owner_user_id IS NULL` 행이 존재하면 마이그레이션 upgrade 시 FK 위반 발생 가능 — upgrade 실행 전 `SELECT COUNT(*) FROM bot_principals WHERE owner_user_id IS NULL` 결과 0건 확인 필수. # 2. 배포 준비 배포 환경, 배포 전 체크리스트, 배포 순서를 정의한다. ## 배포 환경 - 대상 환경: production (Linux/Ubuntu 서버, systemd + uvicorn + Caddy) - 배포 방식: 수동 — git pull 또는 파일 복사 후 마이그레이션 실행 및 서비스 재시작 - 배포 도구/채널: git, alembic, systemctl (CI/CD 파이프라인 없음) ## 배포 전 체크리스트 배포 실행 전에 확인해야 할 항목을 나열한다. - [ ] 로컬 Docker Compose 환경에서 VC-8 (alembic upgrade head) 성공 확인 - [ ] 로컬 Docker Compose 환경에서 VC-9 (alembic downgrade -1) 성공 확인 - [ ] 로컬 Docker Compose 환경에서 VC-10 (auth_tokens.user_id FK 정합성 쿼리) 0건 확인 - [ ] 운영 DB에서 `SELECT COUNT(*) FROM bot_principals WHERE owner_user_id IS NULL` 결과 0건 확인 (R-1) - [ ] 운영 DB 전체 백업 완료 - [ ] 배포 대상 서버에서 `git log --oneline -5` 로 현재 배포 커밋 해시 기록 - [ ] 롤백 계획 확인 완료 ## 배포 순서 변경 사항의 배포 순서를 적는다. 의존 관계가 있는 경우 순서를 명확히 기술한다. 1. **코드 업데이트**: 배포 서버에서 `git pull` 또는 소스 파일 배포 (마이그레이션 파일 포함) 2. **패키지 재설치 확인**: 이번 변경 사항에 의존성 추가 없음 — 생략 3. **DB 마이그레이션**: `alembic upgrade head` — `bot_principals`, `auth_audit_logs` DROP, token_type 보정, UNIQUE INDEX 생성 4. **서비스 재시작**: `sudo systemctl restart portfoliohub` (또는 프로세스 매니저에 따라 uvicorn 재기동) 5. **배포 후 확인**: 스모크 테스트 수행 (`GET /health`, CLI --help, OpenAPI 확인) # 3. 롤백 계획 배포 후 문제가 발생했을 때 이전 상태로 되돌리는 방법을 기술한다. ## 롤백 조건 아래 조건 중 하나라도 충족되면 롤백을 즉시 실행한다. - 배포 후 `GET /health` 응답이 200이 아닌 경우 - `pfhub service-token issue --help` 실행 시 오류 발생 또는 NAME/--user 미노출 - 인증 관련 API (`/auth/login`, `/auth/tokens`) 오류율 급증 (5분 내 비정상 응답 3회 이상) - 마이그레이션 upgrade 실패 또는 롤백 불가 오류 발생 ## 롤백 절차 1. **서비스 중단**: `sudo systemctl stop portfoliohub` 2. **DB 마이그레이션 롤백**: `alembic downgrade -1` — `bot_principals`, `auth_audit_logs` 테이블 재생성, token_type 복원, UNIQUE INDEX DROP 3. **코드 롤백**: `git checkout <이전 커밋 해시>` 또는 이전 소스 파일 복원 4. **서비스 재기동**: `sudo systemctl start portfoliohub` 5. **롤백 확인**: `GET /health` 200 응답 확인 ## 롤백 담당자 - Justin # 4. 배포 후 확인 배포 완료 후 정상 동작을 확인하는 방법을 기술한다. ## 스모크 테스트 항목 | 항목 | 확인 방법 | 성공 기준 | |------|---------|---------| | 헬스 체크 정상 응답 | `curl -s http://localhost:8000/health` | HTTP 200, `{"status":"ok"}` | | CLI service-token issue 명령 노출 | `pfhub service-token issue --help` | NAME, --user 노출. "bot" 문자열 없음. exit 0 | | CLI --user 필수 옵션 강제 | `pfhub service-token issue nightly` (--user 생략) | exit 2, "Missing option '--user'" 출력 | | /auth/bots 경로 미노출 | `curl -s http://localhost:8000/openapi.json \| python3 -m json.tool \| grep bot` | 출력 없음 (0건) | | DB 마이그레이션 반영 | `psql -c "\dt bot_principals"` | 테이블 없음 (`Did not find any relation named "bot_principals"`) | ## 모니터링 확인 항목 배포 후 일정 시간 동안 모니터링해야 하는 지표나 로그를 기록한다. - `journalctl -u portfoliohub -f`: 배포 직후 30분간 ERROR/CRITICAL 로그 없음 확인 - `/auth/login`, `/auth/tokens` 엔드포인트 정상 응답 유지 확인 (1시간) - `auth_tokens` 테이블 `token_type = 'service'` 행 존재 여부: `SELECT COUNT(*) FROM auth_tokens WHERE token_type = 'service'` 결과 확인 (service token 발급 이력이 있는 경우에 한해 수행) # 5. 리스크 및 오픈 질문 Release 단계에서 새로 식별된 리스크와 오픈 질문을 기록한다. ## 리스크 - R-1 (High, 이월): 운영 DB에 `bot_principals.owner_user_id IS NULL` 행 존재 시 마이그레이션 upgrade FK 위반 - 완화 방안: 배포 전 체크리스트에 사전 쿼리 확인 포함. NULL 행 존재 시 배포 중단 후 수동 정리. - R-2 (Medium, 이월): VC-8~VC-10 수동 검증 미완료 상태로 배포 진행 시 DB 변경 미검증 위험 - 완화 방안: 배포 전 로컬 Docker Compose 환경에서 Justin이 VC-8~VC-10 완료 후 배포 진행. ## 오픈 질문 없음. # 6. Operations로 넘기기 전 확인 체크 Operations 단계로 넘기기 전에 무엇이 완료되어야 하는지 확인한다. - [ ] 배포 완료 및 스모크 테스트 통과 - 기준: `# 4` 스모크 테스트 항목 전 항목이 성공 기준을 충족하였는가 - [ ] 롤백 계획 확정 - 기준: 롤백 조건, 절차, 담당자(`REL_ROLLBACK_OWNER`)가 모두 명시되었는가 - [ ] 배포 전 VC-8~VC-10 수동 검증 완료 확인 - 기준: Justin이 로컬 Docker Compose 환경에서 VC-8, VC-9, VC-10 모두 통과 확인 - [ ] R-1 사전 쿼리 확인 완료 - 기준: `SELECT COUNT(*) FROM bot_principals WHERE owner_user_id IS NULL` 결과 0건 - [ ] 모든 오픈 질문(OQ) `Open` 상태 없음 확인 - 기준: OQ 목록에 `Open` 상태 항목이 0개 — 현재 없음 - [ ] Freeze 확정 담당자(CONFIRMED_BY) 지정 - 기준: 담당자 Justin 지정 완료 — confirm-release 단계에서 처리 # 7. 파일 처리 결과 이 Release 문서 생성/갱신 결과와 참조 문서를 기록한다. - 처리 결과: 생성 - 생성 경로: docs/sdlc/sdlc-002_20260423_service-token-user-based/6_release.md - 참조 문서: - 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/technical/deployment-and-operations.md # 8. 사용자 결정 필요 항목 요약 사용자나 승인자가 결정해야 하는 항목만 모아 정리한다. ## DECIDE 없음. ## CONFIRM - Freeze 확정 담당자(`CONFIRMED_BY`): Justin — confirm-release 단계에서 처리 ## DATA - 롤백 담당자(`REL_ROLLBACK_OWNER`): 지정 필요 (Justin 또는 담당 운영자) - 배포 전 VC-8~10: 로컬 Docker Compose 환경(`docker compose -f docker-compose.local-test.yml up -d`) 기동 후 수행 - 운영 DB 사전 쿼리: `SELECT COUNT(*) FROM bot_principals WHERE owner_user_id IS NULL` — 0건이어야 배포 진행 가능 # 9. Release Freeze Operations 인계 시점의 확정 플래그와 섹션 참조만 기록한다. 내용 재작성 없이 원본 섹션을 링크로 대신한다. ## 섹션 참조 - 배포 준비: [# 2. 배포 준비](#2-배포-준비) - 롤백 계획: [# 3. 롤백 계획](#3-롤백-계획) - 배포 후 확인: [# 4. 배포 후 확인](#4-배포-후-확인) ## 확정 플래그 - Handoff Decision: 승인 - Handoff Rationale: 배포 완료 및 스모크 테스트 통과 후 Operations로 인계 - Ready for Operations: true - Confirmed By: Justin - Confirmed At (KST): 2026-04-23