A collaborative rich-text editor with real-time, conflict-free editing.
Multiple people, one document, zero merge conflicts — edits sync live via operational transform (OT) over WebSocket.
Inkflow is a Google Docs–style collaborative editor: open the same document from two devices and watch edits appear live on both, without stepping on each other. Under the hood, every keystroke is a Quill Delta op that the backend transforms against concurrent edits before broadcasting it back out — that's the "OT" in operational transform.
🚧 Status: early scaffolding. Auth, document CRUD, and real-time sync are being built in that order. See docs/roadmap.md for exactly where things stand.
|
|
Why this pairing? Quill's Delta format (insert / retain / delete) is already OT-shaped, so the client's document model maps directly onto a server-authoritative OT engine — no translation layer needed. Full rationale in docs/architecture.md.
┌───────────────────┐ REST (Dio/Retrofit) ┌────────────────────────┐
│ Flutter App │ ─────────────────────────────── │ Spring Boot API │
│ (lib/) │ ─────────────────────────────── │ (inkflow-backend/) │
│ │ │ │
│ flutter_quill │ STOMP over WebSocket (/ws) │ WebSocket + OT engine │
│ (editor widget) │ ◀──────────────────────────────▶ │ com.inkflow.ot │
└───────────────────┘ └────────────────────────┘
│
┌────────────┴────────────┐
▼ ▼
PostgreSQL Redis
(documents, users, (presence, live
doc history) OT state cache)
Inkflow/
├── lib/ Flutter app source
├── inkflow-backend/
│ └── src/main/java/com/inkflow/
│ ├── config/ Spring configuration
│ ├── controller/ REST + WebSocket controllers
│ ├── dto/ Request/response payloads
│ ├── entity/ JPA entities
│ ├── enums/ Shared enums (e.g. DocumentRole)
│ ├── exception/ Error handling
│ ├── ot/ Operational transform engine
│ ├── repository/ Spring Data repositories
│ ├── security/ JWT auth, Spring Security config
│ ├── service/ Business logic
│ └── websocket/ STOMP config & handlers
├── docs/
│ ├── architecture.md System design + open decisions
│ ├── roadmap.md Phased build plan
│ ├── api-contract.md REST + STOMP endpoint contracts (draft)
│ └── data-model.md Entity/schema design (draft)
└── CLAUDE.md Conventions for AI-assisted dev
- Flutter SDK (Dart
^3.10.7) - JDK 21 (this project uses
A:\Android\jbr) - PostgreSQL running locally, with a database named
inkflow - Redis running locally
cd inkflow-backend
$env:JAVA_HOME = "A:\Android\jbr"; $env:PATH = "$env:JAVA_HOME\bin;$env:PATH"
.\mvnw clean install -DskipTests
.\mvnw spring-boot:runServer starts on http://localhost:8080. Connection settings (Postgres/Redis credentials, JWT secret) live in inkflow-backend/src/main/resources/application.properties — defaults assume postgres/postgres on localhost:5432 and Redis on localhost:6379.
flutter pub get
flutter run| Problem | Fix |
|---|---|
mvn compile fails with "release version not supported" |
java.version in pom.xml must match the JDK JAVA_HOME points to. Check with java -version. |
flutter pub get version conflicts |
Check flutter_quill (pinned ^9.2.3 — newer needs Dart ^3.12) and nes_ui (pinned ^0.30.0 for google_fonts ^6.x compatibility) before bumping either. |
| Backend can't connect to Postgres/Redis | Confirm both are running locally and credentials in application.properties match your local setup. |
| Doc | Covers |
|---|---|
| CLAUDE.md | Repo conventions, constraints, and quick commands |
| docs/architecture.md | System design, component rationale, open technical decisions |
| docs/roadmap.md | Phased build plan (auth → CRUD → real-time sync → polish) |
| docs/api-contract.md | Draft REST + STOMP endpoint shapes |
| docs/data-model.md | Draft entities and schema design |
- Phase 0 — Project scaffolding (backend skeleton, Flutter deps)
- Phase 1 — Auth (register/login, JWT)
- Phase 2 — Document CRUD
- Phase 3 — Real-time collaborative editing (the core feature)
- Phase 4 — Presence & polish
- Phase 5 — Hardening (history, permissions, tests)
Full detail in docs/roadmap.md.
MIT