SEOJing F3 발표 PPTX export와 TTS bridge 검증#32
Conversation
|
Warning Review limit reached
More reviews will be available in 49 minutes and 3 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
Walkthrough코드펜스 상태 추적을 도입해 MDX/Markdown에서 프리젠테이션 씬을 추출하고 manifest를 빌드한 뒤 CLI 스크립트로 manifest.json과 PPTX를 생성합니다. 관련 TTS 연동, 단위 테스트, 문서와 PresentationView/PostQaPanel 관련 UI·테스트 개선이 포함되어 있습니다. ChangesPPTX 내보내기와 프리젠테이션 매니페스트
PostQaPanel 컴포넌트 수명 주기 개선
PresentationView 렌더링/스타일 단순화
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
seojing | a349a17 | Jun 08 2026, 04:13 PM |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/src/shared/presentation/presentation-export.ts`:
- Around line 78-81: Extract the duplicate CodeFenceState interface and
nextCodeFenceState function into a single shared utility module (e.g., a
code-fence utility) and export them; then remove the local definitions and
import the shared CodeFenceState and nextCodeFenceState in the modules that
currently duplicate them so both use the same implementation; keep the function
signature and behavior unchanged, export the interface and function from the new
module, update imports in the files that previously declared them, and run type
checks to ensure no API or typing regressions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 61f2d47f-fb9c-4a17-9686-791c07d4d00e
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (7)
apps/web/package.jsonapps/web/scripts/export-presentation-pptx.tsapps/web/src/shared/presentation/presentation-export.test.tsapps/web/src/shared/presentation/presentation-export.tsapps/web/src/shared/tts/tts-artifacts.test.tsapps/web/src/shared/tts/tts-artifacts.tsdocs/seojing-pptx-tts-bridge-spike.md
662d35a to
0bfe78f
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/src/shared/presentation/presentation-export.ts`:
- Around line 268-277: The regex in inferLayoutHint allows unintended matches
because `<pre` and `data-code-block` lack boundaries; update the pattern inside
inferLayoutHint (the branch that currently uses
/(?:`{3,}|~{3,})|<pre|data-code-block/) to require boundaries for the HTML tag
and attribute/token (e.g. use `<pre\b` to avoid matching `<prefix` and
`\bdata-code-block\b` to avoid matching `data-code-blocks`), then run tests to
ensure code, image, and other layout detections still behave as expected.
- Around line 179-189: The current extractPresentationScenes code forces
duplicateCount to 0 for headingLevel===1 and never updates seenIds, causing
multiple H1s to share the same baseId; change the logic so duplicateCount =
seenIds.get(baseId) ?? 0 for all heading levels, always increment
seenIds.set(baseId, duplicateCount + 1) after computing duplicateCount, and
compute headingId as duplicateCount === 0 ? baseId : `${baseId}-${duplicateCount
+ 1}` so the second instance becomes `-2`. Also harden findTtsBridgeForScene so
it only matches title TTS bridges for scene.kind === "title" (e.g., compare
titleId when scene.kind === "title") and only matches section bridges for
scene.kind === "section" (compare sectionId), avoiding attaching section bridges
to title scenes; update matching order/conditions accordingly for correct TTS
pairing.
In `@apps/web/src/widgets/post-qa/PostQaPanel.tsx`:
- Around line 102-105: The remount via key in PostQaPanel causes requestSeq
increments to occur only on the new instance so in-flight requests from the old
instance can still complete and trigger side effects (safeWriteLog /
seojing:qa-interaction); remove the artificial remount (avoid using key on
PostQaPanelInner) and instead cancel in-flight requests on unmount inside
PostQaPanelInner by creating an AbortController for each request (attach its
signal to fetch/async calls), call controller.abort() in the component cleanup,
and ensure requestSeq and any side-effecting handlers (requestSeq, safeWriteLog,
seojing:qa-interaction) are bound to the same instance so aborted requests never
run their completion side effects.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: ad52d20f-868e-4452-8979-7c37c1dd7a67
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (9)
apps/web/package.jsonapps/web/scripts/export-presentation-pptx.tsapps/web/src/shared/lib/code-fence.tsapps/web/src/shared/presentation/presentation-export.test.tsapps/web/src/shared/presentation/presentation-export.tsapps/web/src/shared/tts/tts-artifacts.test.tsapps/web/src/shared/tts/tts-artifacts.tsapps/web/src/widgets/post-qa/PostQaPanel.tsxdocs/seojing-pptx-tts-bridge-spike.md
✅ Files skipped from review due to trivial changes (1)
- docs/seojing-pptx-tts-bridge-spike.md
🚧 Files skipped from review as they are similar to previous changes (3)
- apps/web/src/shared/tts/tts-artifacts.test.ts
- apps/web/src/shared/presentation/presentation-export.test.ts
- apps/web/scripts/export-presentation-pptx.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
apps/web/src/shared/lib/code-fence.test.ts (1)
4-21: ⚡ Quick win엣지 케이스 테스트를 추가하면 견고성이 향상됩니다.
현재 테스트는 핵심 동작을 잘 검증하지만, 다음 엣지 케이스를 추가하면 TTS/프리젠테이션 파싱의 정확성을 더 보장할 수 있습니다:
- 선행 공백:
" ```ts"같은 들여쓰기된 펜스 마커 (정규식^\s*가 허용)- 닫는 펜스 뒤 trailing 콘텐츠:
"``` comment"같은 경우 펜스가 닫히지 않아야 함 (정규식\s*$요구사항)- 더 긴 닫는 펜스: 5개 백틱이 3개 백틱 펜스를 닫는 경우 (
length >= current.length조건)🧪 추천 테스트 케이스 예시
+ it("allows leading whitespace before fence markers", () => { + const opened = nextCodeFenceState(null, " ```js"); + expect(opened).toEqual({ char: "`", length: 3 }); + expect(nextCodeFenceState(opened, " ```")).toBeNull(); + }); + + it("does not close fence when closing marker has trailing content", () => { + const opened = nextCodeFenceState(null, "```"); + const stillOpen = nextCodeFenceState(opened, "``` some comment"); + expect(stillOpen).toEqual(opened); + expect(nextCodeFenceState(stillOpen, "```")).toBeNull(); + }); + + it("closes fence with longer marker", () => { + const opened = nextCodeFenceState(null, "```ts"); + expect(nextCodeFenceState(opened, "`````")).toBeNull(); + });🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/shared/lib/code-fence.test.ts` around lines 4 - 21, Add edge-case tests to apps/web/src/shared/lib/code-fence.test.ts for nextCodeFenceState: include a test that ensures indented fence markers like " ```ts" still open/close (leading whitespace allowed), a test that verifies a closing marker with trailing content e.g. "``` comment" does NOT close the fence (requires closing marker to be followed only by optional whitespace), and a test that a longer closing marker (e.g. "`````") can close a shorter opened fence (length >= current.length should close); name the tests clearly and use nextCodeFenceState to assert opened vs still-open vs closed states.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/web/src/widgets/post-qa/PostQaPanel.tsx`:
- Around line 232-237: The finally block currently skips setPending(false) when
requestSeq.current !== currentRequestSeq, causing pending to stay true after
slug-triggered aborts; update the finally in PostQaPanel so it always clears the
pending state (call setPending(false) unconditionally) and only reset
requestAbortController.current when requestSeq.current === currentRequestSeq to
avoid clobbering newer requests; reference requestSeq, currentRequestSeq,
requestAbortController, and setPending in your change.
---
Nitpick comments:
In `@apps/web/src/shared/lib/code-fence.test.ts`:
- Around line 4-21: Add edge-case tests to
apps/web/src/shared/lib/code-fence.test.ts for nextCodeFenceState: include a
test that ensures indented fence markers like " ```ts" still open/close
(leading whitespace allowed), a test that verifies a closing marker with
trailing content e.g. "``` comment" does NOT close the fence (requires closing
marker to be followed only by optional whitespace), and a test that a longer
closing marker (e.g. "`````") can close a shorter opened fence (length >=
current.length should close); name the tests clearly and use nextCodeFenceState
to assert opened vs still-open vs closed states.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: a4f87710-8b2a-4685-80f1-9d7878cb88f0
📒 Files selected for processing (6)
apps/web/src/shared/lib/code-fence.test.tsapps/web/src/shared/presentation/presentation-export.test.tsapps/web/src/shared/presentation/presentation-export.tsapps/web/src/widgets/post-qa/PostQaPanel.test.tsxapps/web/src/widgets/post-qa/PostQaPanel.tsxapps/web/src/widgets/presentation/PresentationView.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- apps/web/src/shared/presentation/presentation-export.test.ts
- apps/web/src/shared/presentation/presentation-export.ts
작업 배경
F3 티켓은 단순히 PPTX 생성 가능성만 확인하는 것이 아니라, 기존 article slice를 발표용 scene으로 재구성하고 slide별/scene별 TTS script bridge를 연결할 수 있는지 검증하는 spike입니다.
변경 내용
pptxgenjs기반 발표 export 스크립트 추가pnpm --filter @app/web run export:presentation -- --slug <slug>manifest.json과.pptx생성데모 방법
생성 예시:
/tmp/seojing-presentation-export-smoke/study/backend/day1/manifest.json/tmp/seojing-presentation-export-smoke/study/backend/day1/study__backend__day1.pptx검증
pnpm --filter @app/web exec vitest run src/shared/presentation/presentation-export.test.ts src/shared/tts/tts-artifacts.test.ts— 11 tests passpnpm --filter @app/web run lint— passpnpm --filter @app/web run build— passstudy/backend/day1→ 43 scenes / 43 slides / 43 notes 확인git diff --check— pass메모
Summary by CodeRabbit
새로운 기능
문서
개선사항
테스트