Skip to content

fix(automation): resolve n8n workflow ↔ CMS webhook contract drift#59

Merged
derrickmehaffy merged 3 commits into
developfrom
fix/automation-webhook-contract-drift
Jun 18, 2026
Merged

fix(automation): resolve n8n workflow ↔ CMS webhook contract drift#59
derrickmehaffy merged 3 commits into
developfrom
fix/automation-webhook-contract-drift

Conversation

@derrickmehaffy

Copy link
Copy Markdown
Member

What & why

The n8n automation workflows had drifted out of sync with the moderation plugin's current webhook payloads, so the automation loop was broken. Most importantly, lifecycle webhooks no longer carried the submitter's email, so every developer email had no recipient. Field names, callback route plurals, and the security-scan callback auth had also diverged.

This PR resolves the drift on both sides and adds the bits needed to actually run the loop locally.

Changes

  • fix(cms/moderation) — lifecycle webhooks now include owner_email / owner_name (from the submit payload on create; from the populated owner relation on publish/decide) plus a coarse kind (plugin | template). Canonical Strapi field names kept (documentId, name, git_repository, slug).
  • fix(automation) — workflows realigned to the canonical payload (plugin_name/template_namename, submissionId/package_iddocumentId, repository_urlgit_repository, package_slugslug); security-scan / stale-scan callbacks fixed to use the correct route plurals (packages / templates) and to authenticate with Authorization: Bearer {{ $env.STRAPI_API_TOKEN }} (they referenced an unset credential → Credentials not found); standardized on $env.STRAPI_BASE_URL. Added the n8n env wiring (STRAPI_BASE_URL/STRAPI_API_TOKEN, N8N_BLOCK_ENV_ACCESS_IN_NODE). Production-faithful: SendGrid + header-auth webhooks retained — local-only test overrides (Mailpit SMTP, auth off, Slack disabled) were applied to the running n8n instance only and are not committed.
  • chore(cms) — added the pg driver (config/database.ts supports a postgres client but it was never installed).

Verified

Tested end-to-end against a staging DB dump via a local Strapi + n8n + Mailpit harness. All 8 lifecycle events confirmed (correct, interpolated emails delivered / callback persisted): plugin & template submission-received / approved / declined, plugin changes-requested, and the security-scan callback loop (security_reviewcompleted with dependencies/ai/summary written back to Strapi).

Notes for reviewers

  • docker-compose.yml defaults STRAPI_BASE_URL to http://host.containers.internal:1337 (local podman host gateway); it's overridable via env for other deployments.
  • approved requires a publishable recordslug (uid) and, for packages, description must be set before publish or it 400s and the webhook never fires. This matches the real admin flow (reviewer fills these in); flagging in case we want the submit form / a default to populate them.
  • The security-scan AI analysis stage needs an Anthropic credential ("Claude Haiku Security Analysis" node); without it the stage persists a placeholder but the loop still completes.
  • Consider guarding the render-email sub-workflow against an empty recipient (to_email) — it throws "No recipients defined" for a submission with no owner.

🤖 Generated with Claude Code

derrickmehaffy and others added 3 commits June 17, 2026 11:43
…bhooks

Lifecycle webhooks (submission-received, approved, declined, changes-requested) no longer carried the submitter's email/name, so downstream n8n email workflows had no recipient. Add owner_email/owner_name (from the submit payload on create; from the populated owner relation on publish/decide) plus a coarse kind (plugin|template) for routing/labels. Keeps canonical Strapi field names (documentId, name, git_repository, slug).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Workflows were authored against an older payload. Map body fields to canonical names (plugin_name/template_name->name, submissionId/package_id->documentId, repository_url->git_repository, package_slug->slug); fix security-scan/stale-scan callbacks to use the correct route plurals (packages/templates) and authenticate via Authorization: Bearer $env.STRAPI_API_TOKEN instead of an unset credential; standardize on $env.STRAPI_BASE_URL. Add the n8n env wiring (STRAPI_BASE_URL/API_TOKEN, N8N_BLOCK_ENV_ACCESS_IN_NODE) needed for the workflows to reach Strapi. Production-faithful: SendGrid + header-auth webhooks retained.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
config/database.ts supports a postgres client but the driver was never installed, so the app could only run on the sqlite default. Required to run against the (staging) Postgres database.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
community-web Ready Ready Preview, Comment Jun 17, 2026 6:45pm

Request Review

@boazpoolman boazpoolman left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@derrickmehaffy derrickmehaffy marked this pull request as ready for review June 18, 2026 14:01
@derrickmehaffy derrickmehaffy merged commit f3863b2 into develop Jun 18, 2026
3 checks passed
@derrickmehaffy derrickmehaffy deleted the fix/automation-webhook-contract-drift branch June 18, 2026 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants