Skip to content

refactor: mobile-friendly split + compact 전략으로 전환 #103

@greenheadHQ

Description

@greenheadHQ

Summary

현재 atomic split 전략(카드당 1 fact, max 80자, 1 Cloze)을 mobile-friendly 전략으로 전환한다. split/compact/skip 삼자택일 operation 모델을 도입하여, LLM이 카드 특성에 맞는 최적 작업을 판정한다. 과도한 분할로 인한 학습 효과 저하 문제를 해결한다.

Context

  • 현 상태: SuperMemo "Minimum Information Principle"을 엄격하게 적용하여 카드를 극도로 잘게 분할함 (예: CSS 명시도 1매 → 11매, DNS 1매 → 10매)
  • 문제점: 이력 목록의 대부분이 "rejected" 상태. 과도한 분할이 오히려 학습 효과를 저하시킴
  • 필요성: "모바일 AnkiDroid에서 스크롤 없이 표시"를 기준으로, split/compact/skip을 LLM이 판단하는 유연한 전략 필요
  • 관련 이슈: refactor: split을 atomic하게 하지 말고, mobile-friendly하게만 스플릿하도록 하면 좋을듯? #102 (원본 제안)

Related Commits

  • fe8c118 — refactor: Hard Split 제거 및 Split 단일화 (refactor: Hard Split 제거 및 Split 단일화 #45)
  • 0338005 — docs: mobile-friendly split + compact 디자인 스펙 초안
  • 62ef2d4 — docs: 2차 spec review suggestion 반영 및 status 업데이트
  • 038b2fd — docs: mobile-friendly split + compact 구현 계획 작성

Affected Files

File Role Required Change
packages/core/src/parser/text-length.ts 신규 HTML/Cloze/Callout 제거 후 순수 텍스트 길이 계산 유틸리티
packages/core/src/gemini/validator.ts Zod 검증 discriminated union 스키마 (split/compact/skip) + 레거시 shouldSplit 폴백
packages/core/src/splitter/atomic-converter.ts 트리거 판정 analyzeForOptimization (Cloze 수 OR 텍스트 길이 초과)
packages/core/src/gemini/prompts.ts LLM 프롬프트 SYSTEM_PROMPT 전면 개편 (atomic → mobile-friendly), buildOptimizationPrompt
packages/core/src/gemini/client.ts LLM 클라이언트 requestCardOptimization, estimateOptimizationCost
packages/core/src/prompt-version/types.ts 타입/상수 REJECTION_REASONS 업데이트, PromptConfig deprecated
packages/server/src/routes/split.ts API 라우트 operation 분기 (preview/apply), compact apply 경로
packages/server/src/routes/cards.ts API 라우트 needsOptimization, filter alias
packages/server/src/history/store.ts 이력 저장소 operation 컬럼, markGenerated compact 분기
packages/web/src/pages/SplitWorkspace.tsx UI 메인 operation별 프리뷰 뷰, compact diff 뷰
packages/web/src/pages/CardBrowser.tsx UI canSplitneedsOptimization
packages/web/src/components/card/AuditReportPanel.tsx 신규 Compact 감사 보고서 패널
packages/web/src/components/card/CompactDiffView.tsx 신규 Compact 2-pane diff 뷰

Proposed Changes

Core Layer

  • computeTextLength 유틸리티 추가 (HTML/Cloze/Callout 제거 후 순수 텍스트 길이)
  • Zod discriminated union 스키마 (operation: split | compact | skip) + 레거시 shouldSplit 폴백 변환
  • analyzeForOptimization — Cloze 수 OR 텍스트 길이(500자) 초과 시 트리거
  • SYSTEM_PROMPT 전면 개편: atomic → mobile-friendly, operation 판정 가이드, compact 지침
  • buildOptimizationPrompt + OPTIMIZATION_RESPONSE_FORMAT
  • requestCardOptimization, estimateOptimizationCost
  • REJECTION_REASONS 업데이트 (char-exceeded 제거, over-compressed/info-lost 추가)

Server Layer

  • systemPrompt 해시 기반 마이그레이션 (구버전 자동 갱신)
  • 기존 프롬프트 버전 archived + 새 기본 버전 생성
  • routes/cards.tsneedsOptimization, filter alias
  • routes/split.ts — operation 분기 (preview: split/compact/skip, apply: split/compact)
  • History store — operation 컬럼, markGenerated/markApplied compact 분기

Web Layer

  • OptimizationPreviewResult discriminated union 타입
  • AuditReportPanel (preserved/removed/transformed 컬러 태그)
  • CompactDiffView (원본 vs compact 2-pane)
  • SplitWorkspace operation 분기 + CardBrowser needsOptimization
  • History 페이지 operation 배지 + compact 상세 뷰

Notes

  • 디자인 스펙: docs/superpowers/specs/2026-03-22-mobile-friendly-split-design.md
  • 구현 계획: docs/superpowers/plans/2026-03-22-mobile-friendly-split.md
  • 기존 함수명(requestCardSplit 등)은 deprecated wrapper로 유지하여 하위 호환 보장
  • feat(web): Validate 탭 — All-in-One 카드 건강 허브 #93 (Validate 탭)의 Phase 2에서 requestCardSplit 재사용 → 이 리팩토링 완료 후 requestCardOptimization으로 전환 필요
  • MAX_TEXT_LENGTH = 500은 모바일 AnkiDroid 실제 테스트 후 튜닝 예정

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:core핵심 도메인 로직 및 공통 라이브러리area:serverHono API 서버 및 라우트area:webReact 웹 애플리케이션enhancementNew feature or requestpriority:medium다음 작업 주기에 처리할 작업

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions