## perf-data-optimization
- Add @@index([name]) on User model (migration)
- Add WEATHER_HISTORY_LIMIT=90 constant, apply take/orderBy on weather history queries
- Replace deep includes with explicit select on all 6 list service queries
- Add unstable_cache layer with revalidateTag on all list service functions
- Add cache-tags.ts helpers (sessionTag, sessionsListTag, userStatsTag)
- Invalidate sessionsListTag in all create/delete Server Actions
## perf-realtime-scale
- Create src/lib/broadcast.ts: generic createBroadcaster factory with shared polling
(one interval per active session, starts on first subscriber, stops on last)
- Migrate all 6 SSE routes to use createBroadcaster — removes per-connection setInterval
- Add broadcastToXxx() calls in all Server Actions after mutations for immediate push
- Add SESSIONS_PAGE_SIZE=20, pagination on sessions page with loadMoreSessions action
- Add "Charger plus" button with loading state and "X sur Y" counter in WorkshopTabs
## Tests
- Add 19 unit tests for broadcast.ts (polling lifecycle, userId filtering,
formatEvent, error resilience, session isolation)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Eliminate N+1 on resolveCollaborator: add batchResolveCollaborators() in
auth.ts (2 DB queries max regardless of session count), update all 4
workshop services to use post-batch mapping
- Debounce router.refresh() in useLive.ts (300ms) to group simultaneous
SSE events and avoid cascade re-renders
- Call cleanupOldEvents fire-and-forget in createEvent to purge old SSE
events inline without blocking the response
- Add loading.tsx skeletons on /sessions and /users matching actual page
layout (PageHeader + content structure)
- Lazy-load ShareModal via next/dynamic in BaseSessionLiveWrapper to reduce
initial JS bundle
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>