- AW-2: Scope calendar events fetch to visible date range via start/end
query params, leveraging existing backend support
- AW-3: Reduce calendar events poll from 5s to 30s (personal organiser
doesn't need 12 API calls/min)
- AS-4: Gate shared-calendar polling on hasSharedCalendars — saves 12
wasted API calls/min for personal-only users
- AS-2: Lazy-load all route components with React.lazy() — only
AdminPortal was previously lazy, now all 10 routes are code-split
- AS-1: Add Vite manualChunks to split FullCalendar (~400KB), React,
TanStack Query, and UI libs into separate cacheable chunks
- AS-3: Extract clockNow into isolated ClockDisplay memo component —
prevents all 8 dashboard widgets from re-rendering every minute
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Gate dashboard rendering on isLockResolved to prevent content flash
before lock state is known. Remove animate-fade-in from LockOverlay
so it renders instantly. Always write accent color to localStorage
(even default cyan) to prevent theme flash on reload. Resolve lock
state on auth query error to avoid permanent blank screen. Lift
mobileOpen state above lock gate to survive lock/unlock cycles.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implements the full User Connections & Notification Centre feature:
Phase 1 - Database: migrations 039-043 adding umbral_name to users,
profile/social fields to settings, notifications table, connection
request/user_connection tables, and linked_user_id to people.
Phase 2 - Notifications: backend CRUD router + service + 90-day purge,
frontend NotificationsPage with All/Unread filter, bell icon in sidebar
with unread badge polling every 60s.
Phase 3 - Settings: profile fields (phone, mobile, address, company,
job_title), social card with accept_connections toggle and per-field
sharing defaults, umbral name display with CopyableField.
Phase 4 - Connections: timing-safe user search, send/accept/reject flow
with atomic status updates, bidirectional UserConnection + Person records,
in-app + ntfy notifications, per-receiver pending cap, nginx rate limiting.
Phase 5 - People integration: batch-loaded shared profiles (N+1 prevention),
Ghost icon for umbral contacts, Umbral filter pill, split Add Person button,
shared field indicators (synced labels + Lock icons), disabled form inputs
for synced fields on umbral contacts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>