---
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/matrix_room_list_test.go"
file_path: "functions/infra/matrix/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.
