Add v0.5 webhook notification release tickets #41

Merged
Twyco merged 1 commits from codex/v0.5-webhook-notification/release-ticket-docs into main 2026-04-24 13:29:06 +00:00
9 changed files with 484 additions and 0 deletions
+2
View File
@@ -7,10 +7,12 @@ This directory contains small, ordered implementation tickets grouped by release
- [Release 0.1 - Kanban, Ticketing, Users, and Permissions Foundation](0.1-kanban-foundation/01-admin-and-user-management-foundation.md) - [Release 0.1 - Kanban, Ticketing, Users, and Permissions Foundation](0.1-kanban-foundation/01-admin-and-user-management-foundation.md)
- [Release 0.2 - Gitea Integration](0.2-gitea-integration/01-git-provider-abstraction-and-gitea-foundation.md) - [Release 0.2 - Gitea Integration](0.2-gitea-integration/01-git-provider-abstraction-and-gitea-foundation.md)
- [Release 0.3 - GitHub Integration](0.3-github-integration/README.md) - [Release 0.3 - GitHub Integration](0.3-github-integration/README.md)
- [Release v0.5 - Webhook Notifications](v0.5-webhook-notification/README.md)
## Scope notes ## Scope notes
- Release `0.1` covers the core Kanban, ticket, user, team, and permission foundation. - Release `0.1` covers the core Kanban, ticket, user, team, and permission foundation.
- Release `0.2` covers the first Git provider integration with Gitea. - Release `0.2` covers the first Git provider integration with Gitea.
- Release `0.3` covers GitHub Cloud as the second Git provider using the existing provider abstraction and user connection model. - Release `0.3` covers GitHub Cloud as the second Git provider using the existing provider abstraction and user connection model.
- Release `v0.5` covers project-scoped webhook notification actions for ticket status changes.
- Roadmap and other currently out-of-scope items are intentionally not broken into tickets here. - Roadmap and other currently out-of-scope items are intentionally not broken into tickets here.
@@ -0,0 +1,48 @@
# Ticket Implementation Guide
This guide describes how to implement release tickets in this repository.
## Branching
- Use exactly one branch per ticket.
- Use the branch format `codex/<release-name>/<ticket-slug>`.
- For release `v0.5-webhook-notification`, branch names must look like `codex/v0.5-webhook-notification/01-notification-action-foundation`.
- The first ticket branch starts from the release base branch chosen by the maintainer.
- Every later ticket branch starts from the previous ticket branch:
- ticket 02 branches from ticket 01
- ticket 03 branches from ticket 02
- ticket 04 branches from ticket 03
- continue this pattern until the release is complete
- Do not mix multiple release tickets in one branch.
## Implementation Flow
- Read the ticket completely before changing files.
- Keep the implementation limited to the ticket scope.
- Preserve existing UI, API, and MCP behavior unless the ticket explicitly changes it.
- Follow existing project conventions before introducing new patterns.
- Use actions or services for reusable business logic.
- Use FormRequest classes for request validation.
- Keep app-specific frontend types under `resources/js/types`; do not define them inside `.vue` files.
- Generate Wayfinder output when frontend-facing routes or controllers change.
## Finishing A Ticket
Each ticket must end with:
- Relevant automated tests for the changed behavior.
- Formatting and code generation required by the files changed.
- `git diff --check`.
- `git add` for only the ticket's intended files.
- One commit with a concise ticket-specific message.
- `git push origin <branch-name>`.
Do not leave partially staged work for the next ticket. The next ticket should start from the pushed branch of the completed ticket.
## Verification Defaults
- PHP changes: run `vendor/bin/pint --dirty --format agent`.
- Laravel behavior changes: run targeted `php artisan test --compact ...`.
- Route or frontend controller changes: run `php artisan wayfinder:generate --with-form --no-interaction`.
- Vue or TypeScript changes: run `npm run types:check`.
- Documentation-only changes: `git diff --check` is enough unless the ticket says otherwise.
@@ -0,0 +1,62 @@
# 01 Notification Action Foundation
Implementation guide: [Ticket Implementation Guide](../ticket-implementation-guide.md)
## Branch
`codex/v0.5-webhook-notification/01-notification-action-foundation`
Start this branch from the chosen release base branch.
## Goal
Create the backend foundation for project-scoped notification actions and delivery logs.
## Requirements
- Add database tables for configured notification actions and delivery attempts.
- Add models, factories, resources, enums, and reusable actions or services for notification action management.
- A notification action belongs to a project.
- A notification action has a name, enabled flag, event type, channel, channel configuration, optional message template, and secret delivery URL.
- Supported event type for this release: `ticket_status_changed`.
- Supported channels for this release: `webhook` and `discord`.
- Store webhook and Discord URLs encrypted and hide them from serialized model/resource output.
- Add delivery logs that can record action, event type, channel, delivery status, attempt count, HTTP status, response or error excerpt, payload metadata, and timestamps.
- Keep the schema extensible for later event types and channels.
## Acceptance Criteria
- Notification action records can be created, updated, listed, and deleted through backend actions or services.
- Secret URLs are encrypted at rest and are not exposed by resources.
- Delivery log records can represent pending, succeeded, failed, and retryable attempts.
- The foundation does not dispatch external HTTP requests yet.
- Existing ticket, project, API, and MCP behavior is unchanged.
## Tests
- Model tests for relationships, casts, enum handling, and hidden secret URL output.
- Factory tests or feature-backed assertions proving webhook and Discord action records can be created.
- Action/service tests for create, update, delete, and project ownership behavior.
- Delivery log tests for supported statuses and relationship integrity.
## Verification
- `vendor/bin/pint --dirty --format agent`
- `php artisan test --compact tests/Feature/Models tests/Feature/Notifications`
- `git diff --check`
## Commit And Push
- Commit only this ticket's changes.
- Push with `git push origin codex/v0.5-webhook-notification/01-notification-action-foundation`.
## Out of Scope
- Project settings UI
- Ticket status changed event dispatch
- Actual webhook or Discord HTTP delivery
- User bell notifications
- Unread counters
- Slack, Teams, email, or other channels
- Incoming webhooks
- API or MCP management endpoints
@@ -0,0 +1,69 @@
# 02 Project Notification Settings UI
Implementation guide: [Ticket Implementation Guide](../ticket-implementation-guide.md)
## Branch
`codex/v0.5-webhook-notification/02-project-notification-settings-ui`
Start this branch from `codex/v0.5-webhook-notification/01-notification-action-foundation`.
## Goal
Add project settings UI for managing notification actions.
## Requirements
- Add a project settings page at `projects/{project}/settings/notifications`.
- Add a settings navigation link alongside general, board, ticket, and repository settings.
- Project admins can list, create, update, enable, disable, and delete project notification actions.
- The create and update forms support:
- name
- event type
- channel
- enabled flag
- delivery URL
- message template for Discord
- Existing secret URLs stay hidden after save.
- Updating an action only replaces the secret URL when a new URL is submitted.
- Show the fixed template variables in the UI: `$url`, `$ticket_key`, `$ticket_title`, `$project_name`, `$status_from`, `$status_to`, and `$actor_name`.
- Add frontend types under `resources/js/types`.
- Generate Wayfinder output for the new routes and controller methods.
## Acceptance Criteria
- Project admins can manage notification actions from project settings.
- Non-admin project users cannot access the notification settings page or mutate notification actions.
- Validation errors are shown next to the relevant form fields.
- Saved notification actions show their name, event type, channel, enabled state, and created or updated date without exposing the secret URL.
- Existing project settings pages continue to work.
## Tests
- Feature tests for page access, create, update, enable/disable, delete, validation, and authorization.
- Inertia prop assertions for the notification action list and template variable metadata.
- Regression test that secret URLs are not rendered back in page props.
## Verification
- `php artisan wayfinder:generate --with-form --no-interaction`
- `vendor/bin/pint --dirty --format agent`
- `php artisan test --compact tests/Feature/Projects`
- `npm run types:check`
- `git diff --check`
## Commit And Push
- Commit only this ticket's changes.
- Push with `git push origin codex/v0.5-webhook-notification/02-project-notification-settings-ui`.
## Out of Scope
- Ticket status changed event dispatch
- Actual webhook or Discord HTTP delivery
- Delivery attempt screens
- User bell notifications
- Unread counters
- Slack, Teams, email, or other channels
- Incoming webhooks
- API or MCP management endpoints
@@ -0,0 +1,67 @@
# 03 Ticket Status Changed Trigger
Implementation guide: [Ticket Implementation Guide](../ticket-implementation-guide.md)
## Branch
`codex/v0.5-webhook-notification/03-ticket-status-changed-trigger`
Start this branch from `codex/v0.5-webhook-notification/02-project-notification-settings-ui`.
## Goal
Trigger notification deliveries when a ticket status actually changes.
## Requirements
- Add a `TicketStatusChanged` event or equivalent internal event object.
- Emit the event from the existing ticket move action only when the ticket moves to a different status.
- Do not emit the event for no-op moves where the destination status is already current.
- Build a reusable event payload that includes:
- project id, key, and name
- ticket id, key, title, and absolute ticket URL
- actor id and name when available
- origin status id and label
- destination status id and label
- occurred timestamp
- Add a listener or action that finds enabled project notification actions for `ticket_status_changed`.
- Queue one delivery job per matching action.
- Keep existing worklog behavior for status changes.
## Acceptance Criteria
- Moving a ticket to a new status queues delivery jobs for all enabled matching actions in the ticket project.
- Disabled actions are ignored.
- Actions from other projects are ignored.
- No-op moves do not queue delivery jobs.
- Ticket movement responses and worklog entries remain unchanged.
## Tests
- Ticket move feature tests asserting jobs are queued for enabled matching actions.
- Tests asserting disabled, foreign-project, and wrong-event actions are ignored.
- Test asserting no-op moves do not dispatch notifications.
- Test asserting the event payload contains the expected ticket URL and status labels.
## Verification
- `vendor/bin/pint --dirty --format agent`
- `php artisan test --compact tests/Feature/Projects tests/Feature/Notifications`
- `php artisan test --compact tests/Feature/Api/TicketApiTest.php tests/Feature/Mcp`
- `git diff --check`
## Commit And Push
- Commit only this ticket's changes.
- Push with `git push origin codex/v0.5-webhook-notification/03-ticket-status-changed-trigger`.
## Out of Scope
- Actual webhook HTTP request execution
- Actual Discord HTTP request execution
- Delivery attempt UI
- User bell notifications
- Unread counters
- Slack, Teams, email, or other channels
- Incoming webhooks
- API or MCP management endpoints
@@ -0,0 +1,70 @@
# 04 Generic Webhook Delivery
Implementation guide: [Ticket Implementation Guide](../ticket-implementation-guide.md)
## Branch
`codex/v0.5-webhook-notification/04-generic-webhook-delivery`
Start this branch from `codex/v0.5-webhook-notification/03-ticket-status-changed-trigger`.
## Goal
Deliver `ticket_status_changed` notifications to classic JSON webhook URLs.
## Requirements
- Implement queued delivery for notification actions using the `webhook` channel.
- Send an HTTP `POST` JSON request to the configured webhook URL.
- Include a structured payload suitable for n8n:
- event type
- project object
- ticket object
- actor object or null
- from status object
- to status object
- ticket URL
- occurred timestamp
- Use Laravel's HTTP client with a sensible timeout.
- Configure job retry/backoff so temporary webhook failures can retry.
- Persist delivery logs for success and failure.
- Store HTTP status and a short response or error excerpt when available.
- External delivery failures must not roll back ticket moves.
## Acceptance Criteria
- Webhook actions receive a JSON `POST` for ticket status changes.
- The payload contains enough context for n8n to route and format follow-up automation.
- Successful responses mark the delivery log as succeeded.
- Failed responses or connection errors mark the delivery attempt as failed or retryable according to the job state.
- Discord actions are not delivered by this ticket.
## Tests
- HTTP fake tests asserting method, URL, headers, and JSON payload.
- Tests for successful delivery log updates.
- Tests for non-2xx responses and connection failures.
- Queue/job tests for retry/backoff configuration where practical.
- Regression test that ticket moves still succeed when webhook delivery fails later.
## Verification
- `vendor/bin/pint --dirty --format agent`
- `php artisan test --compact tests/Feature/Notifications tests/Feature/Projects`
- `git diff --check`
## Commit And Push
- Commit only this ticket's changes.
- Push with `git push origin codex/v0.5-webhook-notification/04-generic-webhook-delivery`.
## Out of Scope
- Discord delivery
- Custom webhook headers or signing secrets
- Delivery attempt UI
- User bell notifications
- Unread counters
- Slack, Teams, email, or other channels
- Incoming webhooks
- API or MCP management endpoints
@@ -0,0 +1,69 @@
# 05 Discord Webhook Delivery
Implementation guide: [Ticket Implementation Guide](../ticket-implementation-guide.md)
## Branch
`codex/v0.5-webhook-notification/05-discord-webhook-delivery`
Start this branch from `codex/v0.5-webhook-notification/04-generic-webhook-delivery`.
## Goal
Deliver `ticket_status_changed` notifications to Discord webhooks with configurable message text.
## Requirements
- Implement queued delivery for notification actions using the `discord` channel.
- Send an HTTP `POST` request to the configured Discord webhook URL.
- Render the configured message template before delivery.
- Supported template variables:
- `$url`
- `$ticket_key`
- `$ticket_title`
- `$project_name`
- `$status_from`
- `$status_to`
- `$actor_name`
- Send Discord payload `{ "content": "<rendered message>" }`.
- Validate or guard that rendered Discord messages are non-empty.
- Respect Discord content length limits.
- Persist delivery logs using the same delivery logging rules as the generic webhook channel.
## Acceptance Criteria
- Discord actions receive a rendered text message for ticket status changes.
- Template variables are replaced with event payload values.
- Unknown template text remains literal text.
- Empty rendered messages are rejected before delivery and logged as failed.
- Generic webhook actions continue to deliver their JSON payload unchanged.
## Tests
- Template rendering tests for every supported variable.
- HTTP fake tests asserting Discord payload shape.
- Tests for empty template output and content length validation.
- Delivery log tests for successful and failed Discord requests.
- Regression tests proving webhook channel behavior remains unchanged.
## Verification
- `vendor/bin/pint --dirty --format agent`
- `php artisan test --compact tests/Feature/Notifications`
- `git diff --check`
## Commit And Push
- Commit only this ticket's changes.
- Push with `git push origin codex/v0.5-webhook-notification/05-discord-webhook-delivery`.
## Out of Scope
- Discord embeds or rich formatting
- Discord bot tokens
- Slack, Teams, email, or other channels
- Delivery attempt UI
- User bell notifications
- Unread counters
- Incoming webhooks
- API or MCP management endpoints
@@ -0,0 +1,62 @@
# 06 Notification Tests and Release Hardening
Implementation guide: [Ticket Implementation Guide](../ticket-implementation-guide.md)
## Branch
`codex/v0.5-webhook-notification/06-notification-tests-and-release-hardening`
Start this branch from `codex/v0.5-webhook-notification/05-discord-webhook-delivery`.
## Goal
Complete release-level coverage and polish for v0.5 webhook notifications.
## Requirements
- Review the full v0.5 implementation against the release README and all prior tickets.
- Fill missing tests for permissions, validation, hidden secrets, queued delivery, delivery logs, disabled actions, no-op moves, and multiple actions per event.
- Confirm project settings navigation is consistent across settings pages.
- Confirm existing ticket move flows still behave the same for web, API, and MCP clients.
- Confirm documentation matches the implemented behavior.
- Update release ticket docs only when they differ from the finished implementation.
## Acceptance Criteria
- All v0.5 acceptance criteria are covered by automated tests.
- A ticket status change can trigger multiple enabled actions for the same project.
- Failed external deliveries do not prevent ticket status movement.
- Secrets are never exposed in resources, Inertia props, logs, or tests.
- Existing web, API, and MCP status movement tests pass.
- The release docs are accurate after implementation.
## Tests
- End-to-end feature tests for creating actions and triggering deliveries from ticket status movement.
- Authorization tests for project admin management and non-admin denial.
- Regression tests for web, API, and MCP ticket status moves.
- HTTP fake tests for webhook and Discord delivery.
- Queue tests for dispatch behavior and retryable failures.
## Verification
- `php artisan route:list --except-vendor`
- `php artisan wayfinder:generate --with-form --no-interaction`
- `vendor/bin/pint --dirty --format agent`
- `php artisan test --compact tests/Feature/Notifications tests/Feature/Projects tests/Feature/Api/TicketApiTest.php tests/Feature/Mcp`
- `npm run types:check`
- `git diff --check`
## Commit And Push
- Commit only this ticket's changes.
- Push with `git push origin codex/v0.5-webhook-notification/06-notification-tests-and-release-hardening`.
## Out of Scope
- New notification channels beyond webhook and Discord
- User bell notifications
- Unread counters
- Incoming webhooks
- API or MCP management endpoints
- OAuth, scoped notification tokens, or external app installations
@@ -0,0 +1,35 @@
# Release v0.5 - Webhook Notifications
## Purpose
Add project-scoped notification actions that can react to KanbanGit events and deliver outbound webhook-style messages.
The first supported event is `ticket_status_changed`. The first supported channels are a classic JSON webhook for tools like n8n and a Discord webhook with configurable message text.
## Release Decisions
- Notification actions are configured per project in project settings.
- Project admins manage notification actions.
- Delivery is queued so ticket status moves are not blocked by slow external services.
- Every delivery attempt is logged for debugging.
- Webhook and Discord URLs are stored as secrets and are not shown back to the user after save.
- Template rendering uses a fixed variable set: `$url`, `$ticket_key`, `$ticket_title`, `$project_name`, `$status_from`, `$status_to`, and `$actor_name`.
## Tickets
- [01 Notification Action Foundation](01-notification-action-foundation.md)
- [02 Project Notification Settings UI](02-project-notification-settings-ui.md)
- [03 Ticket Status Changed Trigger](03-ticket-status-changed-trigger.md)
- [04 Generic Webhook Delivery](04-generic-webhook-delivery.md)
- [05 Discord Webhook Delivery](05-discord-webhook-delivery.md)
- [06 Notification Tests and Release Hardening](06-notification-tests-and-release-hardening.md)
## Out of Scope
- User bell notifications
- Unread counters
- Slack, Teams, email, or other channels
- Incoming webhooks
- Per-user notification preferences
- API or MCP management endpoints for notification actions
- Event types beyond `ticket_status_changed`