작업 내용 저장

This commit is contained in:
2026-04-23 09:56:08 +00:00
parent 514b49cb98
commit d383c7086f
29 changed files with 1654 additions and 1372 deletions
@@ -0,0 +1,164 @@
# 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 <name> --user <username>` 명령으로 사용자 기반 소유권을 명확히 한다.
## 검증 결과 요약
- 검증 항목 수: 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