프로젝트 타임라인

- (0주)
보고일:
반영일: -
상태: 안정화 및 고도화 단계
지연 (12/11)
오늘
완료
진행중
당초 계획
지연 구간
오늘
마일스톤
주요 이벤트
최근 작업

작업 내역

최근 순 달력: -
날짜 칸 클릭 시 상세 이력 모달
feat (기능)
fix (수정)
refactor
docs
chore
예정

E2E 테스트 대시보드

0개 스위트 · 0개 TC

시스템 워크플로우

Cinology 핵심 파이프라인 · 14 Workers · 10 Queues
처음 보는 분을 위한 한 줄 정리
이 페이지는 "기술 구조"보다 실제 작업 흐름을 먼저 이해하도록 구성했습니다. 특히 협업의 피드백 라운드는 기존의 개별 코멘트 방식과 비교해, "요청 → 검토 → 반영 결정 → 기록"이 한 화면에서 이어지도록 개선했습니다.
시나리오 파이프라인 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
💬 사용자 입력 — Optimistic UI + Background Persist
Optimistic UI
메시지 즉시 화면 표시 → 백그라운드 D1 저장
AbortController
사용자 취소 시 SSE 스트림 즉시 중단 → cleanup
두 가지 모드
Streaming: SSE 실시간 · Background: Queue → WebSocket relay
📡 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)
WorkerPortRoute주요 역할
cinology-api8787api.thengd.com/*Main API — oRPC 30 domains, 268+ handlers, D1, R2, Vectorize, Queue
cinology-auth8789/api/auth/*Better Auth 인증 — 세션, OAuth, 비밀번호
cinology-ai-chat8788/api/rpc/ai/chat/*AI Chat — Agentic Loop V3, Background, HITL, Intent
cinology-scripts-worker8790/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 callPDF 생성 — pdf-lib, split-and-store
Queue Workers (5)
WorkerPortQueue 소비주요 역할
cinology-parse-worker8791parse, vision_reparse, feedback_extractPDF 파싱 — 13-phase, chunk 병렬
cinology-ontology-worker8793ontology지식 그래프 — Entity/Relationship 추출
cinology-analysis-worker8794analysisAI 분석 — 6-category, 4-phase self-requeue
cinology-report-worker8795report리포트 생성 → PDF Worker HTTP 호출
cinology-visual-gen-visual_generation시각 콘텐츠 생성 (experimental)
Queue 토폴로지 (10)
QueueProducerConsumermax_concurrency
parsescripts-worker, apiparse-worker10
vision_reparseapi (admin)parse-worker5
feedback_extractapiparse-worker5
ontologyparse-workerontology-worker5
analysisapi, analysis-workeranalysis-worker5
embeddingapi, ragrag-worker50
patternapirag-worker5
reportapireport-worker10
visual_generationapivisual-gen3
kobis_syncadmin (cron)admin1
Durable Objects (6)
🏠
ScenarioRoom
시나리오별 실시간 WebSocket
🔔
ApprovalNotifier
결재 알림 실시간 전송
👤
UserJobsRoom
사용자별 작업 상태 알림
⏱️
DynamicScheduler
DB-driven Cron 스케줄러
🔑
RateLimiter
API Rate Limiting
💬
ChatSession
AI Chat 세션 상태 관리
외부 서비스
🤖
Gemini AI
파싱 · 분석 · 채팅
☁️
Vertex AI / GCS
PDF→GCS 업로드 후 AI
🎨
FAL AI
이미지 생성 (experimental)
🎬
KOBIS / KMDb
영화 박스오피스 · 메타데이터
🔐
Better Auth
인증 · 세션 · OAuth
📧
Resend
초대/알림 이메일 발송
💰
LiteLLM
AI 비용 추적 · 가격 동기화
데이터 레이어
서비스용도
D1 SQLite주 데이터베이스 — Drizzle ORM, 12 도메인 스키마, 마이그레이션
R2 Object스크립트 PDF, sub-PDF 청크, 파싱 manifest, audit trail, 리포트, 임베딩 배치
KV Key-ValueHITL 상태, 세션 캐시, rate limit 카운터
Vectorize벡터 인덱스 — RAG 시맨틱 검색, 유사 시나리오
GCS임시 PDF 청크 업로드 → Gemini 처리 후 삭제
Cron 스케줄러
실행 주기
매분 실행 · DynamicScheduler DO → DB-driven 30+ handlers
주요 작업
Stale job 복구, 임베딩 배치 처리, KOBIS 동기화, 사용량 집계, 만료 정리
특징
DB에서 handler 목록/주기 읽기 → 런타임 동적 스케줄링 (코드 배포 불필요)