diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 2c332ac..935f3f3 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -35,14 +35,16 @@ Self-hosted Discord alternative with decentralized identity. Each user has a "ho - JWT authentication middleware - Register handler (creates keypair) - Login handler (returns encrypted keypair for device sync) -- Join server handler (signature-based verification - stub) +- Join server handler (signature-based verification with identity checks) +- HTTP client for cross-server public key fetching - Public endpoints for cross-server identity verification - Channel CRUD - Message CRUD with author caching ### ❌ Not Implemented -- HTTP client for cross-server public key fetching -- WebSocket for real-time messages +- WebSocket gateway for real-time events +- Notification system (mentions/replies/unread state) +- Push delivery pipeline (FCM/APNs/WebPush device tokens + dispatch) - Profile sync (push updates to all servers) - Sticker packs (future feature) - File uploads @@ -100,6 +102,24 @@ class Message { String content; DateTime createdAt, editedAt; } + +@Entity() +class Notification { + int id; + int recipientLocalId; + String recipientUserId; // "alice@home.server" + + String type; // "mention", "reply", "system" + String title; + String body; + + int? channelId; + int? messageId; + + bool isRead; + DateTime createdAt; + DateTime? readAt; +} ``` --- @@ -129,10 +149,32 @@ GET /api/messages?channelId=X → Get messages POST /api/messages → Send message PUT /api/messages/:id → Edit message DELETE /api/messages/:id → Delete message + +GET /api/notifications → List notifications +POST /api/notifications/read → Mark notifications read + +POST /api/push/devices → Register device push token +DELETE /api/push/devices/:id → Remove push token ``` --- +## Realtime & Notifications (Planned MVP) + +- Add WebSocket endpoint (e.g. `/gateway`) authenticated by JWT. +- Keep REST as source of truth; WebSocket is for event fanout. +- On message create/edit/delete: + 1. Write to DB + 2. Emit gateway event to subscribed clients + 3. Generate notification records for mention/reply targets +- If recipient is online, deliver notification over gateway immediately. +- If recipient is offline and has device token, enqueue push dispatch. +- Reconnect strategy: client backfills missed messages using + `GET /api/messages?channelId=X&after=lastSeenMessageId`. +- Full Discord-style resume/replay is optional and can be added later. + +--- + ## Key Files ``` @@ -159,7 +201,7 @@ lib/ --- -## Join Server Flow (Needs Implementation) +## Join Server Flow (Implemented) ``` CLIENT GUEST SERVER HOME SERVER @@ -183,7 +225,10 @@ CLIENT GUEST SERVER HOME SERVER │◄─────────────────────────────────────│ │ ``` -The `fetchPublicKeyFromHomeServer()` function in `auth_handlers.dart` needs actual HTTP implementation. +The join flow now: +- Fetches identity from home server over HTTP (`/.well-known/users/:username`) +- Verifies claimed `userId` matches home-server response +- Verifies signature before issuing token (including already-joined users) --- @@ -226,6 +271,7 @@ The `fetchPublicKeyFromHomeServer()` function in `auth_handlers.dart` needs actu 4. **Message Forwarding** - Embed with link to original 5. **Permissions** - Role-based access to channels 6. **WebSocket** - Real-time message delivery +7. **Advanced Notification Rules** - Mute/priority/snooze/digests --- @@ -241,8 +287,9 @@ static const String jwtSecret = 'use-env-variable'; // CHANGE THIS ## Next Steps -1. Implement HTTP client in `fetchPublicKeyFromHomeServer()` -2. Add WebSocket for real-time -3. Add profile sync (client pushes to all servers on change) -4. Test cross-server join flow -5. Add proper error handling and logging +1. Add WebSocket gateway (`/gateway`) with JWT auth + channel subscriptions +2. Add message history cursor pagination (`before` + `after`) +3. Implement notifications (DB model + generation rules + unread counters) +4. Add push token registration + push dispatch worker +5. Add profile sync (client pushes to all servers on change) +6. Add proper error handling, replay protection, and logging