feat: add collaborative review sessions#316
Conversation
Add server-side collaborative review sessions allowing multiple team members to review and annotate a plan using a single shared URL. **Problem Solved:** Previously, to get feedback from N reviewers, you needed N separate share URLs (each reviewer creates their own annotated version and sends it back). Now, create one session URL and all reviewers add annotations to the same session. **Backend Changes:** - Add ReviewSession, CreateReviewSessionRequest, AddAnnotationsRequest types - Extend PasteStore interface with session methods - Implement session storage for filesystem and Cloudflare KV - Add 3 new API endpoints: - POST /api/review-session (create new session) - GET /api/review-session/:id (fetch session state) - PATCH /api/review-session/:id/annotations (add annotations with optimistic locking) **Frontend Changes:** - Add useCollaborativeSession hook for session management - Add CollaborativeSessionButton UI component - Integrate collaborative session button in plan editor toolbar **Key Features:** - One fixed URL for all reviewers (no N-way URL ping-pong) - Server merges annotations automatically (deduplicates) - Optimistic locking prevents version conflicts - Auto-expires after 7 days (same as paste service) - Works offline (local filesystem) or cloud (Cloudflare KV) **Files Changed:** - packages/ui/types.ts (+50 lines) - apps/paste-service/core/storage.ts (+10 lines) - apps/paste-service/stores/fs.ts (+50 lines) - apps/paste-service/stores/kv.ts (+30 lines) - apps/paste-service/core/handler.ts (+210 lines) - packages/editor/App.tsx (+10 lines) - CLAUDE.md (+40 lines) **Files Created:** - packages/ui/hooks/useCollaborativeSession.ts (260 lines) - packages/ui/components/CollaborativeSessionButton.tsx (170 lines) - COLLABORATIVE_REVIEW_GUIDE.md (comprehensive testing guide) **Tested:** - ✅ Session creation - ✅ Session retrieval - ✅ Annotation merging from multiple reviewers - ✅ Optimistic locking (version conflict handling) - ✅ Deduplication - ✅ Filesystem storage persistence Co-authored-by: Claude <noreply@anthropic.com>
|
Hey @eprj453 what was the motivation behind this, what type of testing have you done |
|
We're running plannotator on a self-hosted EKS deployment and this is the feature that would make it genuinely useful for team review. The paste service extension approach is clean — it builds on existing infrastructure without requiring a separate real-time backend. |
|
Related to #313. Great work @eprj453 — this covers a lot of ground and tackles the hardest part: the full storage layer, API endpoints, both FS and KV backends, the hook, and the UI integration. The overall architecture (extending the paste A few things I ran into while prototyping the same feature locally that might save you some debugging. Tagging @backnotprop for his take on these. Encryption The existing share flow uses AES-256-GCM with the key in the URL fragment so the server never sees plan content. This PR stores plans and annotations as plaintext JSON on the paste service. That's a regression from No real-time sync Reviewers have to manually click "Refresh" to see others' annotations and "Submit" to push their own. For a collaborative session this is a dealbreaker in practice — you end up with version conflicts and stale state. A polling Remote annotations won't render as highlights
Optimistic locking on KV is racy The KV No session lifecycle There's no concept of a session owner, closing a session, or approve/deny. In practice the person who created the session needs to be able to lock it when review is done. Theme Minor: @backnotprop what's your thinking on this? Happy to share more detail from my prototype if it helps. |
|
Yes all these things matter @grubmanItay - also willing to meet over call for this work |
|
Thanks everyone for the thoughtful feedback — this is very helpful. You’re right that many of these points should have been discussed earlier in an issue/discussion before going this far in implementation. I’ll make sure to do that for design-heavy changes going forward. I still believe that enabling shared review workflows for even small teams can make plannotator much more broadly useful and drive wider adoption of the project. If follow-up issues or PRs are opened around this direction, I’d be happy to actively support and contribute. |
|
Diving deeper into the PR this weekend |
Adds from PR backnotprop#316: - ReviewSession type with collaborative session fields - CollaborativeSessionButton component - useCollaborativeSession hook Extensions for Shuni integration: - AnnotationAuthor type (human/bot distinction) - Session status lifecycle (reviewing/approved/rejected/expired) - closedBy/closedAt fields on ReviewSession - author field on Annotation type uses AnnotationAuthor
Add server-side collaborative review sessions allowing multiple team members to review and annotate a plan using a single shared URL.
Problem Solved:
Previously, to get feedback from N reviewers, you needed N separate share URLs (each reviewer creates their own annotated version and sends it back). Now, create one session URL and all reviewers add annotations to the same session.
Backend Changes:
Frontend Changes:
Key Features:
Files Changed:
Files Created:
Tested: