--- name: matrix_room_list kind: function lang: go domain: infra version: "0.1.0" purity: impure signature: "func MatrixRoomList(ctx context.Context, cfg MatrixRoomListConfig) ([]RoomSummary, error)" description: "Devuelve la lista de rooms Matrix en los que el usuario esta unido con metadata completa (nombre, alias, avatar, topic, encryption, space, DM, tags), ordenada por LastEventTs DESC." tags: ["matrix", "mautrix", "rooms", "summary", "state", "infra", "matrix-mas"] params: - name: ctx desc: "Context de la llamada. Cancela todas las HTTP requests en curso si se cancela." - name: cfg.Client desc: "Cliente mautrix autenticado. Debe haber completado al menos un Sync para que JoinedRooms devuelva datos frescos. No puede ser nil." output: "[]RoomSummary ordenado por LastEventTs DESC (rooms mas recientes primero). Si LastEventTs es 0 para todos, ordena alfabeticamente por Name." uses_functions: [] uses_types: [] returns: [] returns_optional: false error_type: "error_go_core" imports: - "maunium.net/go/mautrix" - "maunium.net/go/mautrix/event" - "maunium.net/go/mautrix/id" tested: true tests: - "3 rooms devueltos con metadata correcta" - "1 room sin m.room.name usa fallback name" - "IsDirect set correctamente segun m.direct" - "IsEncrypted set segun presencia de m.room.encryption" - "client nil devuelve error" test_file_path: "functions/infra/matrix_room_list_test.go" file_path: "functions/infra/matrix_room_list.go" --- ## Ejemplo ```go rooms, err := MatrixRoomList(ctx, MatrixRoomListConfig{Client: client}) if err != nil { log.Fatal(err) } for _, r := range rooms { fmt.Printf("%s [%s] enc=%v dm=%v members=%d\n", r.Name, r.RoomID, r.IsEncrypted, r.IsDirect, r.MemberCount) } // Output ejemplo: // General [!abc:server] enc=true dm=false members=12 // Alice [!xyz:server] enc=true dm=true members=2 ``` ## Cuando usarla Usar tras al menos un Sync completado, para poblar el sidebar de rooms en la UI. Llamar periodicamente con un TTL de 30s o tras recibir eventos `m.room.*` / `m.direct` en el sync stream. Ideal para el panel lateral de `matrix_client_pc` y `admin_panel`. ## Gotchas - **Costoso si muchos rooms**: cada room genera 3+ HTTP calls (State, Messages, m.tag). Para N=50 rooms son ~150 HTTP calls. Cachear en el backend con TTL 30s antes de exponer al frontend. - **Sin sync previo**: si se llama antes del primer Sync completado, `JoinedRooms` puede devolver lista vacia o stale. Siempre hacer Sync primero. - **LastEventTs puede ser 0**: mautrix Store en memoria no persiste el timestamp del ultimo evento. Si el store es en memoria (default), `Messages(limit=1)` hace una HTTP call extra por room. Si `LastEventTs == 0`, el room cae al fondo del orden (orden alfabetico por Name como desempate). - **UnreadCount siempre 0 en v0.1.0**: los notification counters vienen del Sync response, no de la API de state. TODO: obtenerlos del Syncer internamente. - **Spaces planos**: esta funcion devuelve joined rooms planos. No enumera recursivamente los children de un Space. Para arbol de Space, implementar funcion separada. - **Content.ParseRaw idempotente**: mautrix `parseRoomStateArray` llama `ParseRaw` al deserializar el state. La funcion usa `ensureParsed` que es no-op si ya esta parseado. - **IsDirect puede ser false si m.direct no esta sincronizado**: algunas implementaciones de Synapse no sincronizan `m.direct` inmediatamente. Si IsDirect es incorrecto, hacer un Sync completo primero.