Files
fn_registry/dev/issues/0163-matrix-custom-admin-panel.md
T
egutierrez daef7ea190 feat(matrix): MAS migration helpers + 2 flows + 15 issues + capability group
Helper functions (matrix-mas capability group):
- mas_client_register_bash_infra: register/sync OAuth clients via mas-cli
- mas_syn2mas_migration_bash_infra: dry-run + apply user migration to MAS
- synapse_msc3861_enable_go_infra: edit homeserver.yaml MSC3861 block (with diff)
- wellknown_oidc_patch_go_infra: patch well-known JSON with msc2965.authentication
- synapse_login_flows_check_go_infra: health-check post-migration login flows

Flows + issues for custom Matrix clients (PC + Android):
- 0010 matrix-client-pc: Wails + React+Mantine (issues 0147-0153)
- 0011 matrix-client-android: Kotlin + Compose (issues 0154-0161)
- 0162 enable MAS as auth provider (Synapse delegate) — EXECUTED on VPS
- 0163 custom admin panel propio (sustituye synapse-admin)

Production state (organic-machine.com):
- Synapse migrated SQLite -> Postgres
- MSC3861 active, password_config disabled
- 21 users + 41 access_tokens migrated via syn2mas
- 4 MAS clients registered (element, matrix_pc, matrix_android, admin_panel)
- synapse-admin container removed + Coolify route deleted
- well-known patched with org.matrix.msc2965.authentication

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-24 22:53:33 +02:00

190 lines
9.4 KiB
Markdown

