Files
portfolio-hub/docs/batches/bat-006_20260520_token-surface-code-fixes/design.md
T
genichinandClaude Sonnet 4.6 c815ce39b6 feat: dcy-003/004 토큰 surface 개편 및 daemon lifecycle 정책 구현 (BAT-006/007)
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>
2026-05-21 01:03:39 +00:00

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.py auth 계층에 집중된다.
  • 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-137 daemon_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 — body daemon_id forward 동작 추가

Key Decisions

  1. 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).
  2. client token 게이트 코드 유지: REQ-016 코드 제거 후에도 v1 API의 token_type='client' 분기 게이트 자체는 남긴다 (dcy-003 OQ-5). test_portfolio_ownership.py의 token_type="client" TokenPrincipal 픽스처는 게이트 동작 검증이므로 그대로 유지.
  3. REQ-016 제거 대상 정확 범위: auth_routes.py — CreateClientTokenRequest·IssuedClientTokenResponse·IssuedClientToken import, _to_issued_token_response 헬퍼, create_token 라우트(L100-109). auth_service.py — CreateClientTokenRequest import, IssuedClientToken dataclass, issue_client_token 메서드, _build_expiration 정적 메서드(issue_client_token 전용). schemas/auth.py — CreateClientTokenRequest, IssuedClientTokenResponse 클래스. tests/test_users.py — test_login_and_issue_client_token_flow 제거.
  4. REQ-017 데이터 변경 없음: 기존 active/revoked service token 행은 변경 없음. 신규 partial index가 기존 데이터에 자동 적용되므로 backfill 불요.
  5. REQ-018 1-line 위치 확정: auth_routes.py:131-137 issue_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_error HTTP 4xx 변환 (기존 로직 그대로).

Architecture Impact

  • none (runtime-flows, project-structure 변경 없음 — REQ-019 배치에서 docs 반영)

Reference Doc Update Plan

  • project-structure.md: none (이 배치에서 변경 없음)
  • runtime-flows.md: none (이 배치에서 변경 없음)