docs: T-HUB README and validation guide
README: architecture diagrams (single account, shared accounts, components), status per platform, outreach, hardware and bandwidth requirements, ports, security practices and what to monitor. docs/T-HUB-VALIDACION.txt: per-commit test plan for reviewers.
This commit is contained in:
parent
f6840ff69b
commit
c7d133c395
2 changed files with 417 additions and 6 deletions
156
docs/T-HUB-VALIDACION.txt
Normal file
156
docs/T-HUB-VALIDACION.txt
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
T-HUB - Guía de validación de cambios
|
||||
=====================================
|
||||
Para: quien revise y valide los cambios de T-HUB antes de llevarlos a
|
||||
upstream (gitlab.moxexley.com/mediatools/tacticalmediahub) o a producción.
|
||||
Base: upstream main a6843e9.
|
||||
|
||||
Commits a revisar (en orden):
|
||||
|
||||
feat: wire the Instagram connector into connect and publishing
|
||||
feat: outreach contacts - track hand-written DMs per collective
|
||||
chore(db): force row-level security on media_assets
|
||||
style / docs: estilo de la web, logo y documentación
|
||||
|
||||
Cada commit se puede revisar y aplicar por separado.
|
||||
|
||||
|
||||
0. PREPARACIÓN
|
||||
--------------
|
||||
corepack enable
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm exec turbo run build typecheck --filter=@tactical-media-broadcast-hub/api...
|
||||
|
||||
Para los tests que usan Postgres hacen falta las variables *_IT_DATABASE_URL
|
||||
de cada suite; sin ellas se saltan (comportamiento de upstream).
|
||||
|
||||
Lint: apps/api ya tenía 54 errores antes de estos cambios y sigue teniendo
|
||||
los mismos 54. Los archivos tocados pasan eslint sin errores.
|
||||
|
||||
|
||||
1. INSTAGRAM
|
||||
----------------------
|
||||
Qué cambia
|
||||
- createInstagramConnector registrado en
|
||||
apps/api/src/connections/connector-registry.ts y en connectorFor de
|
||||
apps/api/src/publishing/publishing.service.ts.
|
||||
- Política de publicación instagram: { idempotency: "none" } en
|
||||
packages/connector-runtime/src/policy.ts (Graph no tiene clave de
|
||||
idempotencia; un envío dudoso no se repite).
|
||||
- Las credenciales de la app de Meta se leen SOLO de
|
||||
INSTAGRAM_CLIENT_ID / INSTAGRAM_CLIENT_SECRET. Se quitan los campos
|
||||
clientId/clientSecret del formulario y ya no se copian al vault.
|
||||
- El proveedor sale desactivado (connectEnabled=false) sin esas dos
|
||||
variables, con una nota que lo explica.
|
||||
- Si la persona autoriza varias cuentas de Instagram en el diálogo de
|
||||
Meta, la conexión falla en vez de elegir la primera.
|
||||
|
||||
Tests automáticos
|
||||
pnpm --filter @tactical-media-broadcast-hub/connector-instagram test
|
||||
esperado: 37 pass
|
||||
cd apps/api && npx vitest run src/connections
|
||||
esperado: 18 pass (incluye "offers Instagram only with the Hub's
|
||||
Facebook app configured, and keeps the app secret out of the browser")
|
||||
|
||||
Prueba manual (entorno de pruebas, app de Meta en modo desarrollo)
|
||||
1. Sin variables: GET /connections/providers -> instagram enabled=false.
|
||||
2. Con INSTAGRAM_CLIENT_ID/SECRET: enabled=true.
|
||||
3. En la app de Meta, Valid OAuth Redirect URI =
|
||||
${API_URL}/connections/callback (exacto).
|
||||
4. Canales -> Conectar Instagram con una cuenta Tester Business/Creator
|
||||
vinculada a una página -> vuelve con connect=success y la conexión
|
||||
sale healthy con @usuario.
|
||||
5. Autorizar dos cuentas a la vez -> connect=failure.
|
||||
|
||||
Límites conocidos (no resueltos en este commit)
|
||||
- Publicar imágenes NO funciona todavía: Meta descarga la imagen de una
|
||||
URL pública y los medios están cifrados en el almacén. Hace falta un
|
||||
endpoint temporal que sirva el JPEG descifrado (TTL corto, solo
|
||||
borradores aprobados). Además la regla del proyecto es que los bytes
|
||||
no pasen por la API. Decisión de diseño pendiente.
|
||||
- refreshCredentials usa grant_type=ig_refresh_token contra
|
||||
graph.facebook.com, que es el método de "Instagram Login", no de
|
||||
Facebook Login. Comprobar con un token real; posible caducidad a 60
|
||||
días.
|
||||
|
||||
|
||||
2. OUTREACH
|
||||
---------------------
|
||||
Qué cambia
|
||||
- Migración 041_outreach.sql: tabla outreach_contacts con RLS
|
||||
ENABLE+FORCE y WITH CHECK, índice único (workspace, platform,
|
||||
lower(handle)), trigger de workspace inmutable, permisos
|
||||
outreach.view (Owner, Admin, Editor, Moderator) y outreach.manage
|
||||
(Owner, Admin, Editor).
|
||||
- API: GET/POST/PATCH/DELETE /outreach/contacts (apps/api/src/outreach).
|
||||
Importación de hasta 500 por petición; las cuentas ya existentes se
|
||||
saltan. La auditoría guarda altas, bajas y cambios de estado, nunca el
|
||||
texto del mensaje.
|
||||
- Web: /outreach (barra lateral y "More"). Importar CSV, plantilla con
|
||||
{name} y {handle}, filtros, "Copy & open profile", contador diario
|
||||
con aviso a partir de 20.
|
||||
- El Hub no envía mensajes. No hay llamadas a APIs de redes en este
|
||||
módulo. Ver README, sección "Panel Outreach", para el motivo.
|
||||
|
||||
Tests automáticos
|
||||
cd apps/api && npx vitest run src/outreach esperado: 8 pass
|
||||
pnpm --filter @tactical-media-broadcast-hub/web test:outreach
|
||||
esperado: 4 pass
|
||||
|
||||
Verificado además (fuera del repo): la migración 041 y todas las
|
||||
consultas del servicio se ejecutaron sobre PGlite (Postgres compilado a WASM)
|
||||
como rol sin privilegios con app.workspace_id fijado: aislamiento entre
|
||||
colectivos, salto de duplicados en mayúsculas/minúsculas, sellos de
|
||||
sent_at/replied_at, vuelta a "todo" limpia los sellos.
|
||||
|
||||
Prueba manual
|
||||
1. Aplicar migraciones (src/db/migrate.cli.ts).
|
||||
2. Como Editor: importar
|
||||
name,platform,handle,profileUrl,category,language
|
||||
Prueba,bluesky,prueba.bsky.social,https://bsky.app/profile/prueba.bsky.social,test,es
|
||||
-> "1 contacts added". Reimportar -> "0 added, 1 already on the list".
|
||||
3. Plantilla "Hola {name}" -> el contacto pendiente recibe "Hola Prueba".
|
||||
4. Copy & open profile -> abre el perfil en otra pestaña con el texto
|
||||
en el portapapeles.
|
||||
5. Mark sent -> estado sent y sello de fecha; aparece outreach.sent en
|
||||
/audit sin el texto del mensaje.
|
||||
6. Como Analyst (sin outreach.view) -> GET /outreach/contacts da 403.
|
||||
7. Desde otro colectivo -> la lista no muestra los contactos del primero
|
||||
y PATCH sobre su id da 404.
|
||||
8. profileUrl con http:// o javascript: -> 400.
|
||||
|
||||
|
||||
3. RLS EN media_assets
|
||||
----------------------
|
||||
Qué cambia
|
||||
- 042_media_assets_rls.sql: ENABLE + FORCE RLS y política con
|
||||
WITH CHECK.
|
||||
- Las consultas a media_assets (media.service.ts, publishing.service.ts)
|
||||
filtran también por app.workspace_id.
|
||||
|
||||
Verificación
|
||||
- cd apps/api && npx vitest run src/media src/publishing
|
||||
esperado: 114 pass, 49 skipped (necesitan Postgres).
|
||||
- En la base de datos, después de migrar:
|
||||
SELECT relrowsecurity, relforcerowsecurity
|
||||
FROM pg_class WHERE relname = 'media_assets'; -> t, t
|
||||
- Prueba manual: subir un medio en el colectivo A y pedir
|
||||
GET /media/<id> con sesión del colectivo B -> 404.
|
||||
|
||||
|
||||
4. ESTILO Y LOGO
|
||||
----------------
|
||||
- apps/web/src/app/globals.css: paleta de acampada26s.net sobre fondo
|
||||
oscuro (negro, blanco, neón #00e5ff), títulos h1/h2 en Anton en
|
||||
mayúsculas. Regla que pone texto negro en botones neón.
|
||||
- Fuente Anton en apps/web/public/fonts (licencia SIL OFL incluida).
|
||||
- Logo: docs/brand/t-hub.svg, también como favicon.
|
||||
- Página pública de buzón (/submit/[token]) con el mismo color.
|
||||
Comprobar visualmente: login, Compose, Approvals, Channels, Outreach,
|
||||
Control Room y /submit/<token>, en escritorio y móvil. Buscar textos
|
||||
blancos sobre neón o bloques que hayan quedado con el rojo anterior.
|
||||
|
||||
|
||||
5. SEGURIDAD
|
||||
------------
|
||||
La revisión de seguridad se entrega en privado a quien mantiene el
|
||||
despliegue. Los fallos se comunican por canal privado, no en issues.
|
||||
Loading…
Add table
Add a link
Reference in a new issue