# 0061 — Integrar `notify_telegram` en deploy_server + bucle reactivo

## APP Metadata

| Campo | Valor |
|-------|-------|
| **ID** | 0061 |
| **Estado** | pendiente |
| **Prioridad** | media |
| **Tipo** | integration — `apps/deploy_server/`, `fn_operations/` |

## Dependencias

- `notify_telegram_go_infra` creada el 2026-05-07.
- `pass` con bot token guardado (`pass insert telegram/bot_token`).
- `pass` con chat_id (`pass insert telegram/chat_id`).
- `apps/deploy_server` (issue 0054 paralelo — refactor registry-first).
- `fn_operations/operations.go::ExecuteAndReact()` (bucle reactivo Go).

## Contexto

`notify_telegram_go_infra` fue creada como funcion atomica pero no esta integrada en ningun consumidor. El bucle reactivo (`assertions` que fallan) y los deploys (deploy_server) son los dos puntos donde alertas reales tendrian valor inmediato:

- **deploy_server**: hoy si un deploy falla solo queda en `deploy_logs`. El usuario tiene que mirar la BD o la TUI para enterarse. Ideal: notify_telegram con `[FAIL] <app>@<host>: <error>`.
- **bucle reactivo**: assertion `critical` falla → corruption detectada en datos. Hoy solo se persiste en `assertion_results`. Ideal: notify_telegram con `[CRITICAL] <entity>: <rule>: <value> (expected <expected>)`.

## Objetivo

Anadir hooks de notificacion en los dos puntos:

1. `deploy_server` envia notify al final de cada deploy (success o fail).
2. `fn_operations.ExecuteAndReact` envia notify cuando una assertion `critical` falla.

Ambos hooks usan `notify_telegram_go_infra` y leen credenciales de `pass`.

## Arquitectura

### Archivos afectados

- `apps/deploy_server/deployer.go` — anadir post-deploy hook que invoca notify.
- `apps/deploy_server/app.md` — declarar `notify_telegram_go_infra` en uses_functions.
- `fn_operations/operations.go` — extender `ExecuteAndReact` con notify hook.
- `fn_operations/operations_test.go` — test que mockea notify.
- NUEVA funcion `pass_telegram_creds_bash_infra` o helper Go para leer pass entries.

## Tareas

### Fase 1 — credenciales desde pass
1.1 Decidir naming: `pass insert telegram/bot_token` y `pass insert telegram/chat_id`.
1.2 Helper para leer ambas (existe `pass_get_bash_infra`, basta invocarlo).
1.3 Documentar setup en `docs/sync_setup.md` (no commitear values).

### Fase 2 — integracion deploy_server
2.1 En `deployer.go` post-deploy: si `deploy_telegram_enabled = true` (config en `deploy_targets`), construir mensaje y llamar `infra.NotifyTelegram(...)`.
2.2 Truncar mensaje a 4096 chars (la funcion ya lo hace, pero documentar).
2.3 Schema de `deploy_targets`: anadir columna `notify_telegram BOOLEAN DEFAULT false`.
2.4 CLI: `deploy_server target add ... --notify-telegram`.

### Fase 3 — integracion bucle reactivo
3.1 En `ExecuteAndReact`, tras evaluar assertions, si alguna `critical` fallo, construir mensaje y llamar notify.
3.2 Config: `assertion.notify_telegram BOOLEAN` (por assertion) — solo notifica si true.
3.3 Test `TestExecuteAndReact_NotifiesCriticalFailure` con notify mockeado.

### Fase 4 — docs + verificacion
4.1 Update CHANGELOG.md.
4.2 Manual test: forzar un deploy fail, verificar mensaje llega.
4.3 Manual test: forzar assertion fail, verificar mensaje llega.

## Riesgos

- Spam de notificaciones si una assertion falla repetidamente. Mitigacion: rate limiting (no enviar si ya se envio en ultima hora) — opcional, dejar para v2.
- Token expuesto en logs si `notify_telegram` lo loggea. Verificar que la funcion redacta el token.
- Sin pass: la integracion debe degradar silenciosa (log warning, no abortar deploy).

## Decisiones de diseno

- Mensajes en formato `[<level>] <subject>: <body>` para grep facil en chat.
- Markdown opcional (parseMode "Markdown") — abre superficie a inyeccion de markdown si el body viene de error externo. Default `parseMode=""` (plain).
- NO crear topic/thread de Telegram — un solo chat para todo. Si crece, refactor.
