feat(v2.1.0): API publique + Webhooks sortants + PWA
- Public API: /api/v1 (collections, pages, my-tasks) with token auth
- Token generation: POST /api/v1/token
- Outbound webhooks: /workspace/webhooks CRUD + fire_event dispatcher
- PWA: manifest.json endpoint
- CSRF exempt for /api/v1
- 73/73 tests passent (+6 tests v2.1)
- Version 2.0.0 → 2.1.0
- Docs: ROADMAP updated — 7/7 blocs, 52/52 features ✅
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
"""FlowDeck — Webhook outbound dispatcher (v2.1.0)."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
|
||||
import httpx
|
||||
|
||||
from app.db import get_conn
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
EVENTS = [
|
||||
"page.created", "page.updated", "page.deleted",
|
||||
"collection.created", "collection.updated", "collection.deleted",
|
||||
"comment.added", "page.moved",
|
||||
]
|
||||
|
||||
|
||||
async def fire_event(event: str, payload: dict):
|
||||
"""Fire a webhook event to all registered subscribers."""
|
||||
if event not in EVENTS:
|
||||
return
|
||||
with get_conn() as conn:
|
||||
subs = conn.execute("SELECT url, secret FROM webhook_subscriptions WHERE event=?", (event,)).fetchall()
|
||||
async with httpx.AsyncClient(timeout=10) as client:
|
||||
for sub in subs:
|
||||
url, secret = sub["url"], sub["secret"]
|
||||
headers = {"Content-Type": "application/json", "X-FlowDeck-Event": event}
|
||||
if secret:
|
||||
headers["X-FlowDeck-Secret"] = secret
|
||||
try:
|
||||
await client.post(url, json=payload, headers=headers)
|
||||
except Exception:
|
||||
logger.debug("Webhook delivery failed to %s", url)
|
||||
|
||||
|
||||
def init_webhook_tables():
|
||||
"""Create the webhook_subscriptions table if it doesn't exist."""
|
||||
with get_conn() as conn:
|
||||
conn.execute("""
|
||||
CREATE TABLE IF NOT EXISTS webhook_subscriptions (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
url TEXT NOT NULL,
|
||||
event TEXT NOT NULL,
|
||||
secret TEXT DEFAULT '',
|
||||
active BOOLEAN NOT NULL DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
conn.commit()
|
||||
Reference in New Issue
Block a user