39 lines
3.5 KiB
Markdown
39 lines
3.5 KiB
Markdown
# Architecture Notes
|
|
|
|
Deeper technical reference backing `CLAUDE.md`. Update this as decisions are made — treat it as a living design doc, not a one-time spec.
|
|
|
|
## 1. Outline API surface
|
|
|
|
- **Base**: `https://<your-instance>/api/*`, RPC-style (POST for nearly everything, not strict REST verbs).
|
|
- **Auth**: `Authorization: Bearer <API_KEY>` header. Keys are created per-user under Settings → API Keys on the Outline instance. Store in Keychain, scope a dedicated key to this app rather than reusing a personal one.
|
|
- **Core endpoints to wrap first**: `documents.info`, `documents.list`, `documents.search`, `documents.create`, `documents.update`, `collections.list`, `collections.info`, `users.info`.
|
|
- Full reference: your instance's `/developers` page (same docs as getoutline.com/developers, versioned per Outline release — check against your self-hosted version, not just the public docs).
|
|
|
|
## 2. Realtime collaboration transport
|
|
|
|
- Endpoint: `wss://<your-instance>/collaboration/document.<document-id>`.
|
|
- Protocol: Hocuspocus (a Yjs-CRDT-over-WebSocket server implementation). This is **not** the same socket as any notification/presence channel — it's the actual document edit transport.
|
|
- Payload: binary Yjs update messages (Yjs update format v1/v2) plus the Yjs awareness protocol for cursor/selection presence.
|
|
- Your reverse proxy (Caddy, in your homelab) must forward `Upgrade`/`Connection` headers correctly or collaboration silently falls back to "no live sync" while REST edits still work — worth a smoke test against your own Caddy config early.
|
|
|
|
## 3. CRDT engine — YSwift
|
|
|
|
- Repo: `y-crdt/yswift`. Swift bindings over `yrs` (Rust) via UniFFI, distributed with a prebuilt XCFramework.
|
|
- Status as of mid-2026: WIP, pre-1.0, small but active contributor base. Not all Yrs/Yjs features are exposed yet.
|
|
- Integration point: YSwift gives you a local `Y.Doc` you mutate; a Hocuspocus-compatible WebSocket provider (you'll likely need to write this provider yourself in Swift — no off-the-shelf Swift Hocuspocus client exists yet) syncs that doc's binary updates with the server.
|
|
- Fallback if YSwift blocks progress: vendor the C FFI (`yffi`) directly and write a thinner Swift wrapper for just the operations you need (XML fragment read/write, update encode/decode, state vector diffing).
|
|
|
|
## 4. Document schema mapping
|
|
|
|
Outline's editor is ProseMirror-based; the Yjs doc stores document structure as a `Y.XmlFragment` mirroring the ProseMirror schema (paragraphs, headings, bullet/ordered/checklist lists, tables, code blocks, blockquotes, embeds, comments-as-marks). Native editor work breaks into:
|
|
|
|
- **Read path**: Y.XmlFragment → your own document model → `AttributedString`/TextKit 2 layout.
|
|
- **Write path**: local edit → diff against your document model → Yjs transaction on the XmlFragment → binary update sent over the Hocuspocus socket.
|
|
- Build the node-type mapping table (ProseMirror node/mark name → native representation) as an explicit, tested module — this is the piece most likely to silently drift from Outline's actual schema as Outline ships updates.
|
|
|
|
## 5. Known risk areas (revisit as the project progresses)
|
|
|
|
- YSwift feature gaps vs. full Yjs (undo/redo manager, relative positions) — check current state before Phase 2 starts, this library moves fast.
|
|
- Table and embed support are the least standardized part of ProseMirror schemas generally — budget them last.
|
|
- Outline server version drift: self-hosted instance upgrades could change API shapes or the collaboration payload; pin against your actual running version, not assumptions from docs.
|