iykyka/mobile/lib/screens
Claude 64323b824e
feat: implement 단톡 따라잡기 (group catch-up summary) — roadmap.md §2.7-A
Closes the biggest content gap found against PRD.md §3.1 P0: group chat
catch-up was one of only two v1 MVP scenarios and had zero implementation.

Backend (core-backend):
- ConversationParticipant.LastReadMessageID read marker.
- POST /conversations/:id/read advances the caller's marker (never backward).
- GET /conversations/:id/summary builds context from messages since that
  marker and calls ai-service's new POST /summarize; returns unread_count
  and needs_reply.
- GET /conversations now reports unread_count per room.
- Safety: group conversations now unconditionally block twin-authored
  sends (POST /conversations/:id/messages), regardless of the sender's
  global autonomy level. PRD.md §2.3-③ requires this scenario stay L0-fixed
  with no auto-send; autonomy level is a per-user global setting today, so
  this closes the only path a global L2 whitelist match could otherwise
  auto-send into a group.

AI service (ai-service): new summarize.py module (same Gemini-call shape as
generation.py's draft_reply, no escalation/identity gating since nothing
generated here is ever sent) + POST /summarize.

Mobile: "새 대화" dialog now supports adding/removing multiple peer fields
(2+ peers -> is_group:true automatically); unread badge on conversation
rows; ChatScreen takes isGroup and renders its L1 panel as L0-locked for
groups; new "안 본 동안 요약" AppBar action opens a dialog with the summary
and, when a reply looks needed, a button that feeds straight into the
existing draft-request flow.

Verified with a real Flutter build against a live core-backend + ai-service
instance (Playwright driving 3 demo accounts through group creation, unread
badges, and the summary dialog) — this caught a real ordering bug: marking
the read marker on chat *open* meant the summary was always empty by the
time you could tap it, since opening the room already advanced the marker
past everything you'd come to catch up on. Fixed by marking read on screen
*exit* (dispose) instead, so the marker reflects what was unread that whole
visit and updates once you leave.

go test / pytest / flutter analyze+test all pass.
2026-08-03 03:16:54 +00:00
..
autonomy_settings_screen.dart feat(ui): Soft Neutral + surface hierarchy across all screens 2026-08-03 01:59:28 +00:00
chat_screen.dart feat: implement 단톡 따라잡기 (group catch-up summary) — roadmap.md §2.7-A 2026-08-03 03:16:54 +00:00
contacts_screen.dart feat(ui): Soft Neutral + surface hierarchy across all screens 2026-08-03 01:59:28 +00:00
conversation_list_screen.dart feat: implement 단톡 따라잡기 (group catch-up summary) — roadmap.md §2.7-A 2026-08-03 03:16:54 +00:00
data_flow_screen.dart feat(ui): Soft Neutral + surface hierarchy across all screens 2026-08-03 01:59:28 +00:00
inbox_screen.dart feat(ui): Soft Neutral + surface hierarchy across all screens 2026-08-03 01:59:28 +00:00
onboarding_tone_screen.dart feat(ui): Soft Neutral + surface hierarchy across all screens 2026-08-03 01:59:28 +00:00
sessions_screen.dart feat(ui): Soft Neutral + surface hierarchy across all screens 2026-08-03 01:59:28 +00:00
signup_screen.dart feat(ui): Soft Neutral + surface hierarchy across all screens 2026-08-03 01:59:28 +00:00
splash_screen.dart feat(ui): Soft Neutral + surface hierarchy across all screens 2026-08-03 01:59:28 +00:00