* feat: workspace start of week column
* feat(l10n): add workspace setting for the first day of the week
Fixes#361
* feat: add Saturday as option
* chore: fix migration order
* chore: fix merge
---------
Co-authored-by: Henry <henry_ball@hotmail.co.uk>
* feat(api): add webhook CRUD API router and tests
Add tRPC router for managing workspace webhooks:
- list, create, update, delete endpoints (admin role required)
- test endpoint to send a synthetic payload to a webhook URL
- URL validation, event subscription filtering
- Unit tests for all router procedures
- Integration tests with PGlite test database
- Add vitest config and test infrastructure for API package
Depends on #391 (DB schema & repository).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(api): use assertPermission instead of assertUserInWorkspace
Replace assertUserInWorkspace with assertPermission("workspace:manage")
per project conventions. The permissions system is the preferred
authorization approach for new code.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(api): use @kan/db alias instead of relative imports in tests
Replace relative path imports (../../db/src/...) with the @kan/db
alias configured in vitest.config.ts for consistency and robustness.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(api): use webhookUrlSchema in router input validation
Cherry-pick router-related changes from b2cc9ac:
- Use extracted webhookUrlSchema zod validator in create/update
input schemas for consistent SSRF checks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(api): replace dynamic import with static import for webhook utility
Add packages/api/src/utils/webhook.ts with sendWebhookToUrl,
createCardWebhookPayload, and webhookUrlSchema. Replace the dynamic
import() in the test endpoint with a static import at the top of the
file for better tree-shaking, type-checking, and readability.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(api): align sendWebhooksForWorkspace tests with merged PR #392
The merged delivery utility uses client-side event filtering
(getActiveByWorkspaceId takes 2 args, not 3). Update test assertions
to match the actual implementation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Henry <30578846+hjball@users.noreply.github.com>
* feat(api): add webhook delivery utility and card event integration
Add the core webhook delivery logic and wire it into card mutations:
- Add sendWebhookToUrl() with HMAC-SHA256 signing, 10s timeout
- Add sendWebhooksForWorkspace() for fan-out delivery (fire-and-forget)
- Add createCardWebhookPayload() for building webhook payloads
- Fire webhooks on card create, update, move, and delete events
- Add unit tests for webhook utility functions
Depends on #391 (DB schema & repository).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(api): use correct boardId in webhook payloads and add rejection safety
- Fix bug where workspaceId was incorrectly passed as boardId in all
webhook payloads — now uses board's publicId via boardPublicId
- Replace void sendWebhooksForWorkspace() with .catch() to prevent
unhandled promise rejections if the DB query inside fails
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix(api): add SSRF protection to webhook delivery
Block webhook URLs targeting internal networks:
- Require HTTPS (reject HTTP)
- Block localhost, 127.0.0.1, ::1, 0.0.0.0
- Block cloud metadata endpoints (169.254.169.254, metadata.google.internal)
- Block private IP ranges (10.x, 172.16-31.x, 192.168.x)
- Add tests for all blocked URL patterns
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(api): use WebhookEvent type from schema instead of duplicating
Replace the hardcoded WebhookEventType union with the canonical
WebhookEvent type from @kan/db/schema, addressing reviewer feedback
on PR #392.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor(api): improve webhook delivery safety and validation
Cherry-pick delivery-related changes from b2cc9ac:
- Extract URL validation into reusable webhookUrlSchema zod validator
for SSRF checks
- Wrap sendWebhooksForWorkspace in try/catch to prevent unhandled
promise rejections
- Document SSRF risk mitigation on sendWebhookToUrl
- Add corresponding tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>