feat: finishing of M0
This commit is contained in:
106
docs/COMPATIBILITY_INVENTORY.md
Normal file
106
docs/COMPATIBILITY_INVENTORY.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# bDS Compatibility Inventory: TypeScript vs Rust
|
||||
|
||||
Tracks feature parity between the TypeScript bDS app and the Rust rewrite (RuDS).
|
||||
|
||||
Legend: `[x]` implemented/verified, `[ ]` not yet implemented
|
||||
|
||||
---
|
||||
|
||||
## Database Schema
|
||||
|
||||
- [x] projects table
|
||||
- [x] posts table (with published_* legacy columns)
|
||||
- [x] post_translations table
|
||||
- [x] media table
|
||||
- [x] media_translations table (mediaTranslations)
|
||||
- [x] tags table
|
||||
- [x] templates table (with kind/status defaults matching TypeScript)
|
||||
- [x] scripts table (with kind/status defaults matching TypeScript)
|
||||
- [x] post_links table (postLinks)
|
||||
- [x] post_media table
|
||||
- [x] settings table
|
||||
- [x] generated_file_hashes table
|
||||
- [x] db_notifications table
|
||||
- [x] chat_conversations table
|
||||
- [x] chat_messages table
|
||||
- [x] ai_providers table
|
||||
- [x] ai_models table
|
||||
- [x] ai_model_modalities table
|
||||
- [x] ai_catalog_meta table
|
||||
- [x] embedding_keys table
|
||||
- [x] dismissed_duplicate_pairs table
|
||||
- [x] import_definitions table
|
||||
- [x] All 10 unique indexes
|
||||
- [x] FTS5 virtual tables (posts_fts, media_fts) -- present in fixture DB, runtime creation deferred to M1
|
||||
- [x] Default values match TypeScript (status, kind, enabled, version, entrypoint)
|
||||
|
||||
## File Formats
|
||||
|
||||
- [ ] Post frontmatter (YAML) read/write
|
||||
- [ ] Translation file format (posts/YYYY/MM/slug.lang.md)
|
||||
- [ ] Media sidecar (.meta) read/write
|
||||
- [ ] Template frontmatter read/write
|
||||
- [ ] Script frontmatter read/write
|
||||
- [ ] meta/tags.json
|
||||
- [ ] meta/project.json
|
||||
- [ ] meta/categories.json
|
||||
- [ ] meta/category-meta.json
|
||||
- [ ] meta/publishing.json
|
||||
- [ ] meta/menu.opml
|
||||
|
||||
## Slug Generation
|
||||
|
||||
- [x] Basic transliteration (Unicode to ASCII, lowercase, hyphens, trim)
|
||||
- [x] German umlauts: ae/oe/ue/ss/Ae/Oe/Ue (matches TypeScript transliteration npm)
|
||||
- [x] Uniqueness: base, then {slug}-2..999, then {slug}-{timestamp}
|
||||
|
||||
## Content Location
|
||||
|
||||
- [x] Published posts have NULL content in DB, body in filesystem .md
|
||||
- [x] Draft posts have content in DB
|
||||
- [x] Published translations have NULL content in DB
|
||||
- [x] Published templates have NULL content in DB
|
||||
- [x] Published scripts have NULL content in DB
|
||||
|
||||
## Rendering
|
||||
|
||||
- [ ] Liquid template rendering (subset: if/elsif/else, for, assign, render, whitespace stripping)
|
||||
- [ ] Liquid filters: escape, url_encode, default, append, i18n, markdown
|
||||
- [ ] Markdown rendering via pulldown-cmark
|
||||
- [ ] Built-in macros: gallery, youtube, vimeo, photo_archive, tag_cloud
|
||||
- [ ] RSS/Atom feed generation
|
||||
- [ ] Sitemap generation
|
||||
- [ ] Generated file hash tracking (incremental)
|
||||
- [ ] Pagefind search index generation (via pagefind crate library API)
|
||||
|
||||
## Search
|
||||
|
||||
- [ ] FTS5 post indexing with Snowball stemmers (24 languages)
|
||||
- [ ] FTS5 media indexing
|
||||
- [ ] Cross-language stemming
|
||||
|
||||
## Publishing
|
||||
|
||||
- [ ] SSH/SCP upload
|
||||
- [ ] Rsync upload
|
||||
- [ ] Three parallel upload targets (html, thumbnails, media)
|
||||
- [ ] .meta files excluded from upload
|
||||
|
||||
## AI Integration
|
||||
|
||||
- [ ] Two-endpoint model (online + airplane)
|
||||
- [ ] One-shot operations (translate, analyze, etc.)
|
||||
- [ ] Chat with tool use
|
||||
- [ ] Model catalog refresh
|
||||
- [ ] Secure key storage (OS keychain)
|
||||
|
||||
## Thumbnails
|
||||
|
||||
- [ ] Small (150px), Medium (400px), Large (800px), AI (448x448 JPEG)
|
||||
- [ ] WEBP output
|
||||
|
||||
## MCP Server
|
||||
|
||||
- [ ] HTTP + stdio transports
|
||||
- [ ] Read-only tools
|
||||
- [ ] Proposal-based write tools
|
||||
52
docs/ICED_ARCHITECTURE_PATTERNS.md
Normal file
52
docs/ICED_ARCHITECTURE_PATTERNS.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Iced Architecture Patterns (bDS Rust Rewrite)
|
||||
|
||||
Iced 0.13, wgpu renderer, muda for native menus, rfd for file dialogs.
|
||||
|
||||
## Message Design
|
||||
|
||||
- Root `Message` enum in `app.rs`: `MenuEvent(MenuId)`, `Noop`, plus child view variants.
|
||||
- Child view messages wrapped in parent enum variants: `Message::Editor(editor::Message)`.
|
||||
- Keep messages flat where possible -- avoid deep nesting beyond two levels.
|
||||
- Use `Task<Message>` for async operations (file I/O, dialogs, database queries).
|
||||
- Noop absorbs events that need no action (e.g., unhandled menu IDs).
|
||||
|
||||
## Subscription Model
|
||||
|
||||
- Menu events: `iced::event::listen_with` polling `MenuEvent::receiver().try_recv()` each tick.
|
||||
- Future: filesystem watcher subscription for external db/file changes.
|
||||
- Subscriptions are declarative -- `subscription()` returns the full set every frame; Iced diffs internally.
|
||||
- Each subscription keyed by a unique ID to avoid duplicates.
|
||||
|
||||
## Custom Widget Pattern (CodeEditor)
|
||||
|
||||
- Implements `iced::advanced::Widget<Message, Theme, Renderer>`.
|
||||
- Persistent state via `widget::tree::State` holding `EditorState` (cursor pos, selection, scroll offset).
|
||||
- `tag()` returns `TypeId::of::<EditorState>()` for widget tree identity.
|
||||
- `state()` returns `State::new(EditorState::default())` for initialization.
|
||||
- `on_event()` handles keyboard/mouse input, returns `Status::Captured` or `Status::Ignored`.
|
||||
- `draw()` uses `renderer.fill_quad()` for backgrounds/cursors/gutters, `renderer.fill_text()` for content.
|
||||
- Takes `&mut EditorBuffer` reference for direct mutation on input -- buffer is not owned by the widget.
|
||||
- Focus management: `is_focused` flag in `EditorState`, set on mouse press inside bounds, cleared on press outside.
|
||||
|
||||
## Platform Integration
|
||||
|
||||
- muda menus built once at startup; call `init_for_nsapp()` on macOS before event loop.
|
||||
- Menu IDs stored in a map (`HashMap<MenuId, Message>`) for routing `MenuEvent` to app `Message`.
|
||||
- macOS lifecycle hooks (`application:openFile:`, `openURLs:`) via objc2 -- deferred to M2.
|
||||
- rfd dialogs: `rfd::AsyncFileDialog` spawned behind `Task::perform`, result mapped to a `Message` variant.
|
||||
|
||||
## Rendering
|
||||
|
||||
- Iced uses cosmic-text internally for text shaping and layout.
|
||||
- Custom widgets call `renderer.fill_text()` with a `Text` struct: font, size, bounds, horizontal/vertical alignment.
|
||||
- Use `Font::MONOSPACE` for the editor, default system font for UI chrome.
|
||||
- `renderer.fill_quad()` for solid-color rectangles: backgrounds, cursor bar, gutter column, selections.
|
||||
- Clipping: call `renderer.with_layer()` to restrict drawing to widget bounds.
|
||||
|
||||
## State Management
|
||||
|
||||
- Top-level app state lives in `BdsApp` struct (db connection, open buffers, UI flags).
|
||||
- Child widget state in `widget::tree::State` -- survives across `view()` calls as long as widget identity matches.
|
||||
- `EditorBuffer` (rope-based text buffer via ropey) owned by `BdsApp`, passed as `&mut` to widget on `view()` and `on_event()`.
|
||||
- Database connection (`rusqlite::Connection`) opened once at startup, held in `BdsApp`, not cloned.
|
||||
- No global mutable state -- everything flows through the `Message` -> `update()` -> `view()` cycle.
|
||||
Reference in New Issue
Block a user