claude-notes: update current-state.md (2026-04-11 03:54)

This commit is contained in:
2026-04-11 03:54:26 +10:00
parent a01c527157
commit 93442790f3

View File

@@ -1,51 +1,63 @@
## M8Chat App2 — Current State (2026-04-10) ## M8Chat App2 — Current State (2026-04-11)
Custom Flutter Matrix chat client (v1.2.0) deployed to app2.m8chat.au for testing. Custom Flutter Matrix chat client deployed to app2.m8chat.au. Replaces the FluffyChat fork (app.m8chat.au). Built on Matrix Dart SDK 0.33.0, LiveKit for video, Olm for E2EE.
Production (app.m8chat.au) still runs the old FluffyChat fork — DO NOT deploy there.
### What was built/changed this session
1. **Jitsi Conference tab** — 4th bottom nav tab for joining conf.m8chat.au meetings
2. **Help tab** — 5th bottom nav tab with troubleshooting guides, account management links
3. **Auth rewrite (v2.0.0)** — fresh login every session on web, no credential persistence
4. **SSSS/cross-signing/key backup** — full security setup dialog (Bootstrap flow)
5. **Key restore dialog** — enter recovery key to download Megolm keys from backup
6. **Authenticated media (v2.0.0)** — switched to /_matrix/client/v1/media/download/ (Synapse 1.151.0 froze old endpoint)
7. **LiveKit E2EE** — CallE2EEManager for m.rtc.encryption_keys key exchange, COOP/COEP headers
8. **Hangup fix** — sends {} to clear call.member state event
9. **Cleaned up 24 ghost devices** for try user (DB direct delete)
### What works ### What works
- **Chat messaging** — rooms list, timeline, send/receive, reactions, replies, file upload, typing indicators - Login/logout flow (fresh every session)
- **E2EE (Olm/Megolm)** — Olm loads in browser, device keys upload, messages encrypt/decrypt between app2 and Element - Room list with avatars (authenticated media endpoint)
- **Spaces** — expandable space list with child rooms - Chat messaging (text)
- **User search** — search Matrix user directory, start DMs - Encrypted message display (lock icon for undecryptable)
- **Jitsi conferencing** — lazy-loaded iframe, no-login required - Security setup (SSSS + cross-signing + key backup creation)
- **LiveKit video/audio calls** — JWT fetch works, WebRTC connects, video+audio publish to LiveKit SFU - Key restore from backup
- **Session persistence** — credentials in flutter_secure_storage, events in MatrixSdkDatabase (IndexedDB) - Jitsi conference joining (Conference tab)
- **Brave browser** — app loads and works (Olm included, graceful fallback if WASM blocked) - Help tab with troubleshooting content
- Spaces view
- Profile with security settings
### What is broken / incomplete ### What's broken / untested
- **Video call rendering — SCRAMBLED VIDEO from Element X**: Root cause identified. Element X sends media with `encryption: GCM` (AES-GCM frame encryption). App2 sends `encryption: NONE`. The LiveKit Flutter SDK needs E2EE frame encryption enabled to decrypt Element X video. This is the #1 priority fix. - **Video calls (E2EE interop)** — COOP/COEP headers added, E2EE re-enabled, but NOT YET TESTED. May still show scrambled video if key exchange doesn't interop with Element X's m.rtc.encryption_keys format.
- **Incoming call detection**: App listens for old m.call.invite events. Element X sends MSC3401 call.member state events. Incoming calls from Element X to app2 are not detected. - **Hangup termination** — Changed to send {} but NOT YET TESTED whether Element X recognises it.
- **Avatar 404s**: ~10 room avatars return 404 on legacy /_matrix/media/v3/download/ path. Server may require authenticated media. - **Incoming call detection** — Not implemented. No MSC3401 state event listener.
- **Rooms list spam**: debugPrint in rooms_repository.dart dumps all 15 rooms to console on every sync. Needs removal. - **Avatar 404s in cached/old data** — sync_persistence_service caches URLs; stale URLs may linger in IndexedDB
- **Old ghost devices**: 20 devices for @try user, 5 without keys (from pre-Olm builds). Should be cleaned up server-side. - **Ghost devices accumulate** — each web login creates a new device. No cleanup mechanism.
- **Red exclamation mark in Element**: Try device is unverified (no cross-signing). Cosmetic — requires manual verification or Phase 2 cross-signing. - **Rooms provider fires excessively** — console shows room list logged 15+ times per sync cycle (performance)
- **Profile screen**: E2EE status shows dynamically but notifications/cross-signing are placeholders. - **Noto font warning** — emoji characters in room names can't render (missing font asset)
### Key file paths ### Key file paths
- **Project root**: /srv/wp-dev/pwa-sites/m8chat-app2/ | File | Version | Purpose |
- **Web entry**: web/index.html (Olm load + fallback + Flutter bootstrap) |------|---------|---------|
- **App config**: lib/core/config/app_config.dart (server URLs, version 1.2.0) | lib/core/auth/auth_notifier.dart | 2.0.0 | Auth state machine — fresh login, no restore |
- **Matrix client**: lib/core/network/matrix_client.dart (MatrixSdkDatabase provider) | lib/core/auth/secure_storage.dart | 2.0.0 | Minimal — only stores device ID (currently unused) |
- **Auth flow**: lib/core/auth/auth_notifier.dart + lib/features/auth/data/auth_repository.dart | lib/core/config/app_config.dart | 2.0.0 | Server URLs, app name/version |
- **LiveKit service**: lib/features/calls/data/livekit_service.dart (JWT fetch, MatrixRTC state events) | lib/shared/utils/mxc_url.dart | 2.0.0 | Authenticated media URL resolution |
- **Call screen**: lib/features/calls/presentation/call_screen.dart (video rendering) | lib/features/calls/data/livekit_service.dart | 1.4.0 | LiveKit connect/disconnect with E2EE |
- **Call controller**: lib/features/calls/presentation/call_controller.dart (state machine) | lib/features/calls/data/call_e2ee.dart | 1.0.0 | E2EE key exchange via m.rtc.encryption_keys |
- **Chat repo**: lib/features/chat/data/chat_repository.dart (timeline, send, react, redact) | lib/features/profile/presentation/security_setup_dialog.dart | 1.0.0 | SSSS Bootstrap driver |
- **Jitsi service**: lib/features/jitsi/data/jitsi_web_service.dart (lazy script load) | lib/features/profile/presentation/key_restore_dialog.dart | 1.0.0 | Recovery key input + loadAllKeys |
- **Build output**: build/web/ (flutter build web --release) | lib/features/help/presentation/help_tab.dart | 1.1.0 | In-app help content |
| lib/features/jitsi/presentation/conference_tab.dart | 1.0.0 | Jitsi meeting join UI |
| lib/features/rooms/presentation/rooms_screen.dart | 1.3.0 | 5-tab bottom nav |
### Server infrastructure (chat.m8chat.au) ### Server configuration
- Synapse 1.151.0 (healthy, 86 active users) - **COOP/COEP headers** added to ~/public_html/app2.m8chat.au/.htaccess
- LiveKit 1.10.1 + lk-jwt-service (both healthy) - Synapse 1.151.0 on chat.m8chat.au (PostgreSQL, SQLite was wrong assumption)
- Element Web 1.12.15, Element Call - LiveKit 1.10.1 on chat.m8chat.au
- PostgreSQL on host (user: synapse_user, pass: kijPt4cPWkoaZk8BVm, db: synapse) - lk-jwt-service for MatrixRTC JWT at /_matrix/livekit/jwt/sfu/get
- LiveKit WSS URL: wss://matrix.m8chat.au/livekit/
- JWT endpoint: https://matrix.m8chat.au/_matrix/livekit/jwt/sfu/get
### Deployment ### Known technical debt
- **Target**: app2.m8chat.au (NOT app.m8chat.au) - call_e2ee.dart imported but E2EE interop with Element X not verified
- **SSH**: m8chat@app.m8chat.au:2233 (key: ~/.ssh/m8chat_prod), path: public_html/app2.m8chat.au/ - secure_storage.dart exists but device ID save/load is unused (removed to fix keys/upload 400)
- **Build**: cd /srv/wp-dev/pwa-sites/m8chat-app2 && flutter build web --release - key_restore_dialog.dart is separate from security_setup_dialog.dart — could be consolidated
- **Deploy**: rsync -avz --delete --exclude='.htaccess' --exclude='.ftpquota' -e "ssh -p 2233 -i ~/.ssh/m8chat_prod" build/web/ m8chat@app.m8chat.au:public_html/app2.m8chat.au/ - Rooms provider rebuilds too frequently (every sync tick)
- **Backup on server**: public_html/app2.m8chat.au_backup_20260410_*.tar.gz