Runtime Architecture
Ideon runs as a single container with a custom Node server that hosts both Next.js and a WebSocket server. Both HTTP and WebSocket traffic share the same port.
Startup Flow
- Initialize database connection.
- Run Kysely migrations.
- Prepare the Next.js application.
- Start the HTTP server and attach the WebSocket server.
HTTP Request Flow
All requests are filtered through the proxy layer, which applies security headers and enforces access rules.
- Guest routes include login, setup, register, and public APIs.
- Authenticated users are redirected away from guest only pages.
- Unauthenticated access to protected routes is redirected to login.
WebSocket Flow
Realtime synchronization uses Yjs with a custom WebSocket server.
- Endpoint: The WebSocket server runs on the same port as Next.js at
/yjs. - Documents: Each project maps to a Yjs document named
project-<uuid>. - Authentication:
- Connection requests are validated against the session and project permissions.
- The server monitors access changes in real-time.
- Kick User: If a user's access is revoked, their WebSocket connection is forcibly closed (code 4003).
- Access Grant: When access is granted, the user is notified via a dedicated
project-<id>-accessdocument.
Persistence
Ideon uses a hybrid persistence strategy:
- Relational Data: User profiles, project metadata, folders, and permissions are stored in PostgreSQL or SQLite (managed by Kysely).
- CRDT State (Yjs): The collaborative state of each project (blocks, positions, text) is persisted in LevelDB.
- Path:
storage/yjs - This allows efficient delta updates and history merging.
- Path:
- File Uploads: User uploads are stored locally at
storage/uploads/project-<projectId>.