Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
10 KiB
10 KiB
Scratchpad — Collaborative Editor Document Integration
Key Discoveries
Current architecture
- Documents are edited in a drawer (
Documents.tsx), not a dedicated page - Drawer uses
TextEditor(BlockNote) for editing,RichTextViewerfor viewing CollaborativeEditoruses Tiptap (not BlockNote) — different editor, different JSON schemaDocumentEditor(also Tiptap) exists but is NOT actively used anywhere in the app- Content stored in
document_block_content.block_dataas JSONB
Content format mismatch (CRITICAL)
- BlockNote JSON:
[{ type: "paragraph", props: {...}, content: [{ type: "text", text: "...", styles: {} }] }] - Tiptap/ProseMirror JSON:
{ type: "doc", content: [{ type: "paragraph", content: [{ type: "text", text: "..." }] }] } - Existing documents created via
TextEditorare in BlockNote format CollaborativeEditorreads/writes ProseMirror format- Need a conversion layer or format detection on load
Hocuspocus infrastructure
- Server:
hocuspocus/server.json port 1234 - Room naming:
document:<tenantId>:<documentId> - Tenant validation in
tenantValidation.js createYjsProviderinpackages/ui/src/editor/yjs-config.ts- Env vars:
HOCUSPOCUS_URL(default http://localhost),HOCUSPOCUS_PORT(default 1234)
Snapshot/persistence
syncCollabSnapshot()incollaborativeEditingActions.tsalready works- Converts Y.js XML fragment → ProseMirror JSON →
document_block_content.block_data - Hocuspocus Database extension also persists to its own tables
Key file paths
packages/documents/src/components/Documents.tsx— main documents page with drawerpackages/documents/src/components/CollaborativeEditor.tsx— collab editorpackages/documents/src/components/DocumentEditor.tsx— unused single-user Tiptap editorpackages/documents/src/actions/documentBlockContentActions.ts— CRUD actionspackages/documents/src/actions/collaborativeEditingActions.ts— snapshot syncpackages/ui/src/editor/TextEditor.tsx— BlockNote editor (used in drawer today)packages/ui/src/editor/yjs-config.ts— Y.js provider factoryhocuspocus/server.js— Hocuspocus WebSocket server
Decisions
- Keep drawer UX — replace TextEditor inside drawer with CollaborativeEditor
- Graceful fallback — detect Hocuspocus availability, fall back to current editor
- Keep Save button — auto-sync via Y.js, but keep explicit Save/Snapshot for confidence
- Content format: need to handle both BlockNote and ProseMirror JSON in DB
Open Questions
- How many existing documents are in BlockNote format vs ProseMirror format?
- Should we convert existing documents eagerly (migration) or lazily (on first open)?
Progress
- Replaced drawer edit mode for existing in-app documents to render
CollaborativeEditor(kept BlockNote editor only for new-document flow for now). Placeholder tenant/user display info used until F02 wiring. - Wired current user lookup in
Documents.tsxto supply tenant/user identity toCollaborativeEditorfor proper Hocuspocus room naming. - Added
blockContentFormathelper with JSON parsing + format detection (BlockNote vs ProseMirror vs empty/unknown). - Implemented initial BlockNote-to-ProseMirror conversion for paragraph blocks in
blockContentFormat. - Added heading block conversion with level mapping to ProseMirror heading nodes.
- Added BlockNote list item conversion to ProseMirror bullet/ordered list nodes.
- Expanded inline conversion to map text styles, links, and mentions to ProseMirror marks/text.
- Added conversion support for checklists, code blocks, blockquotes, and table fallbacks.
- Collaborative editor now initializes Y.js state from existing block_data with BlockNote conversion when needed.
- Save button in drawer now triggers collaborative snapshot sync when using the collab editor.
- Added best-effort snapshot on drawer close for collaborative sessions.
- Added 3s Hocuspocus timeout handling to switch drawer editor into fallback mode.
- Fallback editor now uses
DocumentEditorwith drawer-level save viaupdateBlockContentand shared toolbar/styling. - Added fallback status banner: "Offline — manual save mode".
- Presence bar and collaboration cursors are available via
CollaborativeEditorin the drawer context. - New document creation now pre-creates document + block_content and opens the collaborative editor in the new room.
- Added read-only
DocumentViewer(Tiptap) for drawer view mode to render BlockNote or ProseMirror content. - Document name input remains editable and wired to update document name on save in both collab and fallback modes.
- Unsaved changes warning now accounts for fallback editor changes before closing the drawer.
- BlockNote-to-ProseMirror conversion now persists converted JSON back to
document_block_content. - Added drawer test coverage to ensure CollaborativeEditor renders on edit of in-app documents.
- Synced entity-mode drawer rendering with collaborative/fallback editor logic (avoids legacy BlockNote path).
- Added test ensuring
CollaborativeEditorusesdocument:<tenantId>:<documentId>room naming. - Added format detection test for BlockNote JSON.
- Added format detection test for ProseMirror JSON.
- Added empty/null format detection test.
- Added paragraph conversion test for BlockNote → ProseMirror.
- Added styled text conversion test for bold/italic/underline marks.
2026-02-24 Updates
- Added heading conversion test for BlockNote -> ProseMirror (levels 1-3) in
packages/documents/src/lib/blockContentFormat.test.tsand marked T08 complete. - Ran
npx vitest run ../packages/documents/src/lib/blockContentFormat.test.ts. - Added bullet list item conversion test in
packages/documents/src/lib/blockContentFormat.test.tsand marked T09 complete. - Ran
npx vitest run ../packages/documents/src/lib/blockContentFormat.test.ts. - Added numbered list item conversion test in
packages/documents/src/lib/blockContentFormat.test.tsand marked T10 complete. - Ran
npx vitest run ../packages/documents/src/lib/blockContentFormat.test.ts. - Added link inline conversion test in
packages/documents/src/lib/blockContentFormat.test.tsand marked T11 complete. - Ran
npx vitest run ../packages/documents/src/lib/blockContentFormat.test.ts. - Added mention inline conversion test in
packages/documents/src/lib/blockContentFormat.test.tsand marked T12 complete. - Ran
npx vitest run ../packages/documents/src/lib/blockContentFormat.test.ts(tests passed but the command hit the 10s timeout after printing results). - Added code block conversion test in
packages/documents/src/lib/blockContentFormat.test.tsand marked T13 complete. - Ran
npx vitest run ../packages/documents/src/lib/blockContentFormat.test.ts. - Added blockquote conversion test in
packages/documents/src/lib/blockContentFormat.test.tsand marked T14 complete. - Ran
npx vitest run ../packages/documents/src/lib/blockContentFormat.test.ts. - Added empty block conversion test in
packages/documents/src/lib/blockContentFormat.test.tsand marked T15 complete. - Ran
npx vitest run ../packages/documents/src/lib/blockContentFormat.test.ts. - Added recursive conversion to flatten
childrenblocks inpackages/documents/src/lib/blockContentFormat.tsplus a nested children test inpackages/documents/src/lib/blockContentFormat.test.ts(T16). - Ran
npx vitest run ../packages/documents/src/lib/blockContentFormat.test.ts. - Added
CollaborativeEditor.init.test.tsxto cover ProseMirror load (no conversion) and BlockNote load (conversion + persistence), marking T17/T18 complete. - Mocked
EditorToolbarin the new test file to avoid editor API dependencies. - Ran
npx vitest run ../packages/documents/src/components/CollaborativeEditor.init.test.tsx. - Extended
Documents.drawer.test.tsxto assert Save triggerssyncCollabSnapshotin collaborative mode (T19) and adjusted mock to set connection status viauseEffect. - Ran
npx vitest run ../packages/documents/src/components/Documents.drawer.test.tsx. - Added drawer close snapshot test in
Documents.drawer.test.tsxand marked T20 complete. - Ran
npx vitest run ../packages/documents/src/components/Documents.drawer.test.tsx.
Updates
- Fixed fallback mode timing loop by separating
isEditingDocumentfromisCollaborativeEditso the timeout can set fallback without immediately clearing it. Files:packages/documents/src/components/Documents.tsx. - Test T21 now passes by waiting for the 3s timeout to switch to the fallback editor. Test:
packages/documents/src/components/Documents.drawer.test.tsx. - Added fallback mode save test (T22) asserting
updateBlockContentruns when manual save is enabled. EnhancedDocumentEditormock to drive unsaved state and content for fallback save. File:packages/documents/src/components/Documents.drawer.test.tsx. - Added T23 test to confirm offline indicator appears in fallback mode (
Offline — manual save mode). File:packages/documents/src/components/Documents.drawer.test.tsx. - Added collaborative presence/caret tests in
packages/documents/src/components/CollaborativeEditor.init.test.tsx:- Presence bar renders connected users from awareness state.
- Collaboration caret render callback produces labeled cursor.
- Collaboration extension configured with Yjs document for real-time sync.
- Added T27 test to ensure folder-mode new document creation calls
createBlockDocumentand opens the collab editor. Test:packages/documents/src/components/Documents.drawer.test.tsx. - Added T28 test to ensure non-editable docs render the read-only viewer in the drawer. File:
packages/documents/src/components/Documents.drawer.test.tsx. - Added T29 test confirming document name input in drawer is editable. File:
packages/documents/src/components/Documents.drawer.test.tsx. - Added T30 test verifying unsaved changes confirmation appears when closing in fallback mode. Updated ConfirmationDialog mock to render when open. File:
packages/documents/src/components/Documents.drawer.test.tsx. - Marked T31 complete based on existing conversion persistence assertion in
packages/documents/src/components/CollaborativeEditor.init.test.tsx. - Added T32-T35 coverage in
packages/documents/src/components/CollaborativeEditor.init.test.tsx:- Reopens content saved as ProseMirror JSON string.
- Editor toolbar renders when editor is ready.
- Emoticon extension included in editor configuration.
- Link extension configured with autolink + linkOnPaste.