Skip to content

Commit 32f36ae

Browse files
committed
feat : Add DB guard script and Ultraplan/DeepTutor plan
Add an e2e DB guard script and a planning doc. apps/web/e2e/guard-check.ts verifies importing helpers/db.ts fails unless a _test DB is used (logs status and exits with appropriate codes). plan/ultraplan-completion-and-deeptutor.md documents Ultraplan remaining work (including writing auto-tag-suggestions tests and committing the guard script), coverage targets, and a detailed assessment of integrating DeepTutor features (Visualize, Math Animator, Deep Solve) with recommended priorities and integration paths.
1 parent b1ae5f7 commit 32f36ae

2 files changed

Lines changed: 247 additions & 0 deletions

File tree

apps/web/e2e/guard-check.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import("./helpers/db.ts")
2+
.then(() => {
3+
console.error("GUARD FAILED — import succeeded for non-test DB");
4+
process.exit(1);
5+
})
6+
.catch((err: unknown) => {
7+
const msg = err instanceof Error ? err.message : String(err);
8+
if (msg.includes("_test")) {
9+
console.log("GUARD OK: " + msg.slice(0, 120));
10+
process.exit(0);
11+
}
12+
console.error("GUARD UNEXPECTED: " + msg);
13+
process.exit(2);
14+
});
Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
# Ultraplan 완료 + DeepTutor Feature 평가
2+
3+
> 작성일: 2026-04-12 | 상태: 대기 (실행 전)
4+
5+
## Context
6+
7+
ultraplan (품질 게이트 8단계) 구현이 **93.75% 완료**. 남은 갭:
8+
1. `auto-tag-suggestions.test.tsx` 컴포넌트 테스트 미작성 (6단계 중 1/4)
9+
2. `guard-check.ts` 미커밋 (untracked)
10+
11+
추가로 [cskwork/DeepTutor](https://github.com/cskwork/DeepTutor)의 Manim 등 기능을 hwp-to-html에 통합할 가능성 평가.
12+
13+
---
14+
15+
## Part A: Ultraplan 잔여 작업
16+
17+
### A1. `auto-tag-suggestions.test.tsx` 작성
18+
19+
**생성 파일**: `apps/web/src/components/items/__tests__/auto-tag-suggestions.test.tsx`
20+
21+
코드베이스 **최초의 React 컴포넌트 테스트**. 기존 인프라:
22+
- `@testing-library/react` 16.3.2 설치됨 (미사용 상태)
23+
- vitest.config.ts: `environment: "node"` → 파일 최상단 `// @vitest-environment jsdom` pragma 필수
24+
- tRPC mock 패턴: `vi.mock("@/lib/trpc", ...)` (라우터 테스트에서 사용 중)
25+
26+
**대상 컴포넌트**: `apps/web/src/components/items/auto-tag-suggestions.tsx` (255 LOC)
27+
- Props 12개: bodyLatex, schoolLevel, grade, itemType?, formulaType?, solutionSteps?, selectedSkillIds[], selectedStandardIds[], selectedMisconceptionIds[], onSkillSelect, onStandardSelect, onMisconceptionSelect
28+
- tRPC 훅: `trpc.item.suggestMetadata.useQuery(input, { enabled: debouncedBody.length > 0 })`
29+
- 내부 디바운스: `useDebouncedValue(bodyLatex, 500)``useState(value)`로 초기값 = bodyLatex이므로 첫 렌더에서 타이머 불필요
30+
- 하위 컴포넌트: BloomBadge, SuggestionSection, Chip, SkeletonBlock
31+
32+
#### 테스트 케이스 5개
33+
34+
| # | 테스트 | 검증 방법 |
35+
|---|--------|----------|
36+
| 1 | bodyLatex 빈 문자열 → null 렌더링 | `container.innerHTML === ""` |
37+
| 2 | isLoading → 스켈레톤 표시 | `animate-pulse` 클래스 존재 확인 |
38+
| 3 | data 반환 → 칩 렌더링 | skill/standard/misconception 텍스트 존재 |
39+
| 4 | 칩 클릭 → onSkillSelect 콜백 호출 | `fireEvent.click` → vi.fn() 호출 확인 |
40+
| 5 | 선택된 항목 → 체크마크(✓) 표시 | `\u2713` 문자 존재 확인 |
41+
42+
#### Mock 구조
43+
44+
```typescript
45+
// tRPC 모듈 mock
46+
vi.mock("@/lib/trpc", () => ({
47+
trpc: {
48+
item: {
49+
suggestMetadata: {
50+
useQuery: vi.fn(),
51+
},
52+
},
53+
},
54+
}));
55+
56+
// 응답 데이터
57+
const mockData = {
58+
skills: [{ id: "sk1", title: "일차방정식", similarity: 0.92 }],
59+
standards: [{ id: "std1", code: "M8-01", title: "표준1" }],
60+
misconceptions: [{ id: "mc1", title: "부호 오류", typicalError: "부호 반전" }],
61+
bloomLevel: 3,
62+
};
63+
```
64+
65+
#### 참고 파일
66+
- 컴포넌트: `apps/web/src/components/items/auto-tag-suggestions.tsx:47-179`
67+
- tRPC mock 선례: `apps/web/src/server/routers/__tests__/item.router.test.ts:19-64`
68+
- BLOOM_LEVEL 상수: `packages/shared/constants/index.ts`
69+
- vitest 설정: `apps/web/vitest.config.ts` (jsdom pragma, path alias `@`)
70+
71+
---
72+
73+
### A2. `guard-check.ts` 커밋
74+
75+
**파일**: `apps/web/e2e/guard-check.ts` (14줄, 이미 완성됨)
76+
77+
DB 가드 검증 스크립트 — `helpers/db.ts` import 시 `_test` suffix 가드가 정상 작동하는지 확인.
78+
79+
```bash
80+
git add apps/web/e2e/guard-check.ts
81+
# A1 테스트 파일과 함께 커밋
82+
git commit -m "test: add auto-tag-suggestions component test and track guard-check script"
83+
```
84+
85+
---
86+
87+
### A3. 커버리지 임계선 (참고)
88+
89+
현재 (`apps/web/vitest.config.ts:34-39`):
90+
- lines: 21, statements: 20, functions: 13, branches: 17
91+
92+
ultraplan 목표: services 60%, routers 80%, 전체 45%
93+
94+
**권장**: A1 완료 후 커버리지 실행하여 수치 변화 확인. 의미 있는 상승 시 +1~2 bump 고려. 목표치(45%)는 추가 테스트 작성 후에 적용.
95+
96+
---
97+
98+
## Part B: DeepTutor Feature 평가
99+
100+
### DeepTutor 개요
101+
102+
[HKUDS/DeepTutor](https://github.com/HKUDS/DeepTutor) (v1.0.2, Apache-2.0) — Agent-Native 개인화 튜터링 플랫폼.
103+
- Python 3.11+ / Next.js 16
104+
- Two-layer 플러그인 모델: Tools + Capabilities
105+
- ~200k LOC 아키텍처 재작성 (v1.0.0)
106+
107+
### Capability 분석
108+
109+
| Capability | 설명 | hwp-to-html 관련성 | 구현 난이도 |
110+
|-----------|------|-------------------|-----------|
111+
| **Math Animator** | Manim 기반 5-agent 파이프라인 (분석→설계→코드생성→렌더→요약). 비디오/이미지 출력 | **높음**`SolutionMethod.visual` 활용 | 높음 (Docker+ffmpeg+LaTeX) |
112+
| **Visualize** | SVG/Chart.js 3단계 파이프라인 (분석→생성→리뷰) | **높음** — 경량, 즉시 적용 가능 | 낮음-중간 |
113+
| **Deep Solve** | 멀티에이전트 문제풀이 (Plan→ReAct→Write), RAG/웹검색/코드실행 | **중간** — generation.service 보완 | 중간 |
114+
| **Deep Question** | 퀴즈 생성 | 낮음 — 이미 generation.service 존재 | 중간 |
115+
| **Guided Learning** | 구조화 학습 여정 | 중간 — 학생 경험 개선용 | 높음 |
116+
| **Knowledge Hub** | RAG 지식 베이스 | 낮음 — pgvector+Meilisearch 구축됨 | 낮음 |
117+
| **Co-Writer** | AI 협업 마크다운 에디터 | 낮음 | 중간 |
118+
119+
### Effort/Impact 매트릭스
120+
121+
```
122+
High Impact
123+
|
124+
Visualize | Math Animator
125+
(Low Eff.) | (High Eff.)
126+
|
127+
─────────────┼─────────────
128+
|
129+
Deep Solve | Guided Learning
130+
(Med Eff.) | (High Eff.)
131+
|
132+
Low Impact
133+
```
134+
135+
### Top 3 통합 후보 상세
136+
137+
#### 1. Visualize (SVG/Chart.js) — 추천: 1순위
138+
139+
**이유**: 인프라 추가 불필요, 스키마 변경 없이 시작 가능, 즉각적 가치.
140+
141+
**통합 경로**:
142+
- `services/math-ai/app/routers/visualize.py` 추가 — 3단계 파이프라인
143+
- 입력: LaTeX 본문 → LLM이 SVG/Chart.js 코드 생성 → 리뷰/최적화
144+
- 출력: SVG 문자열 또는 Chart.js spec JSON
145+
- 저장: `Solution.steps` JSON에 `{ type: "svg", content: "..." }` 추가
146+
- 프론트엔드: `apps/web/src/components/items/visual-solution.tsx` — SVG inline 렌더 + Chart.js 초기화
147+
- tRPC: `item.generateVisualization` mutation → math-ai `/visualize` 호출
148+
149+
**예상 기간**: 1주 (기본), 2주 (Chart.js 인터랙션 포함)
150+
151+
**기존 자산 활용**:
152+
- `anthropic-generation.service.ts` — LLM 호출 패턴
153+
- `services/math-ai/app/services/sympy_solver.py` — 수식 파싱 재사용
154+
- DeepTutor `deeptutor/capabilities/visualize.py` — 파이프라인 설계 참조
155+
156+
#### 2. Math Animator (Manim) — 추천: 2순위
157+
158+
**이유**: 높은 시각적 영향력. `SolutionMethod.visual` enum이 이미 존재.
159+
160+
**통합 경로**:
161+
- `services/math-ai/app/routers/animate.py` — 5-agent 파이프라인
162+
- ConceptAnalysis → ConceptDesign → CodeGenerator → ManimRender → Summary
163+
- DB 마이그레이션: `Solution` 모델에 `videoUrl String?` 추가
164+
- 인프라 옵션:
165+
- (a) Docker sidecar (Manim + LaTeX + ffmpeg 프리인스톨) — 추천
166+
- (b) 전용 렌더 워커 (BullMQ 비동기 패턴, bulk upload과 동일)
167+
- 객체 스토리지: S3/R2에 비디오 저장, `videoUrl`에 URL 기록
168+
- 프론트엔드: `visual-solution-video.tsx` — lazy-load 비디오 플레이어
169+
- 핵심 포인트: DeepTutor의 `RetryManager` 패턴 필수 (Manim 코드 생성은 불안정)
170+
171+
**예상 기간**: 2-4주
172+
173+
**DeepTutor 참조 코드**:
174+
- `deeptutor/capabilities/math_animator.py` — capability 진입점
175+
- `deeptutor/agents/math_animator/pipeline.py` — 5-agent 오케스트레이션
176+
- `deeptutor/agents/math_animator/renderer.py` — Manim 렌더 서비스
177+
- `deeptutor/agents/math_animator/retry_manager.py` — 코드 재생성 로직
178+
179+
**리스크**: Manim 시스템 의존성(LaTeX 배포판, ffmpeg, Cairo), 코드 생성 불안정성
180+
181+
#### 3. Deep Solve (멀티에이전트 풀이) — 추천: 3순위
182+
183+
**이유**: 기존 generation.service의 SymPy/LLM 전략을 보완하는 고급 풀이 모드.
184+
185+
**통합 경로**:
186+
- `generation.service.ts``"deep-solve"` 전략 추가 (기존 `"sympy"`, `"llm"` 옆)
187+
- `services/math-ai/app/routers/solve.py` — Plan→ReAct→Write 파이프라인
188+
- Plan: 문제 구조 분석
189+
- ReAct: SymPy CAS + 웹 검색을 도구로 사용하여 풀이
190+
- Write: 풀이 단계 포맷팅
191+
- 기존 `sympy_solver.py``verify_answer()`, `solve_equation()`을 ReAct 루프 내 도구로 활용
192+
- 스키마 변경 없음 — `Solution.steps` JSON 동일 포맷 사용
193+
194+
**예상 기간**: 1-2주
195+
196+
**DeepTutor 참조 코드**:
197+
- `deeptutor/capabilities/deep_solve.py` — capability 진입점
198+
- `deeptutor/agents/solve/main_solver.py` — 멀티에이전트 오케스트레이터
199+
200+
---
201+
202+
### 의존성 결정 사항 (구현 전 확정 필요)
203+
204+
1. **객체 스토리지**: Math Animator 비디오 저장용 — S3, R2, 또는 로컬(dev)
205+
2. **LLM 프로바이더**: agent 파이프라인용 — 현재 Z.ai/GLM-4.7 또는 Claude 직접 호출
206+
3. **Manim 렌더링 방식**: 동기 vs 비동기 (BullMQ 큐 패턴 이미 존재)
207+
4. **라이선스**: DeepTutor는 Apache-2.0 — 코드 참조/포팅 가능
208+
209+
---
210+
211+
## 실행 순서
212+
213+
```
214+
[즉시] A1 → auto-tag-suggestions.test.tsx 작성 + 테스트 통과
215+
[즉시] A2 → guard-check.ts 커밋 (A1과 함께)
216+
[즉시] B → docs/deeptutor-feature-assessment.md 작성
217+
[다음 스프린트] Visualize SVG/Chart.js 프로토타입
218+
[2-4주] Math Animator Docker 설정 + 기본 파이프라인
219+
[2-4주] Deep Solve 전략 추가
220+
```
221+
222+
## 검증
223+
224+
```bash
225+
# A1 테스트 통과
226+
pnpm --filter @hwp/web vitest run src/components/items/__tests__/auto-tag-suggestions.test.tsx
227+
228+
# 전체 테스트 회귀 확인
229+
pnpm --filter @hwp/web vitest run
230+
231+
# 커버리지 변화 확인
232+
pnpm --filter @hwp/web test:coverage
233+
```

0 commit comments

Comments
 (0)