Files
portfolio-hub/docs/srs/Interface/req-045_user-daemon-list-endpoint.md
T
genichinandClaude Opus 4.8 853a9bdab8 docs(dcy-009): confirm-req-implemented — REQ-044/045 Implemented, bat-019 confirmed
머지 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
2026-06-27 10:46:35 +09:00

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

  1. Given read 권한 토큰을 소지한 사용자 A(데몬 2개 소유), When 데몬 목록 엔드포인트를 호출, Then HTTP 200 + 사용자 A의 데몬 2개만 포함된 목록 반환.
  2. Given read 권한 토큰을 소지한 사용자 A, When 데몬 목록 엔드포인트를 호출, Then 응답 항목이 id, daemon_slug, display_name, is_active 필드를 모두 포함.
  3. Given read 권한 토큰을 소지한 사용자 A, When 데몬 목록 엔드포인트를 호출, Then 사용자 B의 데몬이 응답에 포함되지 않음(타 사용자 비노출).
  4. Given read 권한 사용자이고 자신에게 데몬이 없을 때, When 데몬 목록 엔드포인트를 호출, Then HTTP 200 + 빈 목록(items: []).
  5. Given 인증 토큰 없는 요청, When 데몬 목록 엔드포인트를 호출, Then HTTP 401.
  6. Given admin 토큰을 소지한 사용자, When 데몬 목록 엔드포인트를 호출, Then HTTP 200 + 해당 admin 사용자 소유 데몬만 반환(admin 권한이어도 caller 스코프 적용).
  7. 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 또는 별도 스키마 파일: DaemonResponse Pydantic 모델 신규 정의.
    • 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/daemons vs /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 evidence test_daemons_admin_token_with_user_id_none_returns_empty PASSED.
  • 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_empty PASSED — 이미 커버).

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_empty PASSED.

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 라우터 등록
  • 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 사용해 타 사용자 데몬 비노출) 강제 검증.