도서 생애주기 & SSoT

우리학교 ERP · 계약 → 편집 → 출간 → 정산 데이터 단일 소스 정리

모든 ERP 테이블은 books.idNOT NULL FK + ON DELETE RESTRICT로 참조한다. books가 모든 데이터의 hub이고, 다른 테이블은 books를 향한 위성이다.

1. 생애주기 흐름

flowchart TB
    classDef ssot fill:#fffbeb,stroke:#c0392b,stroke-width:2px,color:#222
    classDef ext fill:#e3f2fd,stroke:#1565c0,color:#1565c0
    classDef side fill:#f8f9fa,stroke:#999,color:#6c6f85,stroke-dasharray: 4 3
    classDef phase fill:#fff,stroke:#222

    Hub[("📚 books
도서 마스터")]:::ssot subgraph P1["① 계약 체결"] direction TB Modusign[모두싸인 사이트
전자계약]:::ext Upload[ERP 업로드
드래그앤드롭] Storage[(Firebase Storage
PDF 원본)]:::ssot Skill[Claude Code 스킬
PDF Read → 9개 필드] Contracts[("contracts
인세율·선인세·기한")]:::ssot Modusign -->|PDF 다운로드| Upload Upload --> Storage Upload --> Contracts Contracts --> Skill Skill --> Contracts end subgraph P2["② 편집 진행"] Editorial[("editorial_projects
편집 상태·담당자")]:::ssot end subgraph P3["③ 출간·제작"] WO[("work_orders
제작 발주서")]:::ssot WOF[("work_order_files
1:N 첨부")]:::ssot PR[("print_runs
인쇄 이력 쇄별")]:::ssot BT[("book_translations
ko/en/zh/ja")]:::ssot Dropbox[Dropbox
회사 운영 미러]:::side WO --- WOF end subgraph P4["④ 정산·청구"] Settle[("settlements
인세 정산 = 계산값")]:::ssot Inv[("invoice_items
청구서 라인")]:::ssot Alloc[("invoice_item_allocations
쇄별 분배 트리거")]:::ssot Settle --> Inv Inv --> Alloc PR --> Alloc end subgraph P5["⑤ 게시·검색"] RSC[홈페이지 RSC] Typesense[Typesense
검색 인덱스]:::side end Contracts -.-> Hub Editorial -.-> Hub WO -.-> Hub PR -.-> Hub BT -.-> Hub Settle -.-> Hub Inv -.-> Hub Dropbox -. 참고 .- WO Hub --> RSC Hub --> Typesense BT --> RSC

SSoT 외부 원본 시스템 사이드카 (참고/복사) 점선: book_id FK · 실선: 데이터 흐름

2. 단계별 SSoT 매핑

단계 SSoT (단일 진실의 원천) 사이드카 (참고/복사) 핵심 데이터
계약 Supabase contracts (메타)
+ Firebase Storage (PDF 원본)
모두싸인 사이트
(audit 필요 시 역추적)
인세율 (종이/전자/오디오), 선인세, 계약일, 원고/출판 기한, 존속기간
편집 Supabase editorial_projects 편집 진행 상태, 담당자, 마일스톤
도서 메타 Supabase books Typesense (검색 인덱스)
자동 동기화
제목, 저자, ISBN, 카테고리, 가격, 표지, 출간일, 상태
제작·발주 Supabase work_orders +
work_order_files (1:N)
Dropbox 4.제작/작업의뢰서/
사람용 운영 미러
발주일, 인쇄소, 부수, 용지 공급처, 담당자
인쇄 이력 Supabase print_runs 쇄별 부수, 입고일, 정가
다국어 Supabase book_translations ko/en/zh/ja 별 제목·소개·목차·저자소개
정산 Supabase settlements
= contracts × print_runs (계산값)
저자별 인세 지급액, 정산 주기
청구 Supabase invoice_items +
invoice_item_allocations
거래처별 청구 라인 + 쇄별 분배 (DB 트리거 자동 계산)
게시 Next.js RSC (books + book_translations 직조회) 공개 도서 페이지, 검색, 카테고리

3. 핵심 원칙

01
books가 hub다.
모든 ERP 테이블은 book_id NOT NULL + ON DELETE RESTRICT로 books를 참조한다. 새 도서는 라이프사이클의 가장 먼저 만들어지고, 가장 나중에 삭제될 수 있다 (참조가 다 사라진 후).
02
계산값과 원본값을 구분한다.
settlementscontracts × print_runs의 파생 계산값. invoice_item_allocationsinvoice_items + print_runs의 트리거 자동 계산. 계산값은 SSoT가 아니라, 원본값이 바뀌면 다시 계산해야 한다.
03
컬럼이 SSoT, JSON은 audit이다.
contracts.royalty_rate 같은 컬럼이 정산 로직의 SSoT. contracts.parsed_data JSONB는 AI 파싱 원본 보존 + 자유 추가 필드 (참조 안정성 보장 X). 정산 코드는 컬럼만 읽고 JSON은 보지 않는다.
04
사이드카는 SSoT가 아니다.
Typesense는 books의 검색용 인덱스 복사본 — 정합성은 books에서 자동 동기. Dropbox 4.제작/작업의뢰서/는 회사 운영자가 보는 GUI 미러일 뿐, ERP의 SSoT는 work_orders. 사이드카가 없거나 늦어도 ERP는 동작한다.
05
외부 원본 시스템에서 ERP로 가져오는 게이트는 명확히.
모두싸인 사이트는 전자계약의 원본 시스템이지만, ERP는 자체 SSoT(Firebase Storage + contracts)를 갖는다. 사용자가 PDF를 ERP에 업로드하는 시점이 ERP의 게이트. 이후엔 ERP만 신뢰하면 되고, 모두싸인은 audit 필요 시 역추적용.

4. 데이터 등록 흐름 (신규 계약 예시)

sequenceDiagram
    actor User as 사용자
    participant ERP as ERP UI
    participant FS as Firebase Storage
    participant DB as Supabase
    participant Claude as Claude Code 스킬

    Note over User,Claude: ① 업로드 (즉시)
    User->>ERP: PDF 드래그앤드롭
(+선택: modusign URL) ERP->>FS: PDF 업로드 FS-->>ERP: firebase_path ERP->>DB: contracts INSERT
(parse_status='pending') DB-->>User: 업로드 완료 ✓ Note over User,Claude: ② 파싱 (사용자가 트리거) User->>Claude: /parse-contracts Claude->>DB: pending row 조회 Claude->>FS: PDF 다운로드 + Read tool Claude->>Claude: 9개 필드 추출
+ books fuzzy 매칭 Claude->>User: 추출 결과 + book 후보 표시 Note over User,Claude: ③ 검증·확정 User->>Claude: confirm + book_id 선택 Claude->>DB: contracts UPDATE
(parse_status='active') DB-->>User: 라이프사이클 시작 ✓

5. 현재 정합성 (2026-05-14 기준)

연도contracts 등록firebase_pathmodusign_id상태
20204040 (100%)40 (100%)✓ 완전
2021134134 (100%)134 (100%)✓ 완전
20227474 (100%)74 (100%)✓ 완전
2023119119 (100%)119 (100%)✓ 완전
2024157157 (100%)157 (100%)✓ 완전
2025156156 (100%)156 (100%)✓ 완전
20265553532건 진행 중 (가제)

총 685건 · SSoT 결손 0건 · ERP가 회사 마스터 데이터의 실질 진실의 원천.