From 8d1f94e02e927fcb80d170fc85d13a091e5dc304 Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Sun, 05 Apr 2026 16:30:42 +0200
Subject: [PATCH] feat: add message trace log for end-to-end delivery diagnostics

---
 lib/screens/chat_screen.dart |   30 +++++++++++++++++++++++++++++-
 1 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/lib/screens/chat_screen.dart b/lib/screens/chat_screen.dart
index 3a64ee3..9b8a551 100644
--- a/lib/screens/chat_screen.dart
+++ b/lib/screens/chat_screen.dart
@@ -20,6 +20,7 @@
 import '../services/audio_service.dart';
 import '../services/message_store.dart';
 import '../services/mqtt_service.dart';
+import '../services/trace_service.dart';
 import '../services/navigate_notifier.dart';
 import '../services/push_service.dart';
 import '../theme/app_theme.dart';
@@ -43,6 +44,7 @@
 
 Future<void> _chatLog(String msg) async {
   debugPrint('[Chat] $msg');
+  TraceService.instance.addTrace('Chat', msg);
   if (!kDebugMode) return;
   try {
     final dir = await getApplicationDocumentsDirectory();
@@ -256,12 +258,25 @@
 
   void _handleMessage(Map<String, dynamic> msg) {
     final type = msg['type'] as String?;
+    final msgSessionId = msg['sessionId'] as String?;
+    final msgSeq = msg['seq'];
+
+    TraceService.instance.addTrace(
+      'handleMessage processing',
+      'type=$type sessionId=${msgSessionId?.substring(0, msgSessionId.length.clamp(0, 8))} seq=$msgSeq',
+    );
 
     // Track sequence numbers for catch_up protocol
     final seq = msg['seq'] as int?;
     if (seq != null) {
       // Dedup: skip messages we've already processed
-      if (_seenSeqs.contains(seq)) return;
+      if (_seenSeqs.contains(seq)) {
+        TraceService.instance.addTrace(
+          'handleMessage seq deduped',
+          'seq=$seq type=$type — already seen, dropping',
+        );
+        return;
+      }
       _seenSeqs.add(seq);
       _seenSeqsList.add(seq);
       // Keep bounded at 500 with O(1) FIFO eviction (drop oldest first)
@@ -491,6 +506,11 @@
         msg['text'] as String? ??
         '';
 
+    TraceService.instance.addTrace(
+      'handleMessage processing type=text',
+      'sessionId=${sessionId?.substring(0, sessionId.length.clamp(0, 8))}',
+    );
+
     final message = Message.text(
       role: MessageRole.assistant,
       content: content,
@@ -500,6 +520,10 @@
     final activeId = ref.read(activeSessionIdProvider);
     if (sessionId != null && sessionId != activeId) {
       // Store message for the other session so it's there when user switches
+      TraceService.instance.addTrace(
+        'message stored for session',
+        'sessionId=${sessionId.substring(0, sessionId.length.clamp(0, 8))}, toast shown',
+      );
       await _storeForSession(sessionId, message);
       _incrementUnread(sessionId);
       final sessions = ref.read(sessionsProvider);
@@ -516,6 +540,10 @@
         );
       }
     } else {
+      TraceService.instance.addTrace(
+        'message displayed in chat',
+        'sessionId=${sessionId?.substring(0, sessionId.length.clamp(0, 8)) ?? "global"} len=${content.length}',
+      );
       ref.read(messagesProvider.notifier).addMessage(message);
       ref.read(isTypingProvider.notifier).state = false;
       _scrollToBottom();

--
Gitblit v1.3.1