Fizzy API y bridge FastAPI: dos formas de crear tarjetas en el kanban
kanban.d4r.es está protegido por el outpost de Authentik en Traefik, lo que complica cualquier automatización que intente hablar con Fizzy directamente por HTTP. Este post documenta las dos vías que funcionan en el stack D4R y presenta el bridge FastAPI que resuelve el problema de fondo.
El problema: Authentik intercepta todo
Fizzy expone una API JSON interna y acepta tokens Bearer, pero el middleware authentik@docker de Traefik intercepta cada petición a kanban.d4r.es antes de que llegue al contenedor de Rails. Si la petición no trae una sesión OIDC válida, el proxy devuelve un 302 al flujo OAuth de Authentik, independientemente del token que incluyas.
El resultado práctico: un curl con Authorization: Bearer <token> contra kanban.d4r.es recibe HTML de redirección, no JSON.
Vía 1: rails runner dentro del contenedor
La vía más robusta para automatizaciones internas es ejecutar código Ruby directamente dentro de app-fizzy-1 vía docker exec. No depende de HTTP, ni de tokens, ni de Authentik.
El patrón básico para crear una tarjeta:
docker exec app-fizzy-1 sh -lc 'cd /rails && bin/rails runner "
Current.user = User.find(%q{USER_ID})
board = Board.find(%q{BOARD_ID})
column = board.columns.find(%q{COLUMN_ID})
card = board.cards.create!(
title: %q{Título de la tarjeta},
creator_id: %q{USER_ID},
status: %q{published},
column: column,
last_active_at: Time.current
)
puts %Q(#{card.number} | #{card.title})
"'
Un detalle importante: el modelo Card tiene belongs_to :creator, default: -> { Current.user }. En el contexto de rails runner no hay usuario de sesión, así que hay que fijar Current.user explícitamente antes de crear la tarjeta, o pasar creator_id: de forma directa. Sin ese paso la validación Creator must exist bloquea la creación.
Estado DONE: closures
Fizzy no usa un campo status=done en la tarjeta. Las tarjetas cerradas tienen un registro en la tabla closures. El modelo expone el método card.close que crea ese registro usando Current.user como responsable del cierre.
Estado MAYBE: sin columna
Las tarjetas en la columna MAYBE? del board son simplemente tarjetas publicadas con column_id = NULL. No existe una columna «MAYBE» en la base de datos; es el estado por defecto de una tarjeta publicada sin columna asignada.
Vía 2: bridge FastAPI en el portal
Para que el resto del stack (n8n, scripts externos, el propio portal) pueda crear tarjetas sin conocer los detalles de rails runner ni tener acceso SSH al servidor, el portal en d4r.es expone dos endpoints propios que actúan como bridge:
| Endpoint | Función |
|---|---|
GET /api/kanban/project | Devuelve boards y columnas disponibles |
POST /api/kanban/cards | Crea una tarjeta en el board y columna indicados |
Ambos endpoints viven dentro del perímetro autenticado del portal y hablan con Fizzy internamente vía rails runner, sin pasar por el outpost de Authentik.
GET /api/kanban/project
Devuelve la estructura del proyecto Fizzy: boards y sus columnas.
{
"boards": [
{
"id": "03g30vmfynlu0z5sug5339p6x",
"name": "D4R",
"account_id": "03g30vkv0lv4glmwklmzjokp1",
"columns": [
{
"id": "03g329cj705u8zkzvpnb25ktn",
"name": "DOING",
"position": 1
}
]
}
]
}
POST /api/kanban/cards
Crea una tarjeta. Acepta board_id/column_id explícitos o los nombres como atajos:
{
"title": "Nueva tarjeta desde n8n",
"description": "Creada automáticamente",
"board_name": "D4R",
"column_name": "DOING"
}
Si no se especifica columna, la tarjeta cae en MAYBE? (sin columna). La respuesta devuelve el ID de Fizzy, el número de tarjeta y la URL directa.
Modelo de datos relevante
Fizzy usa SQLite. Las tablas más útiles para automatizaciones:
| Tabla | Uso |
|---|---|
boards | Espacios de trabajo (tableros) |
columns | Columnas de cada tablero |
cards | Tarjetas; column_id NULL = MAYBE? |
closures | Registro de tarjetas cerradas (DONE) |
card_not_nows | Tarjetas en estado NOT NOW |
Scripts en el repo
El repo incluye dos scripts bash en scripts/fizzy/ que encapsulan estos patrones:
scripts/fizzy/create_card.sh— crea una tarjeta individual con flags--title,--column,--donescripts/fizzy/import_cards.sh— importa tarjetas desde un CSV con columnastitle,column,done,description
Ambos usan SSH + docker exec internamente y no dependen del token HTTP de Fizzy ni de sesiones OIDC.