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>
48 lines
4.4 KiB
Markdown
48 lines
4.4 KiB
Markdown
# 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 (이 배치에서 변경 없음)
|