Architecture · Forms, review and workflow runtime

Event-Driven Forms and Workflow Backend for WordPress on AWS

Keep form authoring and placement in WordPress while durable drafts, submissions, discussions, review state, notifications and downstream actions run behind an explicit API and event boundary.

WordPress / static frontend
      ↓ Flow runtime
Frontend API
      ↓
Submission + draft state
      ├→ uploads
      ├→ discussion / review state
      └→ workflow events
             ↓
      email / webhooks / actions

Execution boundary

A form becomes a workflow when state must survive the page request

Long forms, approvals and review processes need durable state. Flow separates the browser experience from backend persistence and downstream execution, so the public page can remain static while the process continues independently.

Form / review UI in WordPress
   ↓ browser
/frontend/* API
   ├→ save / load / finalize draft
   ├→ submit record
   ├→ upload contract
   └→ discussion / rating inputs
          ↓ durable state + events
/admin/* → protected management
          ↓
workflow dispatch → email / webhook / process action

Security boundary Public form routes and privileged admin routes have different risk profiles. Anonymous submission controls, authenticated review access and administrative configuration should not share one broad authorization surface.

What the Flow stack creates

The Flow backend separates API, compute, state, payload, event, security and operational concerns. This inventory shows which AWS resources serve each architectural job.

LayerAWS resourcesArchitectural job
API layerRegional API Gateway REST API, optional custom domain, optional Route53 recordsExpose separate frontend and admin route families without tying form execution to WordPress hosting.
Compute layerForms API Lambda, Workflow Dispatcher Lambda, Email Sender Lambda, Webhook Dispatcher Lambda, deployment-time Custom Resource LambdaKeep synchronous form handling, async workflow processing, email delivery and outbound webhooks as separate operational units.
State layerDynamoDB tables for submissions, submission events, templates, workflow definitions, form definitions, webhook endpoints and process mapsStore form definitions, records and workflow state in purpose-specific tables with TTL/retention instead of treating the WordPress database as the integration log.
Payload layerS3 payload bucket and templates bucket, optional existing bucketsMove large file transfer and reusable email/template assets into object storage.
Event layerEventBridge rules and events such as submission created/updated/status/action and AI agent completion/failureTurn form work into observable events that can trigger workflows without blocking the visitor.
Security layerCognito authorizer for admin routes, optional IAM/NONE modes, WAF, reCAPTCHA, IP allow/block lists, SSM/KMS for secretsApply different protections to public form submissions and privileged management APIs.
Operations layerCloudWatch log groups, SQS dead-letter queue, configurable log retention, optional GuardDuty malware protectionGive the runtime its own logs, retry/failure surface and payload scanning options.

Frontend API versus Admin API

The two route families serve different callers and should not inherit the same trust assumptions. This table makes the runtime split visible before form behavior or permissions are configured.

Route familyExamplesTypical callerSecurity posture
Frontend submission/frontend/forms/{formId}/submitA rendered Flow form on a public or protected pageCan run with no user auth, but should use reCAPTCHA/WAF/rate limits for anonymous traffic.
Frontend drafts/frontend/forms/{formId}/drafts, /drafts/load, /drafts/delete, /drafts/{submissionId}/submitA visitor saving, resuming or finalizing a long formDraft credentials and final validation are separated so draft saves do not trigger final workflows.
Frontend upload preparation/frontend/forms/{formId}/upload-urlA form component preparing a large attachmentReturns a presigned S3 upload contract; the payload does not need to pass through WordPress.
Admin forms/submissions/admin/forms, /admin/forms/{formId}/submissionsWP Admin or management UIShould be protected with Cognito/IAM and optionally IP allowlisting.
Admin templates/workflows/webhooks/admin/templates, /admin/workflows, /admin/webhook-endpointsAdministrators configuring business behaviorThese routes change runtime behavior and should never be treated like public frontend endpoints.

Data model: why several tables are useful

The backend separates definitions, current records, event history and integration configuration because they have different lifecycles. This table explains why a single generic form row is not enough for durable workflows.

Table familyWhat it representsWhy it is separate
Form definitionsThe structure and versioning of forms used by the frontendA form can change while old submissions must remain understandable.
SubmissionsCurrent submission state, draft/final status and core field dataThis is the operational record that admin views and workflow steps query.
Submission eventsAppend-style history: created, updated, status changed, action invokedAudit and retry behavior should not overwrite the current submission row.
TemplatesReusable email/template metadataEmail content changes should be managed independently from submission records.
Workflow definitionsRules, actions and routing behaviorWorkflow logic has its own lifecycle and should be versioned/managed explicitly.
Webhook endpointsOutbound integration targets and signing settingsExternal systems are operational dependencies, not just form fields.
Process mapsRuntime mapping between processes, submissions and actionsComplex workflows need correlation state beyond a single form record.

Security and abuse controls

Public form routes and privileged management routes should not share one protection model. This table shows where bot controls, WAF, identity and secret storage belong in the Flow runtime.

ControlWhere it appliesDesign reason
reCAPTCHAPublic frontend form endpointsReduce bot submissions before they become stored records, emails, webhooks or model/workflow costs.
WAF rate limitsFrontend and admin path prefixesThrottle abuse differently for visitor-facing and admin-facing routes.
Admin Cognito authorizer/admin/* routesKeep form definitions, submissions, templates, workflows and webhook configuration behind a real identity boundary.
SSM/KMS secretsreCAPTCHA secrets and webhook signing secretsKeep shared secrets out of WordPress settings and template source.
GuardDuty malware protectionPayload bucket when enabledAdd a scanning option for uploaded payloads before downstream processing relies on them.

Deployment parameters that change the architecture

These parameters are not cosmetic form settings. They change authentication, abuse controls, storage ownership, secrets, domains and operational behavior, so they should be reviewed as architecture decisions.

Parameter areaExamplesArchitectural effect
Auth modesFrontendApiAuthMode, AdminApiAuthMode, AdminCognitoUserPoolId, scopesControls whether frontend and admin surfaces are public, IAM-protected or Cognito-protected.
Abuse protectionEnableRecaptcha, reCAPTCHA mode/site key/threshold, EnableWAF, allowed/blocked IP listsDetermines how much anonymous traffic can reach the backend and which paths are rate-limited or allowlisted.
Storage ownershipTemplatesBucketName, PayloadBucketName, prefixesLets teams use created buckets or attach existing storage conventions.
SecretsEnableKmsForSecrets, webhook signing secret, reCAPTCHA secretControls whether secrets are stored with a dedicated KMS key and SSM parameters.
Domain/DNSApiCustomDomainName, certificate ARN, Route53 settingsMoves the API from an execute-api URL to a branded domain when the DNS/certificate path is ready.
OperationsData retention, log retention, Lambda memory/timeout/log levelControls cost, observability and runtime headroom without changing WordPress pages.

Implementation path

Model the process before wiring the actions

The same backend can support simple forms and more structured processes if draft, submission, review and action state remain explicit.

  1. Define the record and its lifecycle — Decide what is a draft, what becomes a submitted record, which review states exist and which fields or attachments must persist between sessions.
  2. Separate visitor and reviewer operations — Keep public or authenticated frontend actions under a narrow runtime surface and protect administrative form, submission and workflow management separately.
  3. Emit events after durable state changes — Trigger email, webhooks or other process actions only after the relevant record or status change is accepted, so downstream failures do not erase the original submission.
  4. Test retries and handoffs — Verify draft resume, final submit, review decisions, discussion or rating updates, failed notifications and external webhook errors as separate failure paths.

When an event-driven Flow backend is worth the separation

Good fit

Forms that are really business processes

  • Users need to save and resume a long form across sessions.
  • Submissions enter review, approval, discussion, rating or status workflows after the initial form step.
  • The public frontend may be static, while state and downstream actions must remain live and independently operable.

Keep it simpler

A conventional form path may be enough when

  • The form is short and the process ends with one submission and a simple notification.
  • The site is fully dynamic and an existing form plugin already covers the workflow without operational friction.
  • There is no need for durable drafts, backend review state, event history or external workflow actions.

Problem guides

Buyer problems backed by this architecture

How do I replace email and spreadsheet approvals with a WordPress workflow?

Start with Replace Email and Spreadsheet Approvals with a WordPress Workflow. It frames the operational pain; this architecture explains where records, review state and workflow actions live.

How do users save a long WordPress form and continue later?

See Let Users Save a Long WordPress Form and Continue Later. Durable draft state belongs behind the browser runtime rather than inside one PHP page request.

How do I combine forms, discussion and ratings in one review workflow?

See Build a WordPress Review Workflow with Forms, Discussion and Ratings for the review use case, and Add Discussions, Replies and Ratings to a Static WordPress Frontend when the collaboration experience must remain live after static publishing.

Can this still work on statically published WordPress?

Yes. The page can be served from static hosting while Flow calls the configured backend from the browser. See Make WordPress Static Without Losing Dynamic Features for the wider static-plus-runtime model.

Start with the workflow problem

Move the process out of inboxes before adding more automation

Choose the buyer problem first—approval, save-and-resume or structured review—then use this architecture to define persistence, authorization and event boundaries.