From f3c870553d8606360c02a8a0609263421689b851 Mon Sep 17 00:00:00 2001 From: Jinhwan Ko Date: Mon, 13 Apr 2026 23:02:24 +0900 Subject: [PATCH] docs: update SRS tagging requirements --- .../Data/REQ-003_portfolio-required-fields.md | 167 ++++++++++++++++++ .../REQ-002_portfolio-tagging-and-search.md | 65 +++++++ docs/SRS/index.md | 10 +- 3 files changed, 237 insertions(+), 5 deletions(-) diff --git a/docs/SRS/Data/REQ-003_portfolio-required-fields.md b/docs/SRS/Data/REQ-003_portfolio-required-fields.md index b67e658..0e52f2f 100644 --- a/docs/SRS/Data/REQ-003_portfolio-required-fields.md +++ b/docs/SRS/Data/REQ-003_portfolio-required-fields.md @@ -8,6 +8,7 @@ ## Intent - `portfolio` 데이터가 운용 및 검색 맥락에서 일관되게 해석될 수 있도록 필수 필드와 저장 규칙을 명확히 정의한다. - 종목 이름, 심볼, 거래소, 시장 정보를 표준화된 스키마로 관리하여 API, CLI, DB 간 데이터 계약 불일치를 줄인다. +- 태그 기반으로 포트폴리오 목록을 소비하는 외부 서비스가 필요로 하는 원천 데이터 필드 계약을 정확히 정의한다. ## Requirement - 시스템은 신규로 생성되거나 수정되는 각 `portfolio` 레코드에 대해 `name`, `symbol`, `exchange`, `market` 필드를 데이터 계약상 포함해야 한다. @@ -18,6 +19,8 @@ - 시스템은 복수 거래소 지원을 위해 `exchange`를 복수 문자열을 표현할 수 있는 데이터 구조로 저장해야 한다. - 시스템은 기존 `portfolio` 레코드에 `exchange` 또는 `market` 값이 누락되어 있더라도 마이그레이션 과정에서 `NULL` 또는 빈 문자열(`""`)로 보정할 수 있어야 한다. - 시스템은 필수 필드 계약이 추가된 이후에도 기존 레코드 조회가 실패하지 않도록 하위 호환성을 유지해야 한다. +- 시스템은 태그 기반 포트폴리오 목록 조회 응답에서 각 항목의 최소 필드(`symbol`, `name`, `exchange`, `market`, `updated_at`)를 제공해야 한다. +- 시스템은 태그 필터 파라미터를 사용한 목록 조회에서 태그 등록/검색 규칙을 REQ-002 계약에 따라 처리해야 한다. ## Acceptance Criteria 1. Given 새 포트폴리오 레코드가 생성되거나 기존 포트폴리오가 수정될 때, When 시스템이 데이터를 저장하면, Then 해당 레코드는 `name`, `symbol`, `exchange`, `market` 필드를 포함하는 구조로 저장되거나 반환되어야 한다. @@ -25,6 +28,8 @@ 3. Given 사용자가 enum에 없는 새로운 거래소 문자열 또는 시장 문자열을 제공할 때, When 시스템이 이를 저장하면, Then 시스템은 값 목록 제한만을 이유로 해당 값을 거부하지 않아야 한다. 4. Given 기존 포트폴리오 레코드에 `exchange` 또는 `market` 값이 없는 상태에서 스키마가 적용될 때, When 마이그레이션 또는 후속 조회가 수행되면, Then 시스템은 누락 값을 `NULL` 또는 빈 문자열(`""`)로 처리하고 레코드 조회를 실패시키지 않아야 한다. 5. Given 기존 포트폴리오 레코드가 이미 `name`과 `symbol`을 포함하고 있을 때, When 새 필드 계약이 적용된 후 데이터를 조회하면, Then 기존 `name`과 `symbol` 값은 변경되지 않고 그대로 반환되어야 한다. +6. Given 소비 서비스가 태그 기반 목록 조회를 수행하는 상태, When 응답 항목을 확인하면, Then 각 항목에는 최소 `symbol`, `name`, `exchange`, `market`, `updated_at` 필드가 포함되어야 한다. +7. Given 소비 서비스가 태그 필터를 포함해 목록 조회를 요청한 상태, When 조회를 수행하면, Then 태그 필터 적용 규칙은 REQ-002에서 정의한 include/exclude 및 매칭 규칙을 따라야 한다. ## Impacted Area - Docs: `docs/db-schema-spec.md`, `docs/portfoliohub-spec.md`, `docs/api-examples.md`, `docs/SRS/index.md`, `docs/SRS/traceability-matrix.md` @@ -35,9 +40,171 @@ - Assumption: 복수 거래소 지원은 별도 정규화 테이블보다 `exchange` 배열 컬럼이 현재 범위에 더 단순하고 적합한 권장 방식이다. - 신규 생성/수정 계약에서는 `name`, `symbol`, `exchange`, `market` 필드를 모두 포함하되, 기존 데이터 호환성을 위해 레거시 레코드의 누락 신규 필드는 `NULL` 또는 `""`로 허용한다. - `exchange`와 `market`은 허용값 enum을 두지 않고 자유 문자열로 저장한다. +- Note: 본 requirement는 portfolio-hub의 원천 데이터 제공 계약만 다루며, 조회 결과를 스냅샷화하거나 캐시/복구하는 책임은 소비 서비스에 있다. +- Note: 조회 결과의 결정성(동일 tag 필터 입력에 대한 동일 응답 항목 집합 및 정렬 순서) 유지는 소비 서비스(예: stock-picker)의 책임이다. portfolio-hub는 tag 필터를 적용하여 목록을 반환하기만 한다. +- Note: 태그 등록과 태그 필터 세부 규칙은 REQ-002를 단일 source of truth로 사용한다. ## Change Log +### CHG-20260413-07 +- Date: 2026-04-13 +- Author: GitHub Copilot + +#### Change Summary +- REQ-003에서 tag 필터 기반 조회의 결정성(동일 항목 집합/정렬) 유지 책임을 portfolio-hub에서 제거하고 stock-picker(소비 서비스)로 이관했다. + +#### Intent +- portfolio-hub의 책임을 "tag 필터 적용 후 목록 반환"으로 최소화하고, 조회 결과의 캐시/복구/결정성 추적은 소비 서비스가 담당하도록 명확히 하기 위함이다. + +#### Acceptance Criteria Delta +- Added: + - 없음 +- Updated: + - Requirement에서 "동일 tag 필터 조건에서 항목 집합과 정렬 기준을 결정적으로 유지" 요구사항 제거 + - Notes에 결정성 책임이 소비 서비스에 있음을 명시 +- Removed: + - Acceptance Criteria #7 (결정성 검증 기준) + - Requirement의 결정성 유지 조항 + +#### Impacted Area Delta +- Docs: + - `docs/SRS/Data/REQ-003_portfolio-required-fields.md` + - `docs/SRS/index.md` +- Modules: + - 없음 +- Tests: + - 없음 + +#### Validation Plan +- REQ-003의 tag 필터 기반 목록 조회 응답이 필수 필드와 REQ-002 필터 규칙을 만족하는지로 검증한다. +- 결정성 검증(동일 tag 필터 입력에 대한 동일 응답)은 stock-picker 테스트에서 담당한다. + +### CHG-20260413-06 +- Date: 2026-04-13 +- Author: GitHub Copilot + +#### Change Summary +- REQ-003에서 `sourceVersion`/`sourceTimestamp` 메타데이터 요구를 제거하고 태그 필터 기반 조회 결정성 계약만 유지했다. + +#### Intent +- portfolio-hub가 특정 소비자 전용 메타데이터를 제공하지 않고도 공용 태그 기반 목록 조회 계약을 만족하도록 경계를 명확히 하기 위함이다. + +#### Acceptance Criteria Delta +- Added: + - 없음 +- Updated: + - Requirement의 조회 결정성 기준을 태그 필터 조건 기준으로 정리 + - Acceptance Criteria에서 source metadata 검증 항목 제거 및 결정성 검증 항목 재정의 +- Removed: + - `sourceVersion`/`sourceTimestamp` 제공 검증 기준 + +#### Impacted Area Delta +- Docs: + - `docs/SRS/Data/REQ-003_portfolio-required-fields.md` + - `docs/SRS/index.md` +- Modules: + - 없음 +- Tests: + - 없음 + +#### Validation Plan +- 동일 태그 필터 조건으로 반복 조회 시 항목 집합/정렬이 동일한지로 계약 충족 여부를 검증한다. + +### CHG-20260413-05 +- Date: 2026-04-13 +- Author: GitHub Copilot + +#### Change Summary +- REQ-003의 stock-picker 전용 표현을 소비 서비스 중립 표현으로 정리했다. + +#### Intent +- portfolio-hub가 특정 소비자 구현을 인지하지 않아도 되는 일반 태그 기반 목록 조회 계약으로 요구사항 경계를 명확히 하기 위함이다. + +#### Acceptance Criteria Delta +- Added: + - 없음 +- Updated: + - Intent/Requirement/Acceptance Criteria의 소비자 표현을 일반화 + - Notes의 책임 주체를 특정 서비스명 대신 소비 서비스로 일반화 +- Removed: + - 없음 + +#### Impacted Area Delta +- Docs: + - `docs/SRS/Data/REQ-003_portfolio-required-fields.md` + - `docs/SRS/index.md` +- Modules: + - 없음 +- Tests: + - 없음 + +#### Validation Plan +- REQ-003 본문에서 특정 소비자 고정 표현 없이 태그 기반 조회 계약이 동일하게 해석되는지 문서 리뷰로 확인한다. + +### CHG-20260413-04 +- Date: 2026-04-13 +- Author: GitHub Copilot + +#### Change Summary +- REQ-003에 stock-picker 태그 필터 조회 시 REQ-002 계약을 따른다는 교차 참조를 추가했다. + +#### Intent +- 원천 데이터 필드 계약과 태그 필터 계약의 문서 경계를 명확히 분리하고 추적성을 강화하기 위함이다. + +#### Acceptance Criteria Delta +- Added: + - 태그 필터 조회가 REQ-002 규칙을 따르는지 검증하는 기준 +- Updated: + - Requirement에 REQ-002 교차 참조 조항 추가 + - Notes에 태그 계약 source of truth 명시 +- Removed: + - 없음 + +#### Impacted Area Delta +- Docs: + - `docs/SRS/Data/REQ-003_portfolio-required-fields.md` + - `docs/SRS/index.md` +- Modules: + - 없음 +- Tests: + - 태그 필터 조회 계약 연계 테스트 항목 추가 + +#### Validation Plan +- REQ-003과 REQ-002 간 참조가 충돌 없이 추적 가능한지 문서 리뷰로 확인한다. + +### CHG-20260413-03 +- Date: 2026-04-13 +- Author: GitHub Copilot + +#### Change Summary +- stock-picker 기본 유니버스 소비를 위한 원천 데이터 필드/버전 메타데이터/조회 정합성 최소 계약을 REQ-003에 추가했다. + +#### Intent +- portfolio-hub 책임을 원천 데이터 계약으로 한정하면서 소비자(stock-picker)의 입력 고정 요구를 지원한다. + +#### Acceptance Criteria Delta +- Added: + - 원천 데이터 조회 필수 필드 검증 기준 + - sourceVersion/sourceTimestamp 메타데이터 검증 기준 + - 동일 sourceVersion 조회 정합성 검증 기준 +- Updated: + - Requirement에 stock-picker 원천 데이터 제공 계약 조항 추가 + - Notes에 책임 분리 문구 추가 +- Removed: + - 없음 + +#### Impacted Area Delta +- Docs: + - REQ-003 원천 데이터 계약 보강 +- Modules: + - portfolio list response serializer 및 metadata 노출 경로 영향 식별 +- Tests: + - source metadata 및 deterministic ordering 검증 테스트 항목 추가 + +#### Validation Plan +- 동일 sourceVersion 기준 조회 2회 결과의 항목 집합/정렬 일치 여부를 검증한다. +- 원천 데이터 조회 응답에 필수 필드와 source metadata가 존재하는지 확인한다. + ### CHG-20260410-02 - Date: 2026-04-10 - Author: GitHub Copilot diff --git a/docs/SRS/Interface/REQ-002_portfolio-tagging-and-search.md b/docs/SRS/Interface/REQ-002_portfolio-tagging-and-search.md index 2607df1..6d175a7 100644 --- a/docs/SRS/Interface/REQ-002_portfolio-tagging-and-search.md +++ b/docs/SRS/Interface/REQ-002_portfolio-tagging-and-search.md @@ -13,6 +13,8 @@ - 시스템은 각 포트폴리오에 대해 하나 이상의 태그를 추가하고 제거할 수 있어야 한다. - 시스템은 HTTP API와 CLI를 통해 동일한 포트폴리오 태깅 기능을 제공해야 한다. - 시스템은 둘 이상의 태그를 조건으로 포트폴리오를 검색할 수 있어야 하며, 검색 요청에서 `AND` 또는 `OR` 매칭 방식을 선택할 수 있어야 한다. +- 시스템은 다운스트림 소비자가 태그 기반 목록 조회 시 사용할 수 있도록 포함 태그(`includeTags`)와 제외 태그(`excludeTags`)를 동시에 지원해야 한다. +- 시스템은 태그 기반 조회에서 `grade:*`, `blacklist:*`와 같은 태그 네임스페이스를 그대로 보존하고 필터 조건으로 사용할 수 있어야 한다. - 시스템은 공백만으로 이루어지지 않은 태그 문자열을 추가 대상으로 받아들여야 한다. - 시스템은 동일 포트폴리오에 이미 연결된 동일한 태그 문자열을 다시 추가하려는 요청에 대해 `409 Conflict` 또는 이에 대응하는 CLI 오류를 반환해야 하며, 기존 태그 상태를 변경하지 않아야 한다. - 시스템은 태그 추가·삭제·검색 요청에 대해 기존 포트폴리오 접근 권한 정책을 적용해야 하며, 인증 실패 또는 권한 부족 시 기존 인증 오류 계약에 따라 요청을 거부해야 한다. @@ -30,6 +32,7 @@ 7. Given 존재하지 않는 `portfolio_id`가 요청에 포함될 때, When 사용자가 API 또는 CLI로 태그 추가 또는 삭제를 시도하면, Then 시스템은 `404` 응답 또는 이에 대응하는 CLI 오류를 반환하고 어떤 태그 연결도 생성·변경하지 않아야 한다. 8. Given 포트폴리오에 이미 여러 태그가 연결되어 있고 사용자가 긴 태그 문자열을 추가할 때, When API 또는 CLI로 태그 추가를 요청하면, Then 시스템은 애플리케이션 정의 최대 길이 제한 또는 최대 개수 제한만을 이유로 요청을 거부하지 않아야 한다. 9. Given `OR` 모드의 다중 태그 검색에서 하나의 포트폴리오가 두 개 이상의 요청 태그와 동시에 일치할 때, When 사용자가 검색을 수행하면, Then 시스템은 해당 포트폴리오를 결과에 한 번만 반환해야 한다. +10. Given 소비 서비스가 `includeTags=["grade:A", "grade:B"]`, `excludeTags=["blacklist:trade"]` 조건으로 목록 조회를 요청한 상태, When 태그 필터 검색을 수행하면, Then 시스템은 포함 조건을 만족하고 제외 조건을 만족하지 않는 항목만 반환해야 한다. ## Impacted Area - Docs: `docs/portfoliohub-spec.md`, `docs/api-examples.md`, `docs/db-schema-spec.md`, `docs/SRS/index.md`, `docs/SRS/traceability-matrix.md` @@ -40,9 +43,71 @@ - 본 requirement의 검색 범위는 다중 태그 검색을 포함하며, 호출자는 `AND` 또는 `OR` 모드를 선택할 수 있다. - 태그 최대 길이와 포트폴리오당 최대 태그 개수에 대한 애플리케이션 정의 상한은 두지 않는다. - 동일 포트폴리오에 같은 태그 문자열을 다시 추가하는 요청은 `409 Conflict` 또는 이에 대응하는 CLI 오류로 처리한다. +- 특정 소비 서비스의 입력 고정/스냅샷 책임은 소비 서비스 측 requirement에서 관리하며, portfolio-hub는 태그 등록/검색 계약만 제공한다. ## Change Log +### CHG-20260413-04 +- Date: 2026-04-13 +- Author: GitHub Copilot + +#### Change Summary +- REQ-002의 stock-picker 특정 소비자 표현을 다운스트림 소비자 일반 계약으로 정리했다. + +#### Intent +- portfolio-hub 태그 검색 기능을 특정 소비자 전용 기능이 아닌 공용 인터페이스 계약으로 유지하기 위함이다. + +#### Acceptance Criteria Delta +- Added: + - 없음 +- Updated: + - Requirement/Acceptance Criteria/Notes의 소비자 표현 일반화 +- Removed: + - 없음 + +#### Impacted Area Delta +- Docs: + - `docs/SRS/Interface/REQ-002_portfolio-tagging-and-search.md` + - `docs/SRS/index.md` +- Modules: + - 없음 +- Tests: + - 없음 + +#### Validation Plan +- REQ-002 본문이 특정 소비자 구현을 전제하지 않고 include/exclude 태그 검색 계약만 명확히 정의하는지 확인한다. + +### CHG-20260413-03 +- Date: 2026-04-13 +- Author: GitHub Copilot + +#### Change Summary +- REQ-002에 stock-picker 기본 유니버스 소비를 위한 include/exclude 태그 필터 계약을 추가했다. + +#### Intent +- portfolio-hub 태그 등록값(예: grade, blacklist)을 downstream 필터 인자로 직접 활용하는 계약을 명시하기 위함이다. + +#### Acceptance Criteria Delta +- Added: + - includeTags/excludeTags 동시 적용 검증 기준 +- Updated: + - Requirement에 stock-picker 소비자 관점 필터 계약 추가 + - Notes에 stock-picker 연계 경계 문구 추가 +- Removed: + - 없음 + +#### Impacted Area Delta +- Docs: + - `docs/SRS/Interface/REQ-002_portfolio-tagging-and-search.md` + - `docs/SRS/index.md` +- Modules: + - portfolio tag search API/CLI query parser 영향 식별 +- Tests: + - include/exclude 조합 필터링 테스트 항목 추가 + +#### Validation Plan +- includeTags/excludeTags 조합 요청에서 반환 집합이 예상과 일치하는지 API/CLI 테스트로 확인한다. + ### CHG-20260410-02 - Date: 2026-04-10 - Author: GitHub Copilot diff --git a/docs/SRS/index.md b/docs/SRS/index.md index 78f3898..c45327e 100644 --- a/docs/SRS/index.md +++ b/docs/SRS/index.md @@ -26,11 +26,11 @@ | REQ-003 | 포트폴리오 필수 필드 및 거래소/시장 데이터 정의 | Data | Proposed | Medium | Justin | `docs/SRS/Data/REQ-003_portfolio-required-fields.md` | ## Recent Change Log Summary -- 2026-04-10 — `REQ-003`에 신규 입력 계약과 레거시 호환성 규칙을 분리해 반영했다. -- 2026-04-10 — `REQ-003` 초안을 추가해 포트폴리오 필수 필드와 거래소/시장 데이터 계약을 정의했다. -- 2026-04-10 — `REQ-002`에 다중 태그 `AND`/`OR` 검색, 중복 추가 `409 Conflict`, 태그 길이/개수 상한 없음 계약을 반영했다. -- 2026-04-10 — `REQ-002` 초안을 추가해 포트폴리오 태깅과 태그 기반 검색의 API/CLI 계약을 정의했다. -- 2026-04-10 — `REQ-001` 상태를 `Approved`로 전환했다. +- 2026-04-13 — `REQ-003`에서 태그 필터 기반 조회의 결정성 유지 책임을 소비 서비스(stock-picker)로 이관했다. +- 2026-04-13 — `REQ-003`에서 `sourceVersion`/`sourceTimestamp` 요구를 제거하고 태그 필터 기반 조회 결정성 계약으로 정리했다. +- 2026-04-13 — `REQ-003`의 소비자 표현을 특정 서비스 전용에서 태그 기반 조회 소비 서비스 일반 계약으로 정리했다. +- 2026-04-13 — `REQ-002`의 소비자 표현을 특정 서비스 전용에서 다운스트림 소비자 일반 계약으로 정리했다. +- 2026-04-13 — `REQ-002`에 includeTags/excludeTags 태그 필터 계약을 추가했다. ## Status Transition Evidence - `Proposed` → `Approved`: Owner가 지정되고 requirement 문서 리뷰가 완료되며 acceptance criteria가 누락 없이 검토되어야 한다.