fix: Inbox 纯文本自动转换为 TipTap JSON (closes #83)#86
Merged
Conversation
Added storageKey column to echoe_media table for dynamic URL generation.
Changes:
- Added storageKey varchar(500) column to echoe_media schema
- Generated migration 0001_tired_forge.sql
- Column will store storage key format: echoe-media/{uid}/{filename}
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Modified uploadMedia method to save storageKey to database
- storageKey format: echoe-media/{uid}/{filename}
- Existing URL generation logic preserved (returns URL on upload)
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Added url field to EchoeMediaDto (optional, expires in 6 hours) - Modified listMedia to call generateAccessUrl for each record with storageKey - Handles missing storageKey gracefully (backwards compatibility) - Logs warning if URL generation fails Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Added getMediaMetadata method to EchoeMediaService that returns metadata with dynamic URL - Added GET /api/v1/media/:filename/metadata endpoint to controller - Returns EchoeMediaDto with temporary access URL (6 hour expiry) - Validates user ownership and handles missing storageKey gracefully - Preserves existing getMedia file-serving functionality Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Audited all media-related endpoints and methods - Verified all metadata endpoints use dynamic URL generation: * GET / (listMedia) - returns URLs * GET /:filename/metadata (getMediaMetadata) - returns URL * POST /upload (uploadMedia) - returns URL - File-serving endpoint (GET /:filename) serves buffers as designed - No additional endpoints require updates - All media URLs now use storageKey + generateAccessUrl pattern Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Add storageKey field to EchoeMediaDto interface in packages/dto to include the storage key used for dynamic URL generation. This field was already stored in the database but was missing from the DTO. Fixes #82 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- POST /api/v1/import/apkg endpoint already implemented - Converts Anki notes to Echoe format with field normalization - Parses Anki templates (qfmt, afmt) and stores HTML content - Parses CSS from models and applies to notes - Creates notes in database with batch inserts - Creates deck/folder structure from Anki decks - Fixed missing storageKey field in EchoeMediaDto Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Verified that review history import is fully implemented in the Echoe import service: - Revlog parsing integrated into importApkg() pipeline - Converts Anki revlog entries to Echoe FSRS review records - Preserves original timestamps from Anki revlog IDs - Maintains interval and ease factor data with proper FSRS conversion - All tests passing (8/8 in echoe-import.service.test.ts) - Typecheck passes for both server and web Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Upload media files BEFORE importing notes to get filename mapping - Build mapping from original filenames to stored filenames (timestamp-hash format) - Update replaceMediaReferences() to handle both [sound:...] and <img src="..."> patterns - Replace media references with stored filenames in note content - Support common media types: images (jpg, png, gif, svg), audio (mp3, wav, ogg), video (mp4, webm) - Typecheck passes Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Add .apkg file format validation (ZIP structure check) - Add corrupted SQLite database error handling with integrity checks - Add graceful handling for missing/corrupted media files - Improve error messages with user-friendly suggestions - Add detailed error categorization (general, media, etc.) - Update frontend to display error details with collapsible list - Use shared ImportResultDto and ImportErrorDetailDto types Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- 在 CreateInboxDto 和 UpdateInboxDto 中添加 frontJson 和 backJson 可选字段 - 在 InboxService 中添加 convertPlainTextToTipTapJson() 方法用于纯文本转换 - 更新 InboxService 的 create 和 update 方法,当收到 JSON 时直接序列化为 HTML,当收到纯文本时保持原样 - JSON 格式优先于纯文本(当两者都提供时使用 JSON) - 添加完整的单元测试覆盖转换逻辑 - 所有测试通过,typecheck 通过 Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- 将 CreateInboxDialog 中的 textarea 替换为 RichTextEditor - 添加 frontJson 和 backJson 状态来跟踪 TipTap JSON 格式 - RichTextEditor 的 onChange 回调同时返回 HTML 和 JSON - 提交时将 JSON 格式内容传递到 API(通过已更新的 CreateInboxDto) - 支持从剪贴板粘贴富文本(RichTextEditor 内置支持) - Typecheck passes Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- 将 EditInboxDialog 中的 textarea 替换为 RichTextEditor - 添加 frontJson 和 backJson 状态来跟踪 TipTap JSON 格式 - RichTextEditor 加载现有内容(支持纯文本和 HTML) - RichTextEditor 自动处理纯文本内容(RichTextRenderer 内部转换) - 提交时将 JSON 格式内容传递到 API - 支持从剪贴板粘贴富文本(RichTextEditor 内置支持) - Typecheck passes Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- 添加 truncateContent 辅助函数用于截断 HTML 内容为纯文本预览 - 在 Inbox 列表中使用 truncateContent 显示内容摘要(前 100 字符) - 自动去除 HTML 标签,显示纯文本预览 - 对于纯文本历史数据,truncateContent 能正确处理 - 添加 line-clamp-2 CSS 类限制显示为最多 2 行 - Typecheck passes Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Added RichTextRenderer import to inbox-page.tsx - Updated ConvertToCardDialog to display rich text preview of front and back content - Expanded dialog width to max-w-2xl and added scrolling for long content - Rich text content is already preserved during conversion (backend uses HTML format) Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
- Modify inbox schema to store front/back as JSON columns - Update InboxService to store JSON directly instead of converting to HTML - Add convertToPlainText method for card conversion (serializes JSON to plain text) - Update InboxToCardController to use convertToPlainText when building note fields - Update DTOs to accept JSON or string types - Add tests for JSON storage behavior - Generate migration for schema change Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- InboxService.create() 方法现在会将纯文本 front/back 转换为 TipTap JSON 格式 - InboxService.update() 方法同样支持纯文本自动转换 - 如果提供了 frontJson/backJson,则优先使用 JSON(保持原有行为) - 新增单元测试验证纯文本转换路径 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove redundant front/back HTML string state from CreateInboxDialog - Remove redundant front/back HTML string state from EditInboxDialog - Update RichTextEditor onChange to only set frontJson/backJson - Add helper functions to handle content (string | JSON) conversion - Make front/back optional in DTOs when JSON is provided Closes #85 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- 注入 InboxService 并使用 convertToPlainText 方法转换 front/back 字段 - 修复 getL1Context 中的相似度计算,正确处理 JSON 格式内容 - 修复 buildPrompt 中的 AI 提示构建,正确传递纯文本内容 - 修复 formatInboxContent 中的内容格式化 - 修复 generateDailyReport 中的日常报告生成 - 修复 organizeInbox 中的原始内容提取(包括 fallback 路径) - 更新测试 mock 数据使用 TipTap JSON 格式 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Changes
apps/server/src/services/inbox.service.ts: 修改 create() 和 update() 方法,添加 convertPlainTextToTipTapJson 调用apps/server/src/__tests__/inbox.service.test.ts: 新增 5 个测试用例验证纯文本转换Test plan
🤖 Generated with Claude Code