feat: add unified notification system with real-time WS delivery
Persistent, PostgreSQL-backed notification system replacing the in-memory
access request polling. Notifications are created via notify(), persisted
to DB, and delivered in real-time over WebSocket with a 30s polling fallback.
Infrastructure:
- notifications + notification_preferences tables in EncryptID schema
- 10 CRUD functions in db.ts (create, list, count, read, dismiss, etc.)
- notification-service.ts: core notify(), WS registry, notifySpaceAdmins()
- notification-routes.ts: REST API at /api/notifications
- rstack-notification-bell.ts: bell icon component with dropdown panel
Module integration (11 hooks):
- spaces.ts: access_request, access_approved, access_denied, member_joined,
member_left, role_changed
- index.ts WS handler: ping_user (24h expiry)
- encryptid/server.ts: guardian_accepted, recovery_initiated (owner + guardians),
recovery_approved
Legacy cleanup:
- Removed access request polling, badge, and approve/deny UI from
rstack-identity.ts (now handled by notification bell)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>