Document realtime gateway and notifications/push architecture
This commit is contained in:
1 parent
f6b27565cd
commit
3f7d50f6a2
1 file changed
+57
-10
+57
-10
@@ -35,14 +35,16 @@ Self-hosted Discord alternative with decentralized identity. Each user has a "ho
|
|||||||
- JWT authentication middleware
|
- JWT authentication middleware
|
||||||
- Register handler (creates keypair)
|
- Register handler (creates keypair)
|
||||||
- Login handler (returns encrypted keypair for device sync)
|
- 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
|
- Public endpoints for cross-server identity verification
|
||||||
- Channel CRUD
|
- Channel CRUD
|
||||||
- Message CRUD with author caching
|
- Message CRUD with author caching
|
||||||
|
|
||||||
### ❌ Not Implemented
|
### ❌ Not Implemented
|
||||||
- HTTP client for cross-server public key fetching
|
- WebSocket gateway for real-time events
|
||||||
- WebSocket for real-time messages
|
- Notification system (mentions/replies/unread state)
|
||||||
|
- Push delivery pipeline (FCM/APNs/WebPush device tokens + dispatch)
|
||||||
- Profile sync (push updates to all servers)
|
- Profile sync (push updates to all servers)
|
||||||
- Sticker packs (future feature)
|
- Sticker packs (future feature)
|
||||||
- File uploads
|
- File uploads
|
||||||
@@ -100,6 +102,24 @@ class Message {
|
|||||||
String content;
|
String content;
|
||||||
DateTime createdAt, editedAt;
|
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
|
POST /api/messages → Send message
|
||||||
PUT /api/messages/:id → Edit message
|
PUT /api/messages/:id → Edit message
|
||||||
DELETE /api/messages/:id → Delete 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
|
## Key Files
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -159,7 +201,7 @@ lib/
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Join Server Flow (Needs Implementation)
|
## Join Server Flow (Implemented)
|
||||||
|
|
||||||
```
|
```
|
||||||
CLIENT GUEST SERVER HOME SERVER
|
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
|
4. **Message Forwarding** - Embed with link to original
|
||||||
5. **Permissions** - Role-based access to channels
|
5. **Permissions** - Role-based access to channels
|
||||||
6. **WebSocket** - Real-time message delivery
|
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
|
## Next Steps
|
||||||
|
|
||||||
1. Implement HTTP client in `fetchPublicKeyFromHomeServer()`
|
1. Add WebSocket gateway (`/gateway`) with JWT auth + channel subscriptions
|
||||||
2. Add WebSocket for real-time
|
2. Add message history cursor pagination (`before` + `after`)
|
||||||
3. Add profile sync (client pushes to all servers on change)
|
3. Implement notifications (DB model + generation rules + unread counters)
|
||||||
4. Test cross-server join flow
|
4. Add push token registration + push dispatch worker
|
||||||
5. Add proper error handling and logging
|
5. Add profile sync (client pushes to all servers on change)
|
||||||
|
6. Add proper error handling, replay protection, and logging
|
||||||
Reference in new issue
Block a user