# 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 (정책 논쟁 시)