BAT-006 (REQ-016/017/018): - client token 발급 경로 제거 (issue_client_token, POST /auth/tokens, 관련 스키마/테스트) - service-token rotate unique index revoked_at IS NULL 조건 추가 (Alembic CONCURRENTLY 마이그레이션) - POST /auth/service-tokens body daemon_id forward 누락 보정 (1-line fix) BAT-007 (REQ-022/023): - daemon deactivate 시 바인딩 service token 자동 revoke (CLI --force 옵션 + revoke_tokens_by_daemon_id) - NULL daemon_id legacy token 진단 CLI (migrate-null-daemon --dry-run) 거버넌스 문서: dcy-003/004 Discovery, REQ-016~023/025~032 신규, BAT-006/007 전체 산출물 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
4.4 KiB
4.4 KiB
BAT-006 Design
- Status: confirmed
- Batch: BAT-006
Architecture Summary
- 세 가지 변경 모두
app/api/auth_routes.py·app/services/auth_service.py·app/repositories/postgres.pyauth 계층에 집중된다. - REQ-017: DB index 보강 (Alembic migration + ensure_schema 동기화). 애플리케이션 로직 변경 없음. rotate 코드(
auth_service.py:rotate_service_token,postgres.py:1502-1549) 그대로 유지. - REQ-018: HTTP route handler 1-line 추가. service 계층·도메인 모델 변경 없음.
- REQ-016: HTTP 라우트, service 메서드, 스키마 3-layer 제거. 의존 테스트 동시 정리.
Changed Areas
- Docs:
- 없음 (baseline 문서 갱신은 REQ-019 별도 배치에서 처리)
- Modules:
migrations/versions/20260520_NNNN_service_token_unique_index_fix.py— 신규 Alembic revision (REQ-017)app/repositories/postgres.py:161-167—ensure_schema()index 정의 조건 갱신 (REQ-017)app/api/auth_routes.py— L131-137daemon_id=payload.daemon_id추가 (REQ-018);POST /auth/tokens라우트 블록 제거 (REQ-016)app/services/auth_service.py—issue_client_token, 관련 데이터 클래스 제거 (REQ-016)app/schemas/auth.py—CreateClientTokenRequest,IssuedClientTokenResponse제거 (REQ-016)
- Tests:
tests/test_service_token_rotate_integration.py(신규, 실 DB 의존 마킹 —@pytest.mark.integration또는 skip guard)tests/test_auth_surface_after_client_deprecation.py(신규)tests/test_auth.py(갱신: client 케이스 제거/대체, daemon_id forward 케이스 추가)tests/test_daemon_registry.py(갱신: rotate 신규 index 조건 회귀)
- Interfaces:
POST /auth/tokens제거 (→ FastAPI 기본 404)POST /auth/service-tokens— bodydaemon_idforward 동작 추가
Key Decisions
- CONCURRENTLY migration 실행 방식:
op.execute()직접 SQL +connection.execution_options(isolation_level="AUTOCOMMIT")래핑. 기존 migration 패턴(20260423_0013)에서 사용한op.execute()직접 SQL 패턴을 그대로 사용하되 CONCURRENTLY는 autocommit 필요. downgrade에서는DROP INDEX IF EXISTS(non-CONCURRENTLY). - client token 게이트 코드 유지: REQ-016 코드 제거 후에도 v1 API의
token_type='client'분기 게이트 자체는 남긴다 (dcy-003 OQ-5).test_portfolio_ownership.py의token_type="client"TokenPrincipal 픽스처는 게이트 동작 검증이므로 그대로 유지. - REQ-016 제거 대상 정확 범위:
auth_routes.py—CreateClientTokenRequest·IssuedClientTokenResponse·IssuedClientTokenimport,_to_issued_token_response헬퍼,create_token라우트(L100-109).auth_service.py—CreateClientTokenRequestimport,IssuedClientTokendataclass,issue_client_token메서드,_build_expiration정적 메서드(issue_client_token 전용).schemas/auth.py—CreateClientTokenRequest,IssuedClientTokenResponse클래스.tests/test_users.py—test_login_and_issue_client_token_flow제거. - REQ-017 데이터 변경 없음: 기존 active/revoked service token 행은 변경 없음. 신규 partial index가 기존 데이터에 자동 적용되므로 backfill 불요.
- REQ-018 1-line 위치 확정:
auth_routes.py:131-137issue_service_token()호출에daemon_id=payload.daemon_id추가.IssueServiceTokenRequest.daemon_id(스키마 L80) 및AuthService.issue_service_token(daemon_id=)(서비스 L120) 모두 이미 존재 — 라우트 전달 누락만 보정.
Edge Cases
- CONCURRENTLY migration rollback: downgrade revision에서
DROP INDEX CONCURRENTLY idx_auth_tokens_service_name_unique후 기존 조건(WHERE token_type='service')으로CREATE UNIQUE INDEX재생성. - REQ-016 잔여 참조:
grep -rn "issue_client_token\|CreateClientTokenRequest\|IssuedClientTokenResponse"결과 0건이 AC-1 기준. 주석, import, 테스트 픽스처 모두 포함해서 제거. - REQ-018 비존재 daemon_id:
AuthService.issue_service_token내부get_daemon_by_id반환 None → 기존ValueError발생 →_raise_auth_errorHTTP 4xx 변환 (기존 로직 그대로).
Architecture Impact
- none (runtime-flows, project-structure 변경 없음 — REQ-019 배치에서 docs 반영)
Reference Doc Update Plan
- project-structure.md: none (이 배치에서 변경 없음)
- runtime-flows.md: none (이 배치에서 변경 없음)