diff --git a/docs/CURRENT/AEG-VS-00-05_JOBRUN_SCHEMA_DECISION.md b/docs/CURRENT/AEG-VS-00-05_JOBRUN_SCHEMA_DECISION.md new file mode 100644 index 00000000..a1079b58 --- /dev/null +++ b/docs/CURRENT/AEG-VS-00-05_JOBRUN_SCHEMA_DECISION.md @@ -0,0 +1,202 @@ +# AEG-VS-00-05: Job Run 스키마 & 운영 정책 승인 요청 + +**WBS Item:** AEG-VS-00-05 +**Status:** ⏳ IN_PROGRESS → DECISION_REQUIRED +**Decision Owner:** SRE/DBA, Architecture +**Blocks:** Event/Job/Inbox 계약 완료, 재처리 정책 확정 +**Impact:** Job 실행 추적 미완료, 재시도 정책 불명확, 감시 불완전 + +--- + +## 현재 상태 + +**구현 완료:** +- ✅ db/migrations/0000_building_blocks.sql (building_blocks.job_run 생성) +- ✅ DapperJobRunRepository.cs (CRUD 구현) +- ✅ OutboxPollerJob (이벤트 폴링) +- ✅ DownstreamConsumerJob (Inbox 처리) +- ✅ Architecture tests 6/6 PASS + +**검증 대기:** +- ⏳ Fresh/upgrade/re-run/failure 리허설 증거 (DB 필요) +- ⏳ 보존 정책 (retention policy) +- ⏳ 인덱싱 전략 +- ⏳ 운영 SLA 계약 + +--- + +## 필요한 4가지 결정 + +### 1️⃣ Job Run 상태 모델 (State Machine Contract) + +**결정:** Job 실행의 허용된 상태 전이 정의 + +``` +Current schema (building_blocks.job_run): +- id: UUID +- job_type: enum (ShadowRun, OutboxPoller, TradeStatusPolling, etc.) +- status: enum (Queued, Running, Completed, Failed, ???) +- created_at: timestamp +- completed_at: timestamp (nullable) +- duration_ms: integer +- error_message: text +- result_summary: JSONB +- retry_count: integer +- idempotency_key: UUID (unique, for replay safety) + +Questions: +✅ 허용 상태: [ ] (Queued → Running → Completed/Failed/BusinessHold?) +✅ 중간 상태 필요: [ ] (Retrying? Paused?) +✅ 상태별 재시도 정책: [ ] (transient/permanent/dq/business-hold 분류?) +✅ 최대 재시도: [ ] (count) + +Linked Items: +- Hangfire job status (how to map?) +- DEBT-024 (retry classification) +- Exponential backoff policy +``` + +### 2️⃣ Job 실행 재처리 정책 (Replay Semantics) + +**결정:** 실패 Job의 재처리 조건과 안전성 + +``` +Idempotency guarantee: +- Current: idempotency_key (UUID unique constraint) +- Goal: Same key → Same result (deterministic) + +Questions: +✅ Determinism 범위: [ ] (모든 Job? 일부만?) +✅ 외부 API 호출: [ ] (재시도 시 replay 가능?) +✅ 부분 실패: [ ] (일부 성공 + 일부 실패 → 어떻게?) +✅ 재처리 기한: [ ] (24h? 7일? 무제한?) + +Linked Items: +- OutboxPollerJob (exactly-once semantics) +- DapperInboxStore (deduplication) +- Distributed transaction boundaries +``` + +### 3️⃣ 보존 정책 & 정리 (Retention & Archival) + +**결정:** Job 실행 기록을 얼마나 오래 보관할 것인가 + +``` +Current state: +- No archival or cleanup defined +- Table growth: unbounded (2-3 jobs/second × 365 days = ~60M rows/year) + +Questions: +✅ 보존 기간: [ ] (30일? 90일? 1년? 영구?) +✅ 정리 정책: [ ] (DELETE? Archive to S3? Summarize?) +✅ 감사 대상: [ ] (특정 job_type만? 모두?) +✅ GDPR 대응: [ ] (actor/IP/data redaction?) + +Linked Items: +- GDPR retention (docs/CURRENT/AEG-X-007_*) +- Compliance retention periods +- Database archival strategy +- Grafana metric retention +``` + +### 4️⃣ 운영 모니터링 & SLA (Operational Contract) + +**결정:** Job 성능과 SLA 목표 + +``` +Metrics needed: +- P95/P99 job duration (by job_type) +- Failure rate (% per hour) +- Retry rate (successful retries vs give-up) +- Queue depth (pending jobs) + +Questions: +✅ SLA 목표: [ ] (e.g., P95 < 5s, failure rate < 0.1%) +✅ Alert 임계값: [ ] (error rate > 5%? retry rate > 10%?) +✅ 주간 보고: [ ] (job success rate, avg duration, anomalies) +✅ 에스컬레이션: [ ] (SRE pager? on-call runbook?) + +Linked Items: +- Serilog structured logging (job_run_id in logs) +- OpenTelemetry spans (job execution tracing) +- Grafana dashboards (job health) +- Runbook (failure scenarios & recovery) +``` + +--- + +## 제출 형식 + +**승인자는 다음 정보 제공:** + +### 1. Job Run State Machine +``` +Allowed States: + [x] Queued → Running → Completed + [ ] Queued → Running → Retrying → Running → Completed + [ ] Queued → Running → Failed → [terminal] + +Max Retries: [ ] (count) + +Retry Classification: + - Transient: [ ] (e.g., timeout, 503) + - Permanent: [ ] (e.g., 400, bad input) + - DQ (Data Quality): [ ] (e.g., missing field) + - BusinessHold: [ ] (e.g., awaiting approval) +``` + +### 2. Replay Semantics +``` +Idempotency Guarantee: + Applies to all jobs: [ ] (Yes/No) + +External API retry policy: + Retry on 5xx: [ ] (Yes/No) + Retry on timeout: [ ] (Yes/No) + +Partial failure handling: + Strategy: [ ] (all-or-nothing / partial-OK) + +Replay deadline: [ ] (hours) +``` + +### 3. Retention Policy +``` +Retention Period: + All jobs: [ ] (days) + Failed/Retry jobs: [ ] (days, if different) + Archived jobs: [ ] (S3 path or delete) + +GDPR Compliance: + Redact actor/IP: [ ] (Yes/No) + Retention audit: [ ] (Yes/No) +``` + +### 4. Operational SLA +``` +Performance Target: + P95 duration: [ ] (ms) + P99 duration: [ ] (ms) + +Availability: + Target failure rate: [ ] (%) + Alert threshold: [ ] (%) + +Monitoring: + Dashboard link: [ ] (Grafana path) + Runbook: [ ] (ops/runbook link) +``` + +--- + +## 의존성 + +- **Blocks:** Event/Job/Inbox 완전 구현, VS-26/28/29 프로덕션 등록 +- **Related:** Hangfire 스케줄링, Outbox/Inbox 패턴, 감시 +- **Prerequisite:** SRE/DBA/Architecture 팀 협력 + +--- + +**제출 기한:** 2026-08-21 (1주) +**승인자:** SRE Lead, DBA Lead, Architecture +**Escalation:** CTO (정책 논쟁 시) diff --git a/docs/CURRENT/AEG-VS-06-01_COSTTAXFX_SCHEDULE_DECISION.md b/docs/CURRENT/AEG-VS-06-01_COSTTAXFX_SCHEDULE_DECISION.md new file mode 100644 index 00000000..f509e2fb --- /dev/null +++ b/docs/CURRENT/AEG-VS-06-01_COSTTAXFX_SCHEDULE_DECISION.md @@ -0,0 +1,255 @@ +# AEG-VS-06-01: 비용/세금/환율 일정 계약 승인 요청 + +**WBS Item:** AEG-VS-06-01 +**Status:** ⏳ BLOCKED → DECISION_REQUIRED +**Decision Owner:** PM, Architecture, Compliance/Owner +**Blocks:** MaintainFeeTaxFxSchedule Slice (VS-06-01), Cost Basis 계산, 포트폴리오 재조정 +**Impact:** 금융 기능 미구현, 비용 정산 불가능, 규정 준수 불명확 + +--- + +## 근본 원인 + +**WBS vs 기존 문서 충돌:** + +| 항목 | WBS 정의 | 기존 문서 (VS-06) | 충돌 | +|------|---------|-----------------|------| +| **Slice 목표** | MaintainFeeTaxFxSchedule | Stress Testing | ⚠️ 직교 | +| **요구사항** | REQ-COST-001 | 없음 | ❌ 미정 | +| **마이그레이션** | MIG-COST-001/002 | 0035 (unrelated) | ❌ 불일치 | +| **Job** | J04C (비용 유지) | 없음 | ❌ 미정 | +| **API** | T-COST-001, UI-COST-01 | 없음 | ❌ 미정 | + +**의사결정 필요:** +- VS-06은 진짜 뭐야? (Stress Testing vs MaintainFeeTaxFxSchedule) +- WBS 순서 변경해야 함? (VS-06/07/... 재번호) +- Cost 기능은 새 VS 번호 할당? (VS-30/31?) + +--- + +## 필요한 5가지 결정 + +### 1️⃣ Slice 정의 명확화 (Scope Clarification) + +**결정:** WBS "MaintainFeeTaxFxSchedule"의 공식 정의 + +``` +Option A: 기존 VS-06 유지 (Stress Testing) +- 현재 기존 문서 유지 +- MaintainFeeTaxFxSchedule → 새 VS 번호 할당 (VS-30?) +- 비용/세금/환율 일정은 별도 Slice로 추진 + +Option B: VS-06 재정의 (MaintainFeeTaxFxSchedule) +- WBS 정의로 VS-06 이름 변경 +- 기존 Stress Testing → 다른 VS로 이동 +- Cost 기능은 이 Slice 아래 포함 + +Option C: 두 기능 병렬 추진 (Dual Slices) +- VS-06: Stress Testing (기존대로) +- VS-XX: MaintainFeeTaxFxSchedule (신규 slice) +- 의존성 명확화 + +Approval needed: +✅ 선택: [ ] (A/B/C) +✅ 새 VS 번호 (선택 시): [ ] +✅ 우선순위: [ ] (어느 것이 Gate G1 선행?) +``` + +### 2️⃣ 비용/세금/환율 데이터 계약 (Data Contract) + +**결정:** 3가지 일정의 스키마 및 시간 모델 + +``` +Needed schemas: +- commission_schedule (수수료 일정) + - account_id, exchange_id, instrument_id, jurisdiction + - effective_at, published_at (valid-time?) + - fee_rate, min_fee, max_fee + +- tax_rate_schedule (세금 일정) + - jurisdiction (국가/지역) + - effective_at, published_at + - capital_gains_rate, withholding_rate + - applicable_conditions (주식/선물/옵션) + +- fx_rate_schedule (환율 일정) + - from_currency, to_currency (e.g., KRW, USD) + - effective_at (적용 시점) + - rate, bid, ask, mid + - source (KRX? Reuters? 직접 입력?) + +Questions: +✅ Temporal model: [ ] (effective_at? published_at? both?) +✅ Override 계층: [ ] (account > exchange > instrument > jurisdiction?) +✅ 이력 보관: [ ] (PIT + revision? 또는 현재만?) +✅ 정정 정책: [ ] (덮어쓰기? append? versioning?) + +Linked Items: +- AEG-X-038 (Fee/Tax/FX 의사결정) +- Platform data contract v1.0 (PIT envelope) +- Cost Basis calculation (의존 로직) +``` + +### 3️⃣ Job 4C 실행 정책 (Job 4C Schedule) + +**결정:** 비용 일정 갱신 Job의 실행 규칙 + +``` +Current state: +- Job defined in WBS as J04C (MaintainFeeTaxFxSchedule) +- No implementation exists +- Execution policy: UNDEFINED + +Questions: +✅ 실행 주기: [ ] (daily? hourly? on-demand?) +✅ 데이터 소스: [ ] (manual upload? API? configuration table?) +✅ 유효성 검증: [ ] (rate bounds? decimal precision?) +✅ 실패 처리: [ ] (transient/permanent/alert?) +✅ 주요 변경 검토: [ ] (자동? SRE 수동 승인?) +✅ Rollback 절차: [ ] (이전 버전 복원 가능?) +✅ 긴급 대응: [ ] (비상 시나리오? 재무팀 핫라인?) + +Linked Items: +- OutboxPollerJob (event publishing) +- DapperJobRunRepository (execution tracking) +- AEG-VS-00-05 (Job run 스키마) +``` + +### 4️⃣ Cost Basis 계산 통합 (Cost Basis Integration) + +**결정:** 비용/세금/환율이 Cost Basis에 언제 적용되는가 + +``` +Cost Basis calculation flow: +1. Trade executed (실행 거래) +2. Fetch commission_schedule (수수료 조회) +3. Fetch tax_rate_schedule (세금 조회) +4. Fetch fx_rate (환율 조회) +5. Calculate: Cost = (Price × Qty) + Commission - Tax credit +6. Store in cost_basis table (revision-based PIT) + +Questions: +✅ 적용 시점: [ ] (trade execution? trade confirmation?) +✅ 환율 선택: [ ] (execution rate? settlement date rate?) +✅ 세금: [ ] (선제적 계산? 실제 납부 후?) +✅ Commission source: [ ] (정해진 일정? 실제 거래 명세?) +✅ 정정: [ ] (과거 거래 비용 소급 변경 가능?) + +Linked Items: +- VS-28 (Trade Execution) +- VS-29 (Portfolio Reconciliation) +- Cost Basis PIT model +- GDPR impact (tax year 7년 보존?) +``` + +### 5️⃣ 규정 준수 & 감시 (Compliance & Monitoring) + +**결정:** 비용 일정의 규정 준수 및 감시 요구사항 + +``` +Compliance scenarios: +- 비용 조정이 특정 거래 후 지나치게 크지는 않은가? (이상 거래 의심) +- 비용이 두 번 계산되지는 않았는가? (중복 계산 방지) +- 환율 변동성이 2% 초과? (시장 변동 이상?) +- 세금 이연이 10만원 초과? (미수금 적신호?) + +Questions: +✅ DQ 검증: [ ] (rate bounds? calculation cross-check?) +✅ Audit trail: [ ] (누가 일정을 변경했나? 사유?) +✅ 감시 임계값: [ ] (변경 건수? 금액? 비율?) +✅ Alert 채널: [ ] (이메일/Slack/SMS?) +✅ 정정 승인: [ ] (CFO/Compliance만? 또는 자동?) + +Linked Items: +- AuditTrail (compliance.operation_audit_trail) +- Tax compliance (OECD BEPS) +- Financial audit requirements +``` + +--- + +## 제출 형식 + +**승인자는 다음 정보 제공:** + +### 1. Slice Definition & Scope +``` +VS-06 Definition: + Option: [ ] (A-Stress Testing / B-Cost/Tax/FX / C-Both) + +If new slice needed: + Assigned number: [ ] (VS-30? VS-31?) + Priority: [ ] (Gate G1 prerequisite?) +``` + +### 2. Data Contract Specification +``` +Commission Schedule Schema: [ ] (link to definition) +Tax Rate Schedule Schema: [ ] (link) +FX Rate Schedule Schema: [ ] (link) + +Temporal Model: + effective_at semantics: [ ] + published_at semantics: [ ] + Correction policy: [ ] (overwrite/append/version) + +Override Hierarchy: [ ] (account→exchange→instrument→jurisdiction) +``` + +### 3. Job 4C Execution Policy +``` +Execution: + Frequency: [ ] (daily/hourly/on-demand) + Data Source: [ ] (manual/API/config table) + +Validation: + Rate bounds: [ ] (e.g., ±10%?) + Precision: [ ] (decimal places) + +Failure Handling: + Transient: [ ] (retry policy) + Permanent: [ ] (alert) + Emergency: [ ] (hotline/rollback) +``` + +### 4. Cost Basis Integration +``` +Application Point: [ ] (execution/confirmation) + +FX Rate Selection: [ ] (execution/settlement) + +Tax Treatment: [ ] (prospective/actual) + +Commission Source: [ ] (schedule/invoice) + +Retroactive Adjustment: [ ] (Yes/No) +``` + +### 5. Compliance & Monitoring +``` +DQ Validation: + Rate bounds: [ ] (rules) + Duplicate detection: [ ] (Yes/No) + +Audit Trail: + Change tracking: [ ] (Yes/No) + Approval required: [ ] (Yes/No) + +Monitoring: + Alert threshold: [ ] (metrics) + Escalation: [ ] (channel) +``` + +--- + +## 의존성 + +- **Blocks:** Cost Basis implementation, Portfolio Reconciliation, G1 gate +- **Related:** AEG-X-038 (Fee/Tax/FX decisions), VS-28/29 (Trade/Reconciliation) +- **Prerequisite:** PM/Architect/Compliance/CFO 협력 + +--- + +**제출 기한:** 2026-08-21 (1주) +**승인자:** PM Lead, Architecture, Compliance/Owner, CFO +**Escalation:** Chief Financial Officer diff --git a/docs/CURRENT/AEG-X-005_RECONCILIATION_AUTH_DECISION.md b/docs/CURRENT/AEG-X-005_RECONCILIATION_AUTH_DECISION.md new file mode 100644 index 00000000..689382b6 --- /dev/null +++ b/docs/CURRENT/AEG-X-005_RECONCILIATION_AUTH_DECISION.md @@ -0,0 +1,191 @@ +# AEG-X-005: 조정(Reconciliation) 엔드포인트 권한 승인 요청 + +**WBS Item:** AEG-X-005 +**Status:** ⏳ IN_PROGRESS → DECISION_REQUIRED +**Decision Owner:** Security Lead, Compliance +**Blocks:** Portfolio Reconciliation endpoints production registration, G3 gate +**Impact:** 4개 API 경로 미등록, RBAC 미정, 감사 추적 불완전 + +--- + +## 현재 상태 + +**문제:** +- 4개 Reconciliation 경로: `GET /reconciliation`, `POST /reconciliation/submit`, `POST /reconciliation/correct`, `GET /reconciliation/{id}` +- 현재: 모두 `AllowAnonymous()` (인증 없음) +- 상태: `[DontRegister]` 마크됨 — 프로덕션 등록 안 됨 +- 권한: `Roles()` 또는 `Policies()` 정의 없음 + +**구현 완료:** +- ✅ ReconciliationEngine, CostBasisCalculator (정책/로직) +- ✅ ReconciliationEndpoints.cs (HTTP 라우팅, 계약) +- ✅ 18/18 통합 테스트 (DB 필요) + +**검증 필요:** +- ⏳ 각 경로별 필요 역할 정의 +- ⏳ 정책 규칙 (PM/Checker/SRE 구분) +- ⏳ 감사 추적 권한 연결 +- ⏳ GDPR/컴플라이언스 감시 + +--- + +## 필요한 4가지 결정 + +### 1️⃣ 조정 작업 권한 (Reconciliation Action Permission) + +**결정:** 각 경로별 필요 권한 정의 + +``` +GET /reconciliation (조정 목록): +✅ 필요 역할: [ ] (e.g., "reconciliation.read", "ops.read") +✅ 대상 사용자: [ ] (PM/Checker/SRE/Admin) + +POST /reconciliation/submit (위반 제출): +✅ 필요 역할: [ ] (e.g., "reconciliation.submit") +✅ 대상 사용자: [ ] (PM/Checker만? SRE?) + +POST /reconciliation/correct (정정 제출): +✅ 필요 역할: [ ] (e.g., "reconciliation.correct") +✅ 대상 사용자: [ ] (Checker/SRE/Owner?) + +GET /reconciliation/{id} (상세 조회): +✅ 필요 역할: [ ] (동일 또는 별도?) +✅ 소유권 제약: [ ] (본인/팀만? 또는 누구나?) +``` + +### 2️⃣ 승인 워크플로우 통합 (Approval Workflow Integration) + +**결정:** 대사 정정이 승인 워크플로우와 어떻게 연결되는가 + +``` +Current status: +- ApprovalWorkflow (VS-26) exists +- ReconciliationEngine (VS-29) exists +- Integration: NOT DEFINED + +Required decisions: +✅ 정정 제출 → 자동 승인? 또는 Maker-Checker? +✅ Checker는 누가? (역할/권한 정의) +✅ 승인/거부 후 상태 전환? +✅ 감시/알림 조건? + +Linked Items: +- ApprovalWorkflow.ApprovalPolicy +- ReconciliationEngine.StateTransitions +- GDPR 감시 규칙 +``` + +### 3️⃣ 감사 추적 권한 (Audit Trail Hookup) + +**결정:** 조정 작업을 감사 추적에 기록 + +``` +Current state: +- AuditTrailConsumer implemented (DEBT-029 discovered 2026-08-14) +- Wired into OutboxPollerJob (line 99) +- Events: APPROVAL_PROPOSED, APPROVAL_APPROVED, TRADE_SUBMITTED, etc. +- ReconciliationCorrect event: NOT IN EVENT LIST + +Required decisions: +✅ ReconciliationCorrect → compliance.operation_audit_trail 기록? +✅ 정정 내용(before/after) JSONB 저장? +✅ 감사 주체: 누가? (X-KArtSell-User 헤더?) +✅ 보존 정책: [ ] (years, GDPR 호환?) + +Linked Items: +- OutboxPollerJob (event polling) +- AuditTrailConsumer (11 event types mapped) +- GDPR retention (docs/CURRENT/AEG-X-007_SERILOG_CORRELATION.md) +``` + +### 4️⃣ 컴플라이언스/감시 규칙 (Compliance Monitoring) + +**결정:** 정정 금액의 편향성, 체계적 오류 감시 + +``` +Scenarios requiring rules: +- 같은 종목 연속 정정 (일일 3회 초과?) +- 일일 정정 금액 한계 (예: 계좌별 5천만원) +- Checker와 PM이 다른 사람인가? (이해관계 충돌) +- 정정 비율이 20% 초과? (이상 거래 의심) + +Approval needed: +✅ 감시 임계값: [ ] (건수, 금액, 비율) +✅ 알림 채널: [ ] (email/Slack/SMS) +✅ 에스컬레이션: [ ] (SRE/CFO/Compliance) +✅ 자동 잠금: [ ] (정정 일시 중지 가능?) + +Linked Items: +- Serilog correlation (structured properties) +- Alert rules (.gitea/workflows/ or Grafana) +- Runbook (정정 비상 시나리오) +``` + +--- + +## 제출 형식 + +**승인자는 다음 정보 제공:** + +### 1. Reconciliation Endpoint Permissions +```yaml +GET /reconciliation: + Roles: [ ] + Users: [ ] + +POST /reconciliation/submit: + Roles: [ ] + Users: [ ] + +POST /reconciliation/correct: + Roles: [ ] + Users: [ ] + +GET /reconciliation/{id}: + Roles: [ ] + Ownership: [ ] +``` + +### 2. Approval Workflow Integration +``` +Correct → Maker-Checker: [ ] (Yes/No) +Checker Role: [ ] +Auto-Approve Policy: [ ] +Notification Channel: [ ] +``` + +### 3. Audit Trail Specification +``` +ReconciliationCorrect Event: + Log to compliance.operation_audit_trail: [ ] (Yes/No) + Payload includes before/after: [ ] (Yes/No) + Retention: [ ] (years) + GDPR compliant: [ ] (Yes/No) +``` + +### 4. Compliance Monitoring Rules +``` +Alert Threshold (daily): + Max corrections: [ ] (count) + Max amount: [ ] (KRW) + Max ratio: [ ] (%) + +Escalation: + Channel: [ ] (Email/Slack/SMS) + Owner: [ ] + Auto-lock: [ ] (Yes/No) +``` + +--- + +## 의존성 + +- **Blocks:** VS-29 production registration, G3 gate +- **Related:** ApprovalWorkflow (VS-26), AuditTrail (VS-27), GDPR (DEBT-X) +- **Prerequisite:** Security/Compliance team sign-off + +--- + +**제출 기한:** 2026-08-21 (1주) +**승인자:** Security Lead, Compliance Lead +**Escalation:** Chief Compliance Officer diff --git a/docs/CURRENT/AEG-X-008_OPENAPI_BASELINE_DECISION.md b/docs/CURRENT/AEG-X-008_OPENAPI_BASELINE_DECISION.md new file mode 100644 index 00000000..771ad7ef --- /dev/null +++ b/docs/CURRENT/AEG-X-008_OPENAPI_BASELINE_DECISION.md @@ -0,0 +1,208 @@ +# AEG-X-008: OpenAPI 기준선 & 릴리스 서명 승인 요청 + +**WBS Item:** AEG-X-008 +**Status:** ⏳ IN_PROGRESS → DECISION_REQUIRED +**Decision Owner:** API Architect, DevOps +**Blocks:** FE OpenAPI 자동 생성, CI/CD 파이프라인 게이트, API 버전 관리 +**Impact:** API 계약 검증 미완료, 클라이언트 생성 불가, 변경 추적 불명확 + +--- + +## 현재 상태 + +**구현 완료:** +- ✅ Host Release 빌드 (0 경고/오류) +- ✅ Architecture tests 17/17 PASS +- ✅ OpenAPI 게이트 로컬 검증: YAML/기준선/후보 검증 0 위반 +- ✅ FE 회귀 57 files/150 tests PASS + +**아직 미결정:** +- ⏳ 공식 기준선 승인 (baseline approval) +- ⏳ Gitea Actions 실행 권한 +- ⏳ API Architect 릴리스 서명 +- ⏳ 변경 추적 정책 + +**알려진 이슈:** +- 현재: >500 kB Vite 청크 경고 (AEG-X-002 최적화 후에도 지속) + +--- + +## 필요한 4가지 결정 + +### 1️⃣ 공식 OpenAPI 기준선 (Baseline Snapshot) + +**결정:** 프로덕션 릴리스 시 공식 기준선 정의 + +``` +Current state: +- src/KArtSell.Host/artifacts/openapi/current_20260813_auto-off.json (기준) +- Generated on: 2026-08-13 14:02 UTC +- Total endpoints: [count required] +- Security schemes: X-KArtSell-User header + Role-based + +Approval needed: +✅ 기준선 파일 지정: [ ] (git path) +✅ 버전 정책: [ ] (semantic/date-based) +✅ 승인 프로세스: [ ] (자동/수동) +✅ 기준선 갱신 빈도: [ ] (per-release/quarterly) + +Linked Items: +- src/KArtSell.Host/artifacts/openapi/ (저장소) +- .gitea/workflows/openapi-gate.yml (CI 검증) +- docs/DECISIONS/ADR-API-BASELINE-001.md (현재 ADR) +``` + +### 2️⃣ 호환성 정책 (Compatibility Enforcement) + +**결정:** 기준선 vs 후보 비교 규칙 + +``` +Breaking changes that FAIL the gate: +- Endpoint 제거 또는 경로 변경 +- 필수 파라미터 추가 (기존 클라이언트 호환 불가) +- 응답 필드 제거 (기존 클라이언트 parsing 실패) +- Status code 변경 (e.g., 200 → 400) + +Non-breaking changes that PASS: +- 선택적 파라미터/필드 추가 +- 새로운 status code 추가 (기존 클라이언트 무시 가능) +- 기존 필드 추가 필터/정렬 옵션 + +Approval needed: +✅ Breaking change 정의: [ ] (완전? 부분?) +✅ Deprecation 정책: [ ] (90일 공지? 기간?) +✅ 주요 버전 전략: [ ] (v1/v2 지원?) +✅ 예외 프로세스: [ ] (CTO 승인 필요?) + +Linked Items: +- OpenAPI 3.1 deprecated keyword usage +- Semantic versioning (major.minor.patch) +- Client library generation (auto-off vs auto-on) +``` + +### 3️⃣ Gitea Actions 실행 & 서명 (CI/CD Gate) + +**결정:** 자동 검증과 수동 서명 책임 + +``` +Current CI/CD state: +- .gitea/workflows/openapi-gate.yml exists +- Runs on: push/PR (currently local only) +- Validation: YAML structure, baseline diff, schema compliance +- Status: No Gitea Actions configured server-side + +Decisions needed: +✅ Gitea Actions enabled: [ ] (Yes/No) +✅ 실행 권한: [ ] (auto/manual) +✅ 릴리스 서명자: [ ] (단일/복수?) +✅ 서명 증명: [ ] (commit msg/tag/annotation?) + +Approval needed: +✅ API Architect: [ ] (name/email) +✅ API Architect secondary: [ ] (name/email, fallback) +✅ DevOps gate owner: [ ] (name/email) +✅ Approval 보존 기한: [ ] (6개월/1년/영구) + +Linked Items: +- .gitea/workflows/openapi-gate.yml (current workflow) +- src/KArtSell.Host/artifacts/openapi/ (baseline location) +- API Architect approval log (where to record?) +``` + +### 4️⃣ 클라이언트 생성 & 배포 (Client Generation) + +**결정:** 공식 OpenAPI 기준선 기반 클라이언트 생성 여부 + +``` +Option A: Manual (current state) +- Baseline: 수동 승인 → 배포 +- Client: 개발자 수동 생성 (openapi-generator, swagger-codegen) +- 사용: 직접 임포트 또는 npm 게시 + +Option B: Automated +- Baseline: CI gate auto-pass (호환성 규칙 충족) +- Client: 자동 생성 (GitHub Actions / Gitea Actions) +- 배포: NPM registry (npm publish) 또는 S3 +- 버전: OpenAPI 버전 태그 동기화 + +Option C: Hybrid +- Pre-release: 수동 승인 (API Architect sign-off) +- Patch: 자동 생성 (호환성 보장) +- Release: 태그 자동 + NPM publish + +Approval needed: +✅ 정책 선택: [ ] (A/B/C) +✅ 클라이언트 저장소: [ ] (npm/@kartsell/client? git-submodule?) +✅ 배포 주기: [ ] (per-release/weekly) +✅ 자동 테스트: [ ] (생성된 클라이언트 검증?) + +Linked Items: +- docs/CURRENT/V13-FE-009_ADR_OPENAPI_ZOD_STRATEGY.md (현재 전략) +- openapi-generator / swagger-codegen (도구) +- npm registry vs internal repository +``` + +--- + +## 제출 형식 + +**승인자는 다음 정보 제공:** + +### 1. Baseline Approval +``` +Official Baseline: + File: [ ] (git path) + Version: [ ] (vX.Y.Z or YYYY-MM-DD) + +Update Policy: + Frequency: [ ] (per-release/quarterly/on-demand) + Approval Process: [ ] (auto/manual) + Sign-off Required: [ ] (Yes/No) +``` + +### 2. Compatibility Rules +``` +Breaking Changes: + Defined: [ ] (comprehensive list) + Deprecation Period: [ ] (days) + +Non-Breaking: + Auto-approved: [ ] (Yes/No) + Client Notification: [ ] (Yes/No) +``` + +### 3. Gitea Actions & Signing +``` +CI Execution: + Enabled: [ ] (Yes/No) + Trigger: [ ] (push/PR/manual) + +API Architect: + Primary: [ ] (name) + Secondary: [ ] (name) + Approval Record: [ ] (location) +``` + +### 4. Client Generation Strategy +``` +Option: [ ] (A-Manual / B-Automated / C-Hybrid) + +Deployment: + Repository: [ ] (npm/@kartsell/client / git-submodule) + Frequency: [ ] (per-release/weekly) + Validation: [ ] (Yes/No) +``` + +--- + +## 의존성 + +- **Blocks:** FE OpenAPI 클라이언트 생성, CI/CD 완전 자동화 +- **Related:** AEG-X-002 (번들 최적화), 빌드 파이프라인, 버전 관리 +- **Prerequisite:** API Architect, DevOps 팀 협력 + +--- + +**제출 기한:** 2026-08-21 (1주) +**승인자:** API Architect, DevOps Lead +**Escalation:** Engineering Director (정책 논쟁 시)