ralph/collaboration-and-character-variables #9

Merged
GHMiranda merged 22 commits from ralph/collaboration-and-character-variables into developing 2026-01-25 00:11:21 +00:00
Owner
No description provided.
GHMiranda added 14 commits 2026-01-24 20:48:04 +00:00
7fe10544a1 feat: [US-047] - Live cursor positions on canvas
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
841a44112a feat: [US-047] - Live cursor positions on canvas
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ccb05e3a3e feat: [US-050] - Join/leave notifications
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
5b84170a28 fix: allow profile lookup for sharing by adding RLS policy
The profiles table RLS policies only allowed users to view their own
profile, causing the share feature to fail when searching for users
by email. Added a policy allowing any authenticated user to read profiles.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
4a85d7a64b feat: [US-049] - Node editing lock indicators
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6ef5cfc7fa feat: [US-051] - Audit trail recording
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6c4a3ba2b7 docs: update PRD and progress for US-051
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
f06a30b2bf feat: [US-052] - Activity history sidebar
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
315e34e25e feat: [US-053] - Revert changes from audit trail
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
c9f5231137 docs: update PRD and progress for US-053
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
34815d70ee fix: resolve CRDT collaboration sync by registering broadcast listener before channel subscribe
The yjs-update broadcast listener was added after the Supabase channel
was already subscribed, which meant it never received messages. Moved
the listener registration to the builder chain before .subscribe()
(matching how cursor/node-lock listeners work), and removed the broken
isRemoteUpdateRef guard that caused ReferenceErrors preventing local
changes from reaching the CRDT.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
cdaae6b965 feat: broadcast full CRDT state to other clients after manual save
When a user saves, the full Yjs document state is broadcast so all
connected clients converge, even if they missed incremental updates.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
eb86ccd291 feat: notify collaborators to refresh from DB after save
Instead of relying on Yjs broadcast serialization (which has delivery
issues), use a lightweight state-refresh broadcast event. When any
client persists (manual save or CRDT auto-persist), it broadcasts
state-refresh. Other clients fetch the latest flowchart_data from the
database and update their local state and CRDT.

Added isSuppressed flag to CRDTManager to prevent broadcast/persist
loops during initialization and refresh operations.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GHMiranda added 1 commit 2026-01-24 21:23:54 +00:00
cd73b31739 fix: improve realtime connection resilience with auto-reconnect and activity-based lifecycle
Add connection timeout (15s) to handle stale initial subscribes, inactivity
pause (5min) to save resources when idle, and automatic resume on user activity
or tab focus. The heartbeat now detects unhealthy channel states and consecutive
failures to trigger reconnects. Unexpected CLOSED status also triggers reconnect
instead of staying disconnected silently.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GHMiranda added 1 commit 2026-01-24 21:47:35 +00:00
ec053d8126 fix: stop state ping-pong by removing broadcastStateRefresh from auto-persist
The CRDT auto-persist was broadcasting state-refresh after each save, causing
other clients to fetch from DB and overwrite their local variables/characters
with stale values. Since CRDT already syncs nodes/edges via yjs-update
broadcasts, the state-refresh from auto-persist was redundant and destructive.
Manual save still broadcasts state-refresh as intended.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GHMiranda added 1 commit 2026-01-24 21:58:59 +00:00
2d0c3b6df6 fix: reduce auto-save frequency to avoid excessive writes
Increase CRDT DB persist debounce from 2s to 30s since it's only needed for
crash recovery (CRDT handles real-time sync). Increase LocalStorage draft
save debounce from 1s to 5s.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GHMiranda added 1 commit 2026-01-24 22:06:26 +00:00
fa8437d03a fix: broadcast full CRDT state on connect and when new user joins
CRDT broadcasts are fire-and-forget, so any updates missed during a
disconnection were permanently lost. Now when a client connects (or
reconnects), it broadcasts its full Yjs doc state. When an existing client
sees a new user join, it also broadcasts its full state. Yjs merges
handle deduplication automatically, so this converges all clients.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GHMiranda added 1 commit 2026-01-24 22:14:20 +00:00
c28b9ac565 fix: force fresh reconnect when returning after idle period
The WebSocket can go stale during inactivity without triggering any error
status (channel still shows 'joined' but socket is dead). Now when the user
returns after 60+ seconds of inactivity, the connection is torn down and
re-established to guarantee a fresh WebSocket. This ensures CRDT broadcasts
actually reach other clients after returning from idle.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GHMiranda added 2 commits 2026-01-24 22:22:27 +00:00
3b19f58e26 fix: wait for auth session before connecting to realtime channel
On initial page load, the Supabase browser client's auth session may not
be ready yet (still loading from cookies). The Realtime channel subscription
silently fails without a valid access token. Now connect() awaits getSession()
first, which ensures the token is available and also refreshes expired tokens
on reconnect after inactivity.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GHMiranda added 1 commit 2026-01-24 22:35:04 +00:00
cd3ecc4507 fix: only force-reconnect on tab visibility change, not on activity gaps
The 60s stale threshold was triggering during normal use (reading, thinking)
causing constant reconnects and presence join/leave toast spam. Now force-
reconnect only happens when the tab was hidden for 3+ minutes and becomes
visible again. Regular activity (mouse/keyboard) only resets the inactivity
timer without ever forcing a reconnect.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
GHMiranda merged commit 75750cf226 into developing 2026-01-25 00:11:21 +00:00
Sign in to join this conversation.
No reviewers
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: GHMiranda/WebVNWrite#9
No description provided.