docs(unibus_admin): bump 0.2.0 — account creation via invites + hard-delete
Document the wallet-model account flow in the Users tab: invite-link account creation (with the configurable client base URL for the join link), permanent hard-delete with strong confirmation, and the deploy gap (cluster still on bus v0.11.0; this branch merges after the bus reaches master). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,8 +2,8 @@
|
||||
name: unibus_admin
|
||||
lang: go
|
||||
domain: infra
|
||||
version: 0.1.0
|
||||
description: "Panel web de administración de unibus: un binario Go que sirve una SPA Mantine embebida y expone una REST API. Tiene la identidad ADMIN del operador, firma cada petición al plano de control del bus, y gestiona rooms, miembros, claves, usuarios y el estado del cluster."
|
||||
version: 0.2.0
|
||||
description: "Panel web de administración de unibus: un binario Go que sirve una SPA Mantine embebida y expone una REST API. Tiene la identidad ADMIN del operador, firma cada petición al plano de control del bus, y gestiona rooms, miembros, claves, usuarios (alta por invitación + baja por hard-delete) y el estado del cluster."
|
||||
tags: [service, messaging, admin, nats, e2e]
|
||||
uses_functions:
|
||||
- sign_ed25519_go_cybersecurity
|
||||
@@ -78,7 +78,7 @@ no expone. Nunca reimplementa firma ni cripto.
|
||||
|---|---|---|
|
||||
| **Cluster** | up/down + posture (enforce/acl/tls/cluster/store) + latencia de cada nodo | `GET /healthz` (auth-exempt) de los nodos en `--nodes`, TLS pin a la CA del bus |
|
||||
| **Rooms** | listar (rooms del admin), crear (subject + E2E/persist/firmado), ver miembros, invitar, expulsar+rekey | `pkg/client` (mutaciones) + GET firmado (miembros) |
|
||||
| **Users** | listar/añadir/revocar la allowlist del bus | `pkg/client` (`ListUsers`/`AddUser`/`RevokeUser`) contra la API admin-only del plano de control, firmando como el operador. Funciona en cluster (los nodos escriben al mismo store que las rooms) sin acceso directo al store. `--db` queda como fallback single-node opcional |
|
||||
| **Users** | listar la allowlist; **crear usuario** por enlace de invitación (modelo wallet, sin manejar claves); añadir por clave conocida; **revocar** (status flip, auditable) y **eliminar** (hard-delete permanente, con confirmación fuerte) | `pkg/client` (`ListUsers`/`AddUser`/`RevokeUser`/`DeleteUser`/`CreateInvite`/`ListInvites`) contra la API admin-only del plano de control, firmando como el operador. Funciona en cluster sin acceso directo al store. `--db` queda como fallback single-node opcional |
|
||||
|
||||
## Cómo arrancar
|
||||
|
||||
@@ -127,8 +127,36 @@ ofuscado (`admin-<hash>.organic-machine.com`). Credenciales en `pass`
|
||||
(`unibus/admin-panel-password`, `unibus/admin-panel-url`). Artefactos de deploy en
|
||||
`deploy/`.
|
||||
|
||||
## Creación de usuarios (modelo wallet) y enlace de invitación
|
||||
|
||||
La pestaña Users crea usuarios SIN que el operador maneje claves: «Crear usuario»
|
||||
acuña un enlace de invitación de un solo uso (`POST /api/invites` → bus
|
||||
`POST /invites`, admin-only). El gateway construye el enlace
|
||||
`<<APP_BASE>>/join?token=XXX`, donde `<<APP_BASE>>` es la URL del **cliente
|
||||
final** (la página que hospeda `/join`), NO la del panel. Se configura en el
|
||||
gateway con `--join-base-url https://chat.unibus.example` o la variable
|
||||
`UNIBUS_JOIN_BASE_URL`; el valor se expone en `/api/me` (`join_base_url`). Si no
|
||||
se configura, la SPA usa su propio origen como respaldo y avisa de configurarlo.
|
||||
El usuario abre el enlace en su dispositivo, genera ahí su par de claves (la
|
||||
privada nunca sale del equipo) y se registra (`POST /register`, lo consume la
|
||||
página `/join` del cliente web — ver el contrato en el report del bus).
|
||||
|
||||
«Eliminar» es un **hard-delete permanente** (`DELETE /api/users/{pub}` → bus
|
||||
`DELETE /users/{signpub}`), distinto de «Revocar» (status flip auditable). La UI
|
||||
exige teclear el handle para confirmarlo (no se dispara por un clic accidental).
|
||||
|
||||
## Gaps conocidos
|
||||
|
||||
- **Cuentas (invites + hard-delete) contra el cluster desplegado**: el gateway y la
|
||||
SPA ya consumen `POST/GET /api/invites` y `DELETE /api/users/{pub}`, verificados
|
||||
end-to-end contra un `membershipd` v0.12.0 local (crear invite → registrar por
|
||||
`/register` sin firma → aparece en `/users` → hard-delete → desaparece) y vía
|
||||
`--mock`. El gap es de **despliegue**: el cluster corre hoy v0.11.0 (sin
|
||||
`/invites`/`/register`/`DELETE /users`), así que la pestaña Users sólo creará/
|
||||
eliminará cuentas en producción cuando el bus se actualice a v0.12.0 (rollout
|
||||
pendiente). Verificado contra el cluster vivo: `/register` devuelve 401 en
|
||||
magnus/homer/datardos (ruta aún no desplegada) frente a 400 en el nodo v0.12.0
|
||||
local. El merge de esta rama del panel a master debe seguir al merge del bus.
|
||||
- **Users contra el cluster desplegado**: el código del plano de control (unibus
|
||||
master, v0.10.0) ya expone la API admin-only de users (`GET/POST /users`,
|
||||
`POST /users/{signpub}/revoke`) y el gateway la consume firmando como el operador.
|
||||
@@ -145,3 +173,22 @@ ofuscado (`admin-<hash>.organic-machine.com`). Credenciales en `pass`
|
||||
- **Invite a room E2E**: requiere las claves públicas (sign_pub + kex_pub) del
|
||||
invitado en hex, porque la clave de room se sella contra su X25519. La UI las pide
|
||||
manualmente; no hay directorio de claves públicas todavía.
|
||||
|
||||
## Capability growth log
|
||||
|
||||
- v0.2.0 (2026-06-07) — capa de CUENTAS estilo WhatsApp sobre el bus v0.12.0. El
|
||||
gateway gana `POST/GET /api/invites` (acuñar/listar invitaciones de un solo uso,
|
||||
consumiendo `client.CreateInvite/ListInvites`) y `DELETE /api/users/{pub}`
|
||||
(hard-delete, `client.DeleteUser`), con la misma doble vía que el resto de users
|
||||
(plano de control firmado en cluster / store directo en single-node). El enlace de
|
||||
invitación `<<APP_BASE>>/join?token=…` lo construye el gateway desde
|
||||
`--join-base-url` / `UNIBUS_JOIN_BASE_URL` (URL del cliente final, no del panel),
|
||||
expuesto en `/api/me`. La SPA añade a la pestaña Users: botón «Crear usuario»
|
||||
(modal handle+rol+caducidad → enlace copiable), card de invitaciones pendientes
|
||||
(handle, rol, token parcial, caducidad, copiar enlace), y botón «Eliminar» con
|
||||
confirmación FUERTE (teclear el handle) que distingue el borrado permanente del
|
||||
revoke. Verificado: flujo e2e contra `membershipd` v0.12.0 local (invite → register
|
||||
por curl sin firma → aparece en /users → re-register 409 → hard-delete → desaparece)
|
||||
y gateway vía `--mock` (las rutas nuevas + el SPA embebido sirven). El cluster vivo
|
||||
sigue en v0.11.0 (rollout del bus pendiente del orquestador); esta rama del panel se
|
||||
mergea a master tras el merge del bus a master. build/vet/web-build verdes.
|
||||
|
||||
Reference in New Issue
Block a user