Private
Public Access
1
0

Wire up webhook dispatch for all board/column/card events

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Catherine Renelle
2026-03-08 10:41:47 -04:00
parent e8c70bde87
commit a57f83c5cd
5 changed files with 17 additions and 0 deletions
@@ -5,6 +5,7 @@ import { withTenant } from '$lib/server/rls.js';
import { requireBoardView, requireBoardEditor, requireBoardOwner } from '$lib/server/guards.js'; import { requireBoardView, requireBoardEditor, requireBoardOwner } from '$lib/server/guards.js';
import { broadcast } from '$lib/server/realtime.js'; import { broadcast } from '$lib/server/realtime.js';
import { logActivity } from '$lib/server/activity.js'; import { logActivity } from '$lib/server/activity.js';
import { dispatchWebhooks } from '$lib/server/webhooks.js';
// Get single board with all columns and cards // Get single board with all columns and cards
export const GET: RequestHandler = async ({ params, locals }) => { export const GET: RequestHandler = async ({ params, locals }) => {
@@ -50,6 +51,7 @@ export const PATCH: RequestHandler = async ({ params, request, locals }) => {
const socketId = request.headers.get('X-Socket-ID'); const socketId = request.headers.get('X-Socket-ID');
broadcast(params.boardId, 'board:updated', { board: updated, socketId }); broadcast(params.boardId, 'board:updated', { board: updated, socketId });
broadcast(params.boardId, 'activity:new', { boardId: params.boardId, socketId }); broadcast(params.boardId, 'activity:new', { boardId: params.boardId, socketId });
dispatchWebhooks(tenant.id, 'board:updated', { boardId: params.boardId, board: updated });
return json({ board: updated }); return json({ board: updated });
}; };
@@ -6,6 +6,7 @@ import { withTenant } from '$lib/server/rls.js';
import { requireBoardEditor } from '$lib/server/guards.js'; import { requireBoardEditor } from '$lib/server/guards.js';
import { broadcast } from '$lib/server/realtime.js'; import { broadcast } from '$lib/server/realtime.js';
import { logActivity } from '$lib/server/activity.js'; import { logActivity } from '$lib/server/activity.js';
import { dispatchWebhooks } from '$lib/server/webhooks.js';
// Create column // Create column
export const POST: RequestHandler = async ({ params, request, locals }) => { export const POST: RequestHandler = async ({ params, request, locals }) => {
@@ -53,6 +54,7 @@ export const POST: RequestHandler = async ({ params, request, locals }) => {
const socketId = request.headers.get('X-Socket-ID'); const socketId = request.headers.get('X-Socket-ID');
broadcast(params.boardId, 'column:created', { column, socketId }); broadcast(params.boardId, 'column:created', { column, socketId });
broadcast(params.boardId, 'activity:new', { boardId: params.boardId, socketId }); broadcast(params.boardId, 'activity:new', { boardId: params.boardId, socketId });
dispatchWebhooks(tenant.id, 'column:created', { boardId: params.boardId, column });
return json({ column }, { status: 201 }); return json({ column }, { status: 201 });
}; };
@@ -5,6 +5,7 @@ import { withTenant } from '$lib/server/rls.js';
import { requireColumnEditor } from '$lib/server/guards.js'; import { requireColumnEditor } from '$lib/server/guards.js';
import { broadcast } from '$lib/server/realtime.js'; import { broadcast } from '$lib/server/realtime.js';
import { logActivity } from '$lib/server/activity.js'; import { logActivity } from '$lib/server/activity.js';
import { dispatchWebhooks } from '$lib/server/webhooks.js';
// Update column title or position // Update column title or position
export const PATCH: RequestHandler = async ({ params, request, locals }) => { export const PATCH: RequestHandler = async ({ params, request, locals }) => {
@@ -78,6 +79,7 @@ export const DELETE: RequestHandler = async ({ params, request, locals }) => {
const socketId = request.headers.get('X-Socket-ID'); const socketId = request.headers.get('X-Socket-ID');
broadcast(params.boardId, 'column:deleted', { columnId: params.columnId, socketId }); broadcast(params.boardId, 'column:deleted', { columnId: params.columnId, socketId });
broadcast(params.boardId, 'activity:new', { boardId: params.boardId, socketId }); broadcast(params.boardId, 'activity:new', { boardId: params.boardId, socketId });
dispatchWebhooks(tenant.id, 'column:deleted', { boardId: params.boardId, columnId: params.columnId });
return json({ ok: true }); return json({ ok: true });
}; };
@@ -7,6 +7,7 @@ import { requireColumnEditor } from '$lib/server/guards.js';
import { broadcast } from '$lib/server/realtime.js'; import { broadcast } from '$lib/server/realtime.js';
import { logActivity } from '$lib/server/activity.js'; import { logActivity } from '$lib/server/activity.js';
import { runAutomations } from '$lib/server/automations.js'; import { runAutomations } from '$lib/server/automations.js';
import { dispatchWebhooks } from '$lib/server/webhooks.js';
// Create card in column // Create card in column
export const POST: RequestHandler = async ({ params, request, locals }) => { export const POST: RequestHandler = async ({ params, request, locals }) => {
@@ -75,6 +76,7 @@ export const POST: RequestHandler = async ({ params, request, locals }) => {
const socketId = request.headers.get('X-Socket-ID'); const socketId = request.headers.get('X-Socket-ID');
broadcast(params.boardId, 'card:created', { card, columnId: params.columnId, socketId }); broadcast(params.boardId, 'card:created', { card, columnId: params.columnId, socketId });
broadcast(params.boardId, 'activity:new', { boardId: params.boardId, socketId }); broadcast(params.boardId, 'activity:new', { boardId: params.boardId, socketId });
dispatchWebhooks(tenant.id, 'card:created', { boardId: params.boardId, columnId: params.columnId, card });
return json({ card }, { status: 201 }); return json({ card }, { status: 201 });
}; };
@@ -8,6 +8,7 @@ import { broadcast } from '$lib/server/realtime.js';
import { logActivity } from '$lib/server/activity.js'; import { logActivity } from '$lib/server/activity.js';
import { notifyWatchers } from '$lib/server/notifications.js'; import { notifyWatchers } from '$lib/server/notifications.js';
import { runAutomations } from '$lib/server/automations.js'; import { runAutomations } from '$lib/server/automations.js';
import { dispatchWebhooks } from '$lib/server/webhooks.js';
// Get single card with full details // Get single card with full details
export const GET: RequestHandler = async ({ params, locals }) => { export const GET: RequestHandler = async ({ params, locals }) => {
@@ -182,6 +183,13 @@ export const PATCH: RequestHandler = async ({ params, request, locals }) => {
broadcast(params.boardId, 'card:updated', { card: updated, cardId: params.cardId, columnId: params.columnId, socketId }); broadcast(params.boardId, 'card:updated', { card: updated, cardId: params.cardId, columnId: params.columnId, socketId });
broadcast(params.boardId, 'activity:new', { boardId: params.boardId, cardId: params.cardId, socketId }); broadcast(params.boardId, 'activity:new', { boardId: params.boardId, cardId: params.cardId, socketId });
// Dispatch webhook — use card:moved if column changed, otherwise card:updated
if (body.columnId !== undefined) {
dispatchWebhooks(tenant.id, 'card:moved', { boardId: params.boardId, cardId: params.cardId, card: updated });
} else {
dispatchWebhooks(tenant.id, 'card:updated', { boardId: params.boardId, cardId: params.cardId, card: updated });
}
return json({ card: updated }); return json({ card: updated });
}; };
@@ -206,6 +214,7 @@ export const DELETE: RequestHandler = async ({ params, request, locals }) => {
const socketId = request.headers.get('X-Socket-ID'); const socketId = request.headers.get('X-Socket-ID');
broadcast(params.boardId, 'card:deleted', { cardId: params.cardId, columnId: params.columnId, socketId }); broadcast(params.boardId, 'card:deleted', { cardId: params.cardId, columnId: params.columnId, socketId });
broadcast(params.boardId, 'activity:new', { boardId: params.boardId, socketId }); broadcast(params.boardId, 'activity:new', { boardId: params.boardId, socketId });
dispatchWebhooks(tenant.id, 'card:deleted', { boardId: params.boardId, cardId: params.cardId, columnId: params.columnId });
return json({ ok: true }); return json({ ok: true });
}; };