feat: LWW timestamps for bidirectional federation profile & layout sync

Profile and space layout changes on remote instances were being
overwritten by stale data on reconnect. Adds Last-Writer-Wins
timestamps so the client-relay mesh rejects stale writes:

- profile_updated_at column on users table with migration + backfill
- Server LWW guards on PATCH /users/@me and PUT /space-layout
- Bidirectional profileSync: pulls newer remote profiles to home
- LWW layout sync replaces home-authoritative _layoutFromTrueHome flag
- Layout pushes to ALL connected instances in parallel
This commit is contained in:
Jannis Braun
2026-03-12 18:28:37 +01:00
parent acbcf4d4e8
commit 83699d7e91
10 changed files with 294 additions and 115 deletions
+2
View File
@@ -17,6 +17,7 @@ export function sanitizeUser(row: typeof schema.users.$inferSelect): User {
customStatus: null,
isAdmin: false,
isDeleted: true,
profileUpdatedAt: 0,
createdAt: row.createdAt,
homeInstance: null,
homeUserId: null,
@@ -45,6 +46,7 @@ export function sanitizeUser(row: typeof schema.users.$inferSelect): User {
status: (row.status ?? 'offline') as User['status'],
customStatus: row.customStatus,
isAdmin: row.isAdmin === 1,
profileUpdatedAt: row.profileUpdatedAt ?? row.createdAt,
createdAt: row.createdAt,
homeInstance: row.homeInstance ?? null,
homeUserId: row.homeUserId ?? null,