---
id: "0148"
title: "matrix-client-pc rooms list + timeline con sync incremental"
status: pendiente
priority: alta
created: 2026-05-24
related_flows: ["0010"]
related_issues: ["0147", "0149"]
dependencies: ["0147"]
tags: [matrix, sync, timeline, rooms, react, mantine, sse]
---

## Objetivo

Sidebar con rooms (DMs + spaces + grupos) + panel central con timeline del room activo. Sync incremental con Synapse via long-poll `/sync`. Stream eventos backend -> frontend via SSE (`http_sse_server_go_infra`). Pagination scroll-up (cargar mensajes anteriores). Optimistic UI al enviar.

## Tareas

1. Backend Go:
   - `MatrixService.StartSync()` — long-poll `/sync` con since token persistido.
   - `MatrixService.SubscribeEvents() -> chan Event` — broadcaster events a frontend.
   - SSE endpoint `http://127.0.0.1:<puerto>/events` (autenticado con cookie session local).
   - Persistir state en SQLite (`store.db`): rooms, members, last_event_id por room.
2. Frontend React:
   - Hook `useMatrixRooms()` — devuelve `Room[]` ordenadas por last_activity.
   - Hook `useMatrixTimeline(roomId, limit=50)` — devuelve eventos + `loadMore()`.
   - Componente `RoomList` (sidebar con avatar, nombre, last_msg preview, unread badge).
   - Componente `Timeline` con `react-virtuoso` para scroll perf con miles de msgs.
   - Componente `EventBubble` (text, image, file, redacted, reaction agregada).
   - Reconnect automatico si SSE/sync cae (exponential backoff).
3. Tests:
   - `e2e/test_sync_basic.sh` — login + verificar que 3 rooms aparecen en sidebar.
   - `e2e/test_pagination.sh` — scroll-up carga mensajes anteriores sin gap.

## Funciones del registry a crear

- `matrix_room_subscribe_go_infra` — SSE wrapper: subscribe events de Synapse y push a clientes.
- `useMatrixTimeline_ts_ui` — hook React con dedupe + pagination + optimistic.
- `useMatrixRooms_ts_ui` — hook React rooms list.
- `RoomList_ts_ui` — componente sidebar Mantine.
- `EventBubble_ts_ui` — componente burbuja msg.

## Acceptance

- [ ] Sidebar lista rooms del usuario test, ordenados por actividad.
- [ ] Click en room muestra timeline ultimos 50 msgs.
- [ ] Scroll arriba carga msgs anteriores sin duplicar.
- [ ] Mensaje enviado desde Element Web aparece en <2s en la timeline.
- [ ] Cerrar app + abrir: state restaurado desde SQLite, no re-sync completo.
- [ ] Network kill + restore: sync se reanuda sin perder mensajes.

## Notas

- DMs vs rooms grupales: detectar via `m.direct` account data.
- Spaces (`m.space`): mostrar como grupos colapsables en sidebar.
- Edits + redactions: aplicar in-place, no duplicar bubble.
- Read receipts: TBD en otro issue, no bloquea este.