---
id: "0163"
title: "Matrix admin panel propio: users, rooms, devices, sessions (sustituye synapse-admin)"
status: pending
priority: medium
created: 2026-05-24
related_flows: ["0010", "0011"]
related_issues: ["0162", "0147"]
dependencies: ["0162"]
tags: [matrix, admin, panel, react, mantine, mas, synapse, infra]
---
## Objetivo
Panel admin propio que reemplaza `https://admin-0cc4d3.organic-machine.com/#/users` (synapse-admin actual). Funciones equivalentes: gestionar usuarios (crear, deactivate, reset password, list devices, list rooms), gestionar rooms (list, members, kick, force-leave, delete), ver sesiones activas + revoke, ver media (storage usage por user). Auth via MAS OIDC con scope admin. Stack: React+Vite+Mantine+`@fn_library` (consistente con flows 0010/0011 + resto del registry).
## Por que reemplazar synapse-admin
- **Auth legacy**: synapse-admin usa admin token + password admin directo. Tras issue 0162 (MAS obligatorio) esto chirria. Mejor consume MAS OIDC + Synapse Admin API.
- **UI ajena**: stack distinto al resto del registry. Sin theming propio, sin `@fn_library`, sin coherencia visual con cliente PC (flow 0010).
- **Sin agentes**: no podemos integrar paneles especiales para `agents_and_robots`, devices del mesh (flow 0009), policies de widgets.
- **No extensible**: anadir "ver telemetria de calls LiveKit" o "audit log MAS" requiere fork pesado.
## Tareas
1. **Scaffold app**:
- `projects/element_agents/apps/matrix_admin_panel/`.
- Stack: React+Vite+TS+Mantine+`@fn_library`+`@tabler/icons-react`.
- Backend: Go con `mautrix-go` admin client + MAS OIDC client + `livekit-server-sdk-go` (para sesiones de call).
- Empaquetado: backend Go sirve frontend estatico embebido (`embed.FS`).
- Deploy: container Docker en `element_matrix_chat` stack o como service standalone via `deploy_server`.
2. **Auth flow MAS**:
- Cliente registrado en MAS (issue 0162 paso 2) con scope `urn:synapse:admin:*`.
- Login Web: OIDC redirect a MAS.
- Token guardado en httpOnly cookie + CSRF token.
3. **Modulos UI**:
- **Users**:
- Tabla virtualizada con `data-table` (cuando exista TS equivalente) o `mantine-react-table`.
- Columnas: localpart, displayname, avatar, admin, deactivated, last_seen, device_count.
- Acciones por row: view detail, deactivate/reactivate, reset password (force MAS link), list devices.
- Filtros: deactivated, admin, search.
- **User detail**:
- Sub-tabs: Profile, Devices (list + revoke individual), Rooms (membership list), Media (uploads + size), Sessions (MAS active sessions + revoke), Audit log (MAS).
- **Rooms**:
- Tabla: room_id, name, alias, members_count, encrypted, public, federated, state_events.
- Acciones: view detail, force-leave usuarios, delete room (purge), shutdown notif.
- **Room detail**:
- Members + roles, state events viewer (read-only JSON), media in room, widgets activos (interop con flow 0010 widget API).
- **Sessions** (MAS):
- Lista sesiones activas global.
- Filtro por user, IP, device, last_used.
- Revoke individual o bulk.
- **Federation**:
- Estado federation (Synapse `federation_handler`).
- Allowlist/blocklist servers.
- **Stats**:
- Resumen: users count, rooms count, mensajes/dia (ultima semana), media storage, calls activas (via LiveKit `RoomService.ListRooms`).
- Graficas con `@mantine/charts` o `recharts`.
4. **Capability groups en panel**:
- Reusa `AgentPanel` (flow 0010 issue 0153) para mostrar info de agentes registrados.
- Reusa `DevicePanel` (cuando flow 0009 vivo) para devices del mesh.
- Slot "Widgets policy": ver/aprobar capabilities concedidas globalmente, audit log.
5. **API endpoints backend Go**:
- `GET /api/users` -> proxy a Synapse `/_synapse/admin/v2/users` con auth MAS.
- `POST /api/users/<id>/deactivate`.
- `GET /api/rooms`, `POST /api/rooms/<id>/delete`.
- `GET /api/mas/sessions`, `POST /api/mas/sessions/<id>/revoke` (MAS admin API).
- `GET /api/livekit/rooms` (active calls).
- `GET /api/stats/summary`.
6. **Permisos**:
- Solo users con flag `admin: true` (Synapse) o scope MAS admin claim.
- Backend valida claim/flag en cada request.
- UI muestra "Access denied" si user logueado no es admin.
7. **Deploy**:
- Anadir container al `docker-compose.yml` de `element_matrix_chat`.
- O bien standalone via `deploy_server` (registry function existente).
- URL: `admin-af2f3d.organic-machine.com` o reusar `admin-0cc4d3.organic-machine.com` cuando se retire synapse-admin.
8. **Migracion synapse-admin -> panel propio**:
- Coexistencia 2 semanas: ambos vivos, MAS audita uso de cada uno.
- Cuando uso de synapse-admin = 0 durante 7 dias seguidos: detener container.
- Documentar en `docs/admin_panel_migration.md`.
9. **Tests**:
- `e2e/test_admin_login.sh` — MAS OIDC + scope admin valido -> acceso.
- `e2e/test_admin_login_denied.sh` — user no-admin recibe 403.
- `e2e/test_user_deactivate.sh` — flow completo deactivate + verify can't login.
- `e2e/test_room_purge.sh` — purge room + verify gone en Synapse.
- `e2e/test_session_revoke.sh` — revoke sesion MAS + user perdiendo acceso en <30s.
## Funciones del registry a crear
- `synapse_admin_client_go_infra` — wrapper Synapse Admin API.
- `mas_admin_client_go_infra` — wrapper MAS admin API (`/api/admin/v1/...`).
- `livekit_admin_client_go_infra``RoomService.ListRooms`, kick participant, etc.
- `oidc_admin_middleware_go_infra` — middleware Go que valida scope admin en cookie/Bearer.
- `UsersTable_ts_ui` — componente Mantine con virtualization + filtros.
- `RoomDetail_ts_ui` — componente con tabs Members/State/Media/Widgets.
- `SessionsList_ts_ui` — lista sesiones + revoke action.
- `StatsSummary_ts_ui` — componente con `@mantine/charts`.
- `FederationStatusPanel_ts_ui` — componente federation diag.
## Acceptance
- [ ] App compila + arranca como container Docker.
- [ ] Login via MAS OIDC con scope admin funciona.
- [ ] User no-admin recibe 403 al intentar entrar.
- [ ] Tabla users con 50+ rows + filtros + actions.
- [ ] Deactivate user end-to-end (verify cannot login despues).
- [ ] Room detail muestra members + state events JSON.
- [ ] Sessions MAS listadas + revoke individual.
- [ ] Stats: counts + media usage + active calls visibles.
- [ ] Tema visual coherente con cliente PC (flow 0010).
## Definition of Done
### Mecanica
- `go build` + `pnpm build` verde.
- Container Docker `<150MB` (Alpine + binary + static).
- Health endpoint `/health` 200.
- E2E suite pasa.
### Cobertura
| Escenario | Evidencia | Resultado |
|---|---|---|
| Golden: admin login + ver users | `e2e/test_admin_full_flow.sh` | tabla con users reales, actions visibles |
| Edge: 5000 users en tabla | benchmark scroll | 60fps, <300MB RAM |
| Edge: user sin admin entra | request directo | 403 + audit log |
| Edge: room con 200 members | view detail | render < 1s, paginacion OK |
| Error: Synapse Admin API caida | mock 500 | UI muestra error claro, no crash |
| Error: MAS session revoke fails | mock 500 | retry + toast error |
### Vida util (>=7 dias)
| Metrica | Umbral | Donde | Ventana |
|---|---|---|---|
| Crashes container | `0` | docker logs | 7 dias |
| Uso real | `>= 2 sesiones/semana` (operador) | nginx access log | 7 dias |
| Latency p95 endpoint /api/users | `< 800ms` (Synapse Admin paginado) | metrics | 7 dias |
| Acciones destructivas auditadas | `100%` (cada delete/revoke con audit row) | local audit DB | continuo |
### Anti-criterios
- NO marcar done si admin panel acepta token sin claim/flag admin.
- NO marcar done si delete room no purga media en DB Synapse.
- NO marcar done si UI deja al operador sin confirmacion en acciones destructivas (deactivate, purge, revoke).
- NO marcar done si lookalike de synapse-admin sin features propias (mejor mantener synapse-admin entonces).
## Notas
**Ventajas reales sobre synapse-admin:**
1. Coherencia visual + Mantine + theme propio.
2. Integracion con `agents_and_robots` (panel agente embedded).
3. Integracion con widgets policy (audit + override capabilities).
4. Integracion con LiveKit calls (ver rooms activos, force-end).
5. Audit log local SQLite con todas las acciones admin (synapse-admin no lo tiene).
6. Extensible — anadir tabs para mesh devices (flow 0009), telemetria, etc.
**Onboarding:**
1. `cd projects/element_agents/apps/matrix_admin_panel`.
2. `make dev` (Go backend + Vite frontend hot reload).
3. Visitar `http://127.0.0.1:8090` -> login MAS dev.
4. Deploy prod: ver `deploy/README.md`.
**Decisiones:**
- Backend Go > Python/Node: alinea con `mautrix-go` + reusa funciones del registry. Binario pequeno, deploy facil.
- Embedded static (Go `embed.FS`): un binario, sin docker multi-stage compleja.
- Audit log local SQLite > Postgres: panel admin no necesita HA, suficiente con SQLite local + backup periodico.
**Gotchas:**
- Synapse Admin API requiere `Bearer <admin_token>` — el panel intercambia OIDC token + admin claim por admin_token (con MAS admin API o con cuenta admin shared).
- MAS admin API esta en `/api/admin/v1/` — version unstable, monitorizar breaking changes.
- Federation tab: si federation deshabilitada (caso actual, ver `homeserver.yaml`), tab muestra "disabled" en vez de error.
**Roadmap post-DoD:**
- Bulk actions (mass deactivate, mass invite).
- Export reports CSV.
- Slack/email alerts en eventos criticos (server cae, MAS down, federation block).
- Multi-tenancy si llegan mas homeservers.
## Capability growth log
- v0.1.0 (2026-05-24) — issue creada.