처음 보는 분을 위한 한 줄 정리
이 페이지는 "기술 구조"보다 실제 작업 흐름을 먼저 이해하도록 구성했습니다.
특히 협업의 피드백 라운드는 기존의 개별 코멘트 방식과 비교해,
"요청 → 검토 → 반영 결정 → 기록"이 한 화면에서 이어지도록 개선했습니다.
시나리오 파이프라인 6 Stages
📤
Upload
scripts-worker
Gemini FlashR2
→
📄
Parse
parse-worker
Queue ×10Gemini
→
🕸️
Ontology
ontology-worker
QueueGemini
→
🔬
Analysis
analysis-worker
Queue ×5Gemini
→
🧬
Embedding
rag-worker
Queue ×50Vectorize
→
📊
Report
report-worker
Queue ×10HTTP
📤 Upload — 스크립트 업로드 및 메타데이터 추출
1. 프론트엔드 모달
사용자가 PDF/DOCX 선택 → 업로드 모달 표시 → scripts-worker로 전송
2. Gemini Flash 메타추출
제목, 작가, 장르, 페이지수 자동 추출 (fast model) → filename fallback
3. R2 저장
원본 PDF → scripts/{scriptId}/original.pdf
4. startParse RPC
scripts-worker → Main API startParse → Parse Queue 메시지 발행
📄 Parse — PDF 파싱 (13-Phase Gemini)
1. PDF Split & R2 저장
PDF Worker /pdf/split-and-store → sub-PDF를 parse-pdf-chunks/{parseId}/에 저장
2. Chunk Queue (병렬)
max_concurrency 10 · 초기 3개 동시 → manifest 기반 진행률 관리
3. Gemini Per-Chunk
GCS 업로드 → generateWithGcsFile → 13-phase 구조화 파싱 → GCS 삭제
4. Scene Merge + Dedup
청크 결과 병합 → 씬 중복 제거 → 캐릭터 추출 → D1 저장
5. Manifest R2
파싱 진행 상태 manifest를 R2에 저장/갱신 → 프론트엔드 폴링
SDK Retry
maxRetries: 0 (SDK 내부 retry 비활성) → agentRetry가 유일한 retry 컨트롤러
🕸️ Ontology — 지식 그래프 생성
1. Queue Trigger
Parse 완료 → ontology queue 메시지 → ontology-worker 소비
2. Entity/Relationship 추출
Gemini로 캐릭터, 장소, 이벤트, 관계를 구조화 추출
3. Graph 저장
D1에 노드/엣지 저장 → Cytoscape.js 프론트 시각화
🔬 Analysis — 6-Category AI 분석 (4-Phase Self-Requeue)
Phase 1: AI Analyze
6개 카테고리 (스토리, 캐릭터, 대화, 구조, 시각, 시장성) 개별 AI 분석
Phase 2: Insights
분석 결과 → 인사이트 도출 → self-requeue로 다음 Phase
Phase 3: Aggregate
개별 카테고리 → 종합 점수 + 강점/약점 집계
Phase 4: Finalize
최종 결과 D1 저장 → 상태 COMPLETED → 프론트엔드 알림
🔄
max_concurrency 5 · 각 Phase 완료 시 self-requeue로 다음 Phase 진행
🧬 Embedding — 벡터화 + Vectorize 저장
1. Batch R2 저장
씬/캐릭터/분석 텍스트 → embedding 배치로 R2에 임시 저장 (CPU 소진 방지)
2. Queue 소비
embedding queue · max_concurrency 50
3. Vectorize 저장
Cloudflare Vectorize에 벡터 인덱싱 → RAG 검색 활성화
📊 Report — PDF 리포트 생성
1. Queue Trigger
report queue · max_concurrency 10
2. Report Worker
D1에서 분석 데이터 조회 → 템플릿 렌더링
3. PDF Worker (HTTP)
Report Worker → HTTP 호출 → PDF Worker에서 pdf-lib로 생성
4. R2 저장
완성 PDF → R2 reports/{reportId}.pdf → 다운로드 URL 발급
AI 채팅 Agentic Loop V3 5 Stages
💬
사용자 입력
Optimistic UI
AbortController
→
📡
SSE 연결
ai-chat-worker
WorkerLazy Load
→
📋
Blueprint
Single AI Call
Gemini
→
⚡
Phase 실행
5-way Switch
Tool CallsHITL
→
💾
응답 저장
D1 + R2 Audit
D1R2
📡 SSE 연결 — AI Chat Worker
Lazy Load
14개 모듈 동적 import (Worker 400ms CPU limit 대응)
Access Check
시나리오 접근권한 + 사용량 Quota 확인
Service Binding
Main API → AI_CHAT_WORKER binding으로 프록시
📋 Blueprint — Intent + Phase 계획 (Single AI Call)
Intent 분석
intent, entities, complexity, summary를 한 번의 AI 호출로 결정
Phase 계획
ask → planning → execution → reflection → synthesis 중 필요한 phase 선택
execution_path 이벤트
SSE로 intent, entities, summary, confidence 전송
🔀
Route Change: complex + non-destructive → SSE 종료 → Background Queue → WebSocket relay
⚡ Phase 실행 — 5-way Switch + Tool Calls
ask
사용자에게 추가 정보 요청 (자유입력 + 옵션)
planning
실행 계획 수립 → 사용자 확인
execution
Tool calls (시나리오 조회, 분석 실행, 수정 등) → Keepalive 5초
reflection
실행 결과 검토 → 추가 작업 필요 시 재실행
synthesis
최종 응답 생성 → 인사이트 포함
🤝
HITL: confirm (취소/건너뛰기/계속) · ask (자유입력+옵션) → KV 기반 60초 timeout
SSE 이벤트 종류
thinking
tool_call
tool_result
intent
message
contexts
phase_change
execution_path
ask
confirm
route_change
done
error
💾 응답 저장 — D1 (slim) + R2 (full trace)
D1 chat_messages
intent, responseType, structured, modification, toolCalls, contexts (슬림 메타데이터)
R2 Audit Trail
audit/chat/{sessionId}/{messageId}.json — executionPath, thinkingSteps, reasoning, phases, 전체 CoT
CoT Display
프론트엔드 lazy-load R2 → thinkingSteps + reasoning 표시
협업 플로우 3 Stages
👥
시나리오 공유
Stakeholder 관리
ScenarioRoom DO
→
💬
피드백 라운드
Review Cycle
Realtime
→
✅
결재선
Approval Chain
ApprovalNotifier DO
👥 시나리오 공유 — Stakeholder Access Control
Add Stakeholder
OWNER · EDITOR · COMMENTER · VIEWER 역할 부여
초대 프로세스
이메일 초대 → Accept/Reject → 접근 권한 자동 부여
Access Control
역할별 읽기/쓰기/삭제 권한 분리 · API 레벨 enforcement
Realtime
ScenarioRoom DO → WebSocket으로 참여자 상태 브로드캐스트
💬 피드백 라운드 — Review Cycle
1. 라운드 시작
작성자가 이번 검토 범위를 정하고 리뷰어를 지정합니다.
2. 리뷰어 코멘트 등록
씬/캐릭터/대화 단위로 의견을 남기고, 필요하면 AI 추출 결과를 함께 확인합니다.
3. 작성자 결정
각 항목을 반영(Apply) 또는 보류/거절(Reject)로 처리해 상태를 명확히 남깁니다.
4. 라운드 종료
처리가 끝나면 라운드를 닫고, 누가 무엇을 결정했는지 이력을 보존합니다.
이전 방식 (개별 코멘트 중심)
- 코멘트가 여러 화면에 흩어져 진행 상태를 보기 어려움
- 누가 처리해야 하는지 명확하지 않은 경우가 잦음
- 반영 여부가 대화/메모에만 남아 추적이 어려움
- 라운드 단위 마감 기준이 약해 일정 관리가 어려움
현재 방식 (라운드 중심 워크플로우)
- 요청, 코멘트, 결정, 종료가 같은 흐름에서 관리됨
- 작성자/리뷰어 역할이 분리되어 책임 주체가 분명함
- 항목별 Apply/Reject 상태로 반영 여부를 즉시 확인 가능
- 라운드 종료 시점 기준으로 이력과 결과를 깔끔히 남김
As-Is 사례 (기존 방식)
사례: 투자자 A가 "씬 12 대사 톤이 약하다"는 피드백을 남긴 경우
Writer -> Reviewer : "검토 한번 부탁"
Reviewer -> Scenario : 코멘트 등록
Reviewer -> Writer : DM/채팅으로 알림
Writer -> Scenario : 수정 반영(수동)
Writer -> Reviewer : "수정 완료" 공유
Note: 반영 여부/근거가 여러 채널에 흩어짐
To-Be 시퀀스 (현재 반영)
동일 사례를 라운드 중심으로 처리한 실제 운영 흐름
Writer -> Round : 라운드 생성 + 리뷰어 지정
Round -> Reviewer : 리뷰 요청 알림
Reviewer -> Round : FB-123 등록 (Scene 12)
Writer -> Round : FB-123 Apply or Reject
Round -> AuditLog : 결정자/시간/근거 저장
Writer -> Round : 라운드 Close
Round -> Team : 처리 결과 공유
Result: 누락/중복 확인이 줄고 추적이 쉬워짐
📌
핵심 개선: "의견 수집"에서 끝나지 않고, "결정과 기록"까지 한 번에 완료되는 운영 흐름으로 바뀌었습니다.
✅ 결재선 — Approval Chain System
Create Chain
승인 단계(steps) 정의 → 각 단계별 Approver 지정
Trigger
특정 이벤트 발생 시 결재 프로세스 자동 시작
Approver 응답
Approve / Reject / Delegate (위임) → 다음 단계 진행
Escalation
미응답 시 상위자 에스컬레이션 → Conflict Resolution
Post-approval
승인 완료 → 후속 작업 자동 실행 (배포, 알림 등)
🔔
Realtime 알림: ScenarioRoom DO + ApprovalNotifier DO + UserJobsRoom DO → WebSocket broadcast
MSA 아키텍처 14 Workers · 10 Queues · 6 DO
HTTP Workers (7)
| Worker | Port | Route | 주요 역할 |
| cinology-api | 8787 | api.thengd.com/* | Main API — oRPC 30 domains, 268+ handlers, D1, R2, Vectorize, Queue |
| cinology-auth | 8789 | /api/auth/* | Better Auth 인증 — 세션, OAuth, 비밀번호 |
| cinology-ai-chat | 8788 | /api/rpc/ai/chat/* | AI Chat — Agentic Loop V3, Background, HITL, Intent |
| cinology-scripts-worker | 8790 | /api/scripts/* | Heavy HTTP — 스크립트 업로드, AI 메타추출, 파일 처리 |
| cinology-rag | - | /api/rag/* | RAG/Embedding — 벡터 검색, 임베딩 처리 |
| cinology-admin | - | /api/admin/* | Admin — LiteLLM, KOBIS, KMDb, CF AI Gateway |
| cinology-pdf-worker | - | HTTP call | PDF 생성 — pdf-lib, split-and-store |
Queue Workers (5)
| Worker | Port | Queue 소비 | 주요 역할 |
| cinology-parse-worker | 8791 | parse, vision_reparse, feedback_extract | PDF 파싱 — 13-phase, chunk 병렬 |
| cinology-ontology-worker | 8793 | ontology | 지식 그래프 — Entity/Relationship 추출 |
| cinology-analysis-worker | 8794 | analysis | AI 분석 — 6-category, 4-phase self-requeue |
| cinology-report-worker | 8795 | report | 리포트 생성 → PDF Worker HTTP 호출 |
| cinology-visual-gen | - | visual_generation | 시각 콘텐츠 생성 (experimental) |
Queue 토폴로지 (10)
| Queue | Producer | Consumer | max_concurrency |
| parse | scripts-worker, api | parse-worker | 10 |
| vision_reparse | api (admin) | parse-worker | 5 |
| feedback_extract | api | parse-worker | 5 |
| ontology | parse-worker | ontology-worker | 5 |
| analysis | api, analysis-worker | analysis-worker | 5 |
| embedding | api, rag | rag-worker | 50 |
| pattern | api | rag-worker | 5 |
| report | api | report-worker | 10 |
| visual_generation | api | visual-gen | 3 |
| kobis_sync | admin (cron) | admin | 1 |
Durable Objects (6)
🏠
ScenarioRoom
시나리오별 실시간 WebSocket
🔔
ApprovalNotifier
결재 알림 실시간 전송
👤
UserJobsRoom
사용자별 작업 상태 알림
⏱️
DynamicScheduler
DB-driven Cron 스케줄러
🔑
RateLimiter
API Rate Limiting
💬
ChatSession
AI Chat 세션 상태 관리
외부 서비스
☁️
Vertex AI / GCS
PDF→GCS 업로드 후 AI
🎨
FAL AI
이미지 생성 (experimental)
🎬
KOBIS / KMDb
영화 박스오피스 · 메타데이터
🔐
Better Auth
인증 · 세션 · OAuth
💰
LiteLLM
AI 비용 추적 · 가격 동기화
데이터 레이어
| 서비스 | 용도 |
| D1 SQLite | 주 데이터베이스 — Drizzle ORM, 12 도메인 스키마, 마이그레이션 |
| R2 Object | 스크립트 PDF, sub-PDF 청크, 파싱 manifest, audit trail, 리포트, 임베딩 배치 |
| KV Key-Value | HITL 상태, 세션 캐시, rate limit 카운터 |
| Vectorize | 벡터 인덱스 — RAG 시맨틱 검색, 유사 시나리오 |
| GCS | 임시 PDF 청크 업로드 → Gemini 처리 후 삭제 |
Cron 스케줄러
실행 주기
매분 실행 · DynamicScheduler DO → DB-driven 30+ handlers
주요 작업
Stale job 복구, 임베딩 배치 처리, KOBIS 동기화, 사용량 집계, 만료 정리
특징
DB에서 handler 목록/주기 읽기 → 런타임 동적 스케줄링 (코드 배포 불필요)