# DS App Contract (S1 인터페이스 동결) — v0.1

S1·S2·S3 **동시 출발선**. 앱(S3)은 실 백엔드/실 LLM 없이 **이 디렉토리만 보고** 빌드한다.

```
contract/
  CONTRACT.md            ← 엔드포인트 + 요청/응답 shape 동결 스펙 (읽기 시작점)
  fixtures/              ← 응답 JSON 박제 (앱 프리뷰/디코딩 테스트가 로드)
    auth_login.json            POST /auth/login
    auth_me.json               GET  /auth/me
    documents_list.json        GET  /documents/         (DocumentListResponse)
    document_detail.json       GET  /documents/{id}     (md_status=completed — MD-first 렌더)
    document_detail_pending_md.json  GET /documents/{id} (md_status=pending — extracted_text 폴백 케이스)
    document_content.json      GET  /documents/{id}/content
    documents_tree.json        GET  /documents/tree
    documents_stats.json       GET  /documents/stats/category-counts
    documents_duplicates.json  GET  /documents/duplicates   [S1-ADD] 중복검사
    search.json                GET  /search/
    ask.json                   GET  /search/ask
    memos_list.json            GET  /memos/
    memo_detail.json           GET  /memos/{id}
    digest.json                GET  /digest
```

## 동결 원칙
- 모든 shape는 **실제 GPU 백엔드 Pydantic 모델에서 추출**(지어내지 않음). `[S1-ADD]` 필드만 신규.
- 앱 모델(Swift Codable)은 위 fixtures를 그대로 디코딩할 수 있어야 한다 = 1차 수용 테스트.
- 통합 시 fixture ↔ 실 응답 **call-shape regression**으로 대조.

## `[S1-ADD]` (S1이 추가할 신규 — 앱은 옵셔널 디코딩)
- `original_filename`, `duplicate_of`, `duplicate_count` (DocumentResponse/Detail)
- `GET /documents/duplicates` (중복검사 개선 트랙)
- Word/Excel/이미지/오디오 → `md_content` 채우기 (MD-first 전포맷 — marker는 현재 PDF 전용)

## 다음
- S3: 이 fixtures를 디코딩하는 Swift `Codable` 모델 + API client(프로토콜) → macOS 앱.
- S1: `[S1-ADD]` 구현 + 위 shape 유지(깨면 version bump).
- S2: `/search/ask?backend=` + 온디바이스 provider 추상화(`AIProvider`).
