Add three approved requirements documents for dcy-011: - REQ-052: User-owned credential management API (Interface) - REQ-053: Admin daemon CRUD API (Interface) - REQ-054: Credential management security with write-only constraint (Non-Functional) Update discovery document to reference generated requirements and update index with new REQ IDs and Change Log. Scope: Self-service credential management + admin daemon CRUD + security-isolated API for portfolio-hub. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
8.3 KiB
8.3 KiB
REQ-053: admin 데몬 CRUD HTTP API
- Status: Approved
- Type: Interface
- Priority: High
- Owner: Justin Ko
Intent
- 현재
Daemon엔티티는GET /v1/daemons(read 전용, REQ-045)만 HTTP로 노출되며, 생성·변경·(비)활성화 HTTP API가 없다. 관리자(admin)가 HTTP API로 데몬을 provisioning하고 owner를 할당·변경·(비)활성화할 수 있어야 한다. - trex-web dcy-009 admin UI가 소비하는 백엔드 경로를 신설한다.
- 데몬은 운영 런타임 식별자(service-token daemon_id 바인딩, KIS 계좌 연결)로 하드 삭제는 제공하지 않으며 비활성화로 대체한다(dcy-011 FR-4 결정). owner 재할당은 허용하되 owner 변경 시 해당 데몬의 기존 인증정보를 자동 무효화한다(이전 owner의 KIS 계좌 이관 금지, dcy-011 OQ-3 결정).
Requirement
- 시스템은 admin role로 인증된 요청자가 데몬을 생성하고
owner_user_id를 할당할 수 있는 POST 엔드포인트를 제공해야 한다.- 입력:
daemon_slug(고유 식별자),display_name(선택),owner_user_id. - 성공 시 생성된 Daemon의
id,daemon_slug,display_name,owner_user_id,is_active반환.
- 입력:
- 시스템은 admin이 기존 데몬의
display_name또는owner_user_id를 변경할 수 있는 PATCH 엔드포인트를 제공해야 한다.- owner 변경 시 해당 데몬의 기존
BrokerCredential전체를 자동 삭제(무효화) 해야 한다 — 이전 owner의 KIS 계좌 정보가 새 owner에게 이관되는 것을 방지한다.
- owner 변경 시 해당 데몬의 기존
- 시스템은 admin이 데몬을 비활성화(
is_active=false) 및 재활성화(is_active=true)할 수 있는 엔드포인트를 제공해야 한다.- 비활성화 시 해당 데몬에 바인딩된 service token을 자동 revoke해야 한다(기존 REQ-022 정책 재사용).
- 하드 삭제(DELETE) 엔드포인트는 제공하지 않는다. 비활성화가 유일한 종료 경로이다.
- admin role이 아닌 요청(user-token, service-token 포함)은 HTTP 403 Forbidden을 반환해야 한다.
- 엔드포인트 경로·HTTP 메서드의 구체 형태는 draft-batch-design에서 v1 admin 컨벤션(dcy-011 OQ-2 Deferred, dcy-006 admin 경로 참고)에 맞춰 확정한다.
Acceptance Criteria
- Given admin 토큰으로 daemon_slug, display_name, owner_user_id를 포함한 생성 요청, When POST 엔드포인트를 호출, Then HTTP 201 + 생성된 Daemon(
id,daemon_slug,display_name,owner_user_id,is_active=true) 반환. - Given admin 토큰으로 중복
daemon_slug로 생성 요청, When POST 엔드포인트를 호출, Then HTTP 409(또는 422) Conflict 반환(중복 슬러그 거부). - Given admin 토큰으로 존재하는 daemon D의
display_name변경 요청(owner 변경 없음), When PATCH 엔드포인트를 호출, Then HTTP 200 + 갱신된 Daemon 반환. 기존 BrokerCredential은 유지된다. - Given admin 토큰으로 daemon D의
owner_user_id를 사용자 B로 재할당 요청(원래 소유자 A), When PATCH 엔드포인트를 호출, Then HTTP 200 + 갱신된 Daemon 반환 + 해당 daemon D의 BrokerCredential이 모두 삭제(무효화)된다. - Given daemon D의 owner가 변경된 직후, When 변경 전 소유자 A의 service-token으로
/v1/user_info를 호출, Thenbroker: null반환(이전 owner 인증정보 이관 차단). - Given admin 토큰으로 활성 daemon D 비활성화 요청, When 비활성화 엔드포인트를 호출, Then HTTP 200 +
is_active: false반환 + daemon D에 바인딩된 service token 자동 revoke(REQ-022 정책). - Given admin 토큰으로 비활성 daemon D 재활성화 요청, When 재활성화 엔드포인트를 호출, Then HTTP 200 +
is_active: true반환. - Given admin 토큰으로 daemon D에 DELETE 요청(하드 삭제), When 호출, Then HTTP 405 Method Not Allowed(또는 404) 반환 — 하드 삭제 엔드포인트 미제공.
- Given user-token(admin role 없음)으로 데몬 생성·변경·비활성화 엔드포인트 호출, When 호출, Then HTTP 403 Forbidden 반환.
- Given service-token으로 데몬 CRUD 엔드포인트 호출, When 호출, Then HTTP 403 Forbidden 반환.
- Given 인증 토큰 없는 요청으로 데몬 CRUD 엔드포인트 호출, When 호출, Then HTTP 401 반환.
- Given admin 토큰으로 존재하지 않는 daemon_id에 PATCH/비활성화 요청, When 호출, Then HTTP 404 반환.
Impacted Area
- Docs:
docs/interface-contract.md— admin 데몬 CRUD 엔드포인트 경로·권한·owner 재할당 시 인증정보 무효화 정책 신규 섹션 추가.
- Modules:
- 신규 또는 확장 admin 데몬 라우터(경로·파일명은 design 확정).
app/schemas/—DaemonCreateRequest,DaemonUpdateRequest,DaemonAdminResponse스키마 신규 정의.app/services/— 데몬 생성·변경·비활성화 서비스 메서드 신규. owner 재할당 시BrokerCredential무효화 로직 포함.app/repositories/—DaemonRepositorycreate/update/deactivate/reactivate 메서드 신규.app/repositories/broker_credential_repository.py— owner 재할당 시 credential 삭제 메서드(신규 또는 확장).- REQ-022(
daemon deactivation service token auto-revoke) 서비스 로직 재사용 — 비활성화 경로에서 호출.
- Tests:
- AC-1~12 커버 pytest 케이스. AC-4/5(owner 재할당 + 인증정보 무효화), AC-8(DELETE 405 음성), AC-9/10/11(권한 음성) 강제 검증.
Notes
- OQ-2(엔드포인트 경로): draft-batch-design 위임(dcy-011 Deferred).
/v1/admin/daemonsvs/v1/daemons(admin 분기) — dcy-006 admin 경로 컨벤션 참고. - owner 재할당 + 인증정보 자동 무효화(AC-4/5): dcy-011 OQ-3 Answered(2026-06-28 결정). 새 owner는 자기 KIS 인증정보를 REQ-052 API로 재등록해야 한다. 이 정책은 이전 owner의 KIS 계좌 정보가 데몬에 잔류하는 보안 위험을 제거한다.
- 하드 삭제 미제공(AC-8): 데몬은 운영 런타임 식별자(service-token daemon_id 바인딩)이므로 참조 무결성 보호를 위해 비활성화가 유일 종료 경로. dcy-011 FR-4 결정.
- 비활성화 → service token revoke(AC-6): 기존 REQ-022 정책(
daemon deactivation auto-revoke)을 이 경로에서도 호출. REQ-022 구현 재사용. - NFR-2(권한 — admin role 강제): AC-9/10/11로 흡수한다.
- daemon_slug 중복 처리(AC-2): HTTP 409 vs 422는 design 단계에서 v1 컨벤션에 맞춰 확정.
- Source: dcy-011 FR-4, NFR-2, OQ-3 Answered.
Change Log
CHG-20260628-01
- Date: 2026-06-28
- Author: Justin Ko
Change Summary
- 신규 생성 (Proposed) — dcy-011 FR-4 산출물.
Intent
- dcy-011 confirmed Discovery의 FR-4(admin 데몬 생성·owner 할당·변경·(비)활성화, 삭제 제외) 및 OQ-3 결정(owner 재할당 허용 + 인증정보 자동 무효화)을 Interface REQ로 정규화한다.
Acceptance Criteria Delta
- Added:
- AC-1 ~ AC-12 전체 (신규 초안)
- Updated: 없음
- Removed: 없음
Impacted Area Delta
- Docs:
docs/srs/Interface/req-053_admin-daemon-crud-api.md신규 생성docs/interface-contract.md갱신 예고
- Modules:
- admin 데몬 라우터(신규), DaemonCreate/UpdateRequest/AdminResponse 스키마(신규), 서비스·repository 신규
- Tests:
- owner 재할당+인증정보 무효화(AC-4/5), DELETE 음성(AC-8), 권한 음성(AC-9~11) 케이스 신규
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 후 suggest-batch-reqs. REQ-052/REQ-054와 동일 batch 묶기 권고. OQ-2(경로)은 design 단계 해소.
Validation Plan
- pytest로 AC-1~12 각 케이스 확인. AC-4/5(owner 재할당 + 인증정보 무효화) 통합 시나리오, AC-8(DELETE 음성), AC-9(admin role 강제 음성) 강제 검증.
CHG-20260628-02
- Date: 2026-06-28
- Author: 팀장(Claude)
- confirm-req:
Proposed→Approved. dcy-011 FR-4/OQ-3 추적. 데몬 생성·할당·(비)활성화, owner 재할당 시 인증정보 자동 무효화(AC-4/5) 보안정합, 하드 삭제 미제공(AC-8)·비활성화→service token revoke(REQ-022 재사용, AC-6)·admin role 강제(AC-9/10/11) 적절. 경로(OQ-2)·409/422·405/404 design 위임. blocker 없음.