머지 PR #16(7f15c6b) 반영. 사용자 read 엔드포인트 delivery 완료. REQ-045 env토큰 처리 200+empty로 문서 동기화(change-req).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
7.8 KiB
7.8 KiB
REQ-045: 사용자 가용 데몬 목록 read 엔드포인트 신설
- Status: Implemented
- Approved By: 팀장 (Claude), 2026-06-27 (confirm-req)
- Type: Interface
- Priority: High
- Owner: Justin Ko
Intent
- caller(인증 사용자)가 자신이 소유한 데몬 목록을 조회할 수 있는 HTTP 엔드포인트를 신설한다.
- trex-web 포트폴리오 관리 UI(dcy-007)에서 포트폴리오를 생성하거나 관리 데몬(
managed_by_daemon_id)을 지정할 때, 사용자가 선택 가능한 데몬 후보를 이 엔드포인트로 불러온다. - 현재 도메인
Daemon모델과list_daemons_for_user(user_id)서비스/리포지토리가 존재하나 HTTP 라우트로 노출되지 않는 상태다. 이 REQ는 그 노출 경로를 추가한다.
Requirement
- 시스템은 caller(인증 사용자) 소유 데몬 목록을 반환하는 GET 엔드포인트를
require_read권한으로 제공해야 한다. - 응답은 caller(
auth.user_id) 소유 데몬만 포함해야 한다 — 타 사용자 데몬은 절대 반환하지 않는다. - 각 응답 항목은 다음 필드를 포함해야 한다:
id(str),daemon_slug(str),display_name(str | None),is_active(bool). - 엔드포인트 경로와 응답 스키마(
DaemonResponse) 구체 형태는 draft-batch-design에서 기존 라우팅 컨벤션에 맞춰 확정한다(OQ-2 Deferred). - 인증 토큰 없는 요청은 HTTP 401을 반환해야 한다.
- 해당 사용자에게 데몬이 없는 경우 빈 목록(
[])으로 HTTP 200을 반환해야 한다(404 아님). - 기존 서비스 메서드
find_candidate_daemons_for_user(user_id)(AuthService)를 활용한다. 이 메서드는 내부적으로repository.list_daemons_for_user(user_id)를 호출한다.
Acceptance Criteria
- Given read 권한 토큰을 소지한 사용자 A(데몬 2개 소유), When 데몬 목록 엔드포인트를 호출, Then HTTP 200 + 사용자 A의 데몬 2개만 포함된 목록 반환.
- Given read 권한 토큰을 소지한 사용자 A, When 데몬 목록 엔드포인트를 호출, Then 응답 항목이
id,daemon_slug,display_name,is_active필드를 모두 포함. - Given read 권한 토큰을 소지한 사용자 A, When 데몬 목록 엔드포인트를 호출, Then 사용자 B의 데몬이 응답에 포함되지 않음(타 사용자 비노출).
- Given read 권한 사용자이고 자신에게 데몬이 없을 때, When 데몬 목록 엔드포인트를 호출, Then HTTP 200 + 빈 목록(
items: []). - Given 인증 토큰 없는 요청, When 데몬 목록 엔드포인트를 호출, Then HTTP 401.
- Given admin 토큰을 소지한 사용자, When 데몬 목록 엔드포인트를 호출, Then HTTP 200 + 해당 admin 사용자 소유 데몬만 반환(admin 권한이어도 caller 스코프 적용).
- Given read 권한 토큰으로 기존
GET /v1/assets(REQ-044)를 호출, Then 회귀 없음(데몬 라우터 추가가 기존 assets 라우터에 영향 없음).
Impacted Area
- Docs:
docs/srs/Interface/req-045_user-daemon-list-endpoint.md(신규) - Modules:
- 신규 라우터 파일 또는 기존 라우터에 엔드포인트 추가(경로·파일 위치는 design 확정 — OQ-2).
app/schemas/v1.py또는 별도 스키마 파일:DaemonResponsePydantic 모델 신규 정의.app/services/auth_service.py:find_candidate_daemons_for_user기존 활용(변경 없거나 최소).app/main.py또는 라우터 등록: 신규 라우터 include.
- Tests: 2사용자 fixture로 caller 스코프 격리 테스트(AC-3). 빈 목록·401 케이스. 기존 assets/auth 회귀.
Notes
- OQ-2(엔드포인트 경로·응답 스키마 형태): design 단계에서 기존 라우팅 컨벤션(
/v1/daemonsvs/v1/users/me/daemons등)을 분석해 확정. 이 REQ에서는 경로를 확정하지 않으며 design Deferred. confirm-req 시 blocker 아님 — design 단계 위임 가능. - OQ-3("가용 데몬" 의미): 현재 기본안은 사용자 소유 데몬 전체(
find_candidate_daemons_for_user). active 여부 필터링이 필요한지(소유 active 전체 vs 미바인딩 후보) design에서 확정. 이 REQ에서는 "caller 소유 데몬"으로만 명시하며 active 필터는 design 위임. - env 기반 token(
token_source="env")은user_id가 None이다. 이 경우auth.user_id가 없어 caller 스코프 적용이 불가. 구현 확정(BAT-019 design/CHG-20260627-02): user_id=None이면 빈 목록[]HTTP 200 반환. 403 거부 대신 빈 목록으로 안전하게 처리하며, env토큰 호출자는 소유 데몬이 없는 것으로 간주한다. 초안의 "기본안: DB 토큰만 허용(user_id 없으면 HTTP 403)"은 폐기한다. 근거: BAT-019 design.md OQ-2 결정 + AC-4/verification evidencetest_daemons_admin_token_with_user_id_none_returns_emptyPASSED. - NFR-1(기존 admin asset 관리·토큰 daemon 바인딩 회귀 0)은 AC-7 회귀 확인으로 흡수한다.
- NFR-2(caller 스코프 정확)는 AC-1/3/6으로 흡수한다.
Change Log
CHG-20260627-02
- Date: 2026-06-27
- Author: 팀장 (Claude)
Change Summary
- 상태
Approved→Implemented(confirm-req-implemented) + Notes env토큰 처리 정정(change-req: "403 거부" → "빈 목록 200").
Intent
- BAT-019 PR #16이 main(
7f15c6b)으로 머지 완료됨에 따라 구현·검증 완료를 공식화한다. - QC가 지적한 문서(Notes: "user_id 없으면 HTTP 403")-구현(빈 목록 200) 불일치를 해소한다.
Acceptance Criteria Delta
- Added: 없음
- Updated: AC-4(데몬 없으면 빈 목록 200)는 env토큰(user_id=None) 케이스에도 적용됨을 명확히 함. AC 본문 변경 없음(이미 "해당 사용자에게 데몬이 없는 경우 빈 목록"으로 커버). Notes의 env토큰 처리 방침 기술 정정.
- Removed: Notes의 "기본안: DB 토큰만 허용(user_id 없으면 HTTP 403)" 폐기.
Impacted Area Delta
- Docs: REQ-045 Notes 내 env토큰 처리 기술 정정.
- Modules: 변경 없음 (구현은 이미 빈 목록 200으로 배포됨).
- Tests: 변경 없음 (
test_daemons_admin_token_with_user_id_none_returns_emptyPASSED — 이미 커버).
Delivery Trace Delta
- Batches: BAT-019
- PR: #16 (main 머지, HEAD
7f15c6b) - QC: PASS (독립 qc-reviewer, env토큰 문서-구현 불일치 지적 → 이번 change-req로 해소)
- Releases: 미정
Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no (구현은 이미 빈 목록 200, 문서만 맞춤)
- Status Recommendation: Implemented
- Follow-up Action: 없음
Validation Plan
- BAT-019 verification.md Evidence — 472 passed, 0 failed (2026-06-27). AC-1~7 전부 PASS.
- env토큰 케이스:
test_daemons_admin_token_with_user_id_none_returns_emptyPASSED.
CHG-20260627-01
- Date: 2026-06-27
- Author: Justin Ko
Change Summary
- 신규 생성 (Proposed) — dcy-009 FR-2 구현을 위한 REQ 초안.
Intent
- dcy-009 confirmed Discovery의 FR-2를 REQ로 정규화한다. 코드·테스트 구현의 기준 문서로 사용.
Acceptance Criteria Delta
- Added:
- AC-1 ~ AC-7 전체 (신규 초안)
- Updated: 없음
- Removed: 없음
Impacted Area Delta
- Docs:
docs/srs/Interface/req-045_user-daemon-list-endpoint.md신규 생성
- Modules:
- 신규 라우터 파일(경로 design 확정 후),
DaemonResponse스키마 신규,app/main.py라우터 등록
- 신규 라우터 파일(경로 design 확정 후),
- Tests:
- 2사용자 스코프 격리 테스트, 빈 목록·401 케이스 신규
Delivery Trace Delta
- Batches: 미정 (suggest-batch-reqs 대기)
- Releases: 미정
Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: confirm-req 후 batch 배정. OQ-2/OQ-3는 design 단계에서 해소.
Validation Plan
- pytest로 AC-1~7 각 케이스 확인. 특히 AC-3(2사용자 fixture 사용해 타 사용자 데몬 비노출) 강제 검증.