You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4.7 KiB

Phase 1 서비스 계약서

1. 목적

이 문서는 각 서비스와 adapter가 어떤 입력을 받고 어떤 출력을 내야 하는지 정의합니다. AI 코딩 에이전트는 이 계약을 기준으로 인터페이스를 고정해야 합니다.

2. 공통 원칙

  • 모든 서비스는 명시적 입력 객체를 받습니다.
  • 모든 서비스는 typed result 또는 typed error를 반환합니다.
  • 외부 API 호출 결과는 raw 저장 이후에만 정규화됩니다.
  • 서비스는 가능하면 pure function 형태를 유지합니다.
  • DB write는 application layer에서 수행하고, parser/adapter core는 side-effect를 최소화합니다.

3. 공통 타입

3.1 FetchRequest

{
  "source": "sec",
  "entity": "issuer|symbol|series|date",
  "key": "0000789019",
  "start_date": "2026-01-01",
  "end_date": "2026-03-31",
  "run_mode": "backfill|daily|replay"
}

3.2 FetchResult

{
  "status": "success|partial|failed|skipped",
  "raw_object_ids": ["RAW::..."],
  "records_seen": 3,
  "records_written": 3,
  "warnings": [],
  "errors": []
}

3.3 NormalizeResult

{
  "status": "success|failed",
  "canonical_records": [{"...": "..."}],
  "warnings": [],
  "errors": []
}

4. SEC adapter 계약

4.1 입력

  • CIK 또는 accession
  • 기간 또는 개별 filing key
  • run_mode

4.2 출력

  • submissions raw object
  • filing raw object
  • exhibit raw object list
  • canonical document metadata

4.3 함수 예시

def fetch_submissions(cik: str) -> FetchResult: ...
def fetch_filing(accession_no: str, cik: str) -> FetchResult: ...
def normalize_filing(raw_object_id: str) -> NormalizeResult: ...

4.4 실패 규칙

  • HTTP 실패 → retryable error
  • 404 → non-retryable warning
  • parsing 실패 → raw는 유지, normalize fail

5. Alpaca adapter 계약

5.1 입력

  • symbol list
  • timeframe
  • start/end

5.2 출력

  • canonical OHLCV record list

5.3 함수 예시

def fetch_bars(symbols: list[str], timeframe: str, start: str, end: str) -> FetchResult: ...
def normalize_bars(raw_object_id: str) -> NormalizeResult: ...

6. FRED adapter 계약

def fetch_series(series_id: str, start: str | None = None, end: str | None = None) -> FetchResult: ...

출력:

  • series metadata
  • observation records

7. FINRA adapter 계약

def fetch_daily_short_volume(trade_date: str) -> FetchResult: ...
def normalize_daily_short_volume(raw_object_id: str) -> NormalizeResult: ...

주의:

  • symbol mapping 실패 가능
  • 원본 ticker_raw는 반드시 유지

8. Event Parser 계약

입력:

{
  "document_id": "DOC::...",
  "source_name": "sec",
  "form_type": "8-K",
  "issuer_id": "ISSUER::...",
  "filing_date": "2026-01-29",
  "accepted_at_utc": "2026-01-29T21:05:00Z",
  "text": "...document text...",
  "metadata": {
    "item_numbers": ["2.02", "7.01"],
    "exhibits": ["EX-99.1"]
  }
}

출력:

  • parser_event.schema.json을 만족하는 JSON

실패:

  • invalid schema → validation_status=invalid
  • parser exception → error object 반환, event 생성 금지

9. Feature Builder 계약

입력:

  • event row
  • related market data
  • optional macro/short volume rows

출력 예시:

{
  "event_id": "EVT::...",
  "snapshot_name": "event_v1",
  "snapshot_version": "1.0.0",
  "feature_json": {
    "guidance_direction": "raised",
    "oneoff_penalty": 0,
    "reaction_day_return": 0.042,
    "volume_ratio_20d": 2.3
  }
}

10. Job Runner 계약

입력:

  • job_name
  • source_name
  • run_date
  • mode

출력:

  • job_runs 테이블 row 업데이트
  • 로그 스트림

상태 전이:

  • pending → running → succeeded
  • pending → running → partial
  • pending → running → failed

11. 에러 객체 표준

{
  "error_class": "RateLimitError",
  "message": "HTTP 429 from source",
  "retryable": true,
  "source_name": "sec",
  "entity_key": "0000789019",
  "context": {"url": "..."}
}

12. 로그 포맷 표준

{
  "timestamp": "2026-03-12T10:00:00Z",
  "level": "INFO",
  "service": "sec_collector",
  "job_run_id": "...",
  "message": "fetched submissions",
  "source": "sec",
  "entity_id": "0000789019",
  "records_seen": 1,
  "records_written": 1
}

13. 재시도 계약

  • source adapter의 네트워크 실패는 최대 3회 지수 백오프
  • validation 실패는 재시도하지 않음
  • DB deadlock/connection issue는 retryable
  • schema mismatch는 raw 보존 후 failed 처리

14. 금지 규칙

  • adapter가 임의로 심볼명을 정정하지 말 것
  • parser가 raw text를 수정 저장하지 말 것
  • feature builder가 원문 source를 재호출하지 말 것
  • job runner가 실패를 성공으로 덮어쓰지 말 것