Files
telegram-gateway/migrations/001_init.sql
Gabriel Radureau 799e10dcc2
Some checks failed
Docker Build / build-and-push-image (push) Has been cancelled
Phase 2b — durable Postgres queue + worker (gated on DATABASE_URL)
Adds the async dispatch infrastructure :

- Postgres pool + embedded migration (CREATE TABLE/INDEX IF NOT EXISTS
  gateway_jobs). Auto-applied at boot. lib/pq driver (matches webapp
  convention).
- queue.go : Enqueue (idempotent on UNIQUE(bot_slug, update_id) — handles
  Telegram redelivery), Pop with FOR UPDATE SKIP LOCKED, MarkDone,
  MarkFailed with exponential backoff (30s → 2m → 10m → 1h → dead at 5).
- worker.go : goroutine that drains the queue, dispatches via the same
  Handler interface as sync, schedules retries on failure, notifies the
  user once when a job goes to dead.
- BotConfig gains `async: bool`. Registry refuses bots with async=true
  if DATABASE_URL is unset (queue=nil).
- Server : when bot.Async, the webhook ack is immediate ; the update
  payload is enqueued for the worker.

When DATABASE_URL is unset (current default), queue/worker stay disabled
and only sync handlers (echo, http, auth) work — no breaking change to
the running cluster.

Refs ~/.claude/plans/pour-les-notifications-on-inherited-seal.md § Phase 2.
2026-05-09 14:38:41 +02:00

25 lines
1020 B
SQL

-- Phase 2b — durable job queue for async handlers (shell, script, ollama).
-- Voir ~/.claude/plans/pour-les-notifications-on-inherited-seal.md § Phase 2.
CREATE TABLE IF NOT EXISTS gateway_jobs (
id BIGSERIAL PRIMARY KEY,
bot_slug TEXT NOT NULL,
handler_type TEXT NOT NULL,
update_id BIGINT NOT NULL,
payload JSONB NOT NULL,
attempts INT NOT NULL DEFAULT 0,
next_retry_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
status TEXT NOT NULL DEFAULT 'pending',
last_error TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
-- idempotence : si Telegram redélivre (ack > 60s), on ignore le doublon.
CONSTRAINT gateway_jobs_uniq_update UNIQUE (bot_slug, update_id)
);
CREATE INDEX IF NOT EXISTS gateway_jobs_pickable
ON gateway_jobs (next_retry_at)
WHERE status = 'pending';
CREATE INDEX IF NOT EXISTS gateway_jobs_status
ON gateway_jobs (status);