Submission Lifecycle: @@save-poll

Submission Lifecycle: @@save-poll A sequence diagram generated by Archify. GET @@get-form-json · access mode enforced form schema + auth_token (HS256, version bound) POST @@save-poll · pollResult size limit · token & replay check · normalize 413 / 403 reject, or normalized deep copy schema + payload written as temp files valid, or 400 external_validation_failed notify(submission event) store · poll_id, seq_no, site_id mail · mail-notification · post payload { isSuccess: true, stored: false if store off } Receive & harden Validate & answer Browser · SurveyJS viewer · Sequence participant Browser SurveyJS viewer Plone add-on · viewer · save-poll · Sequence participant Plone add-on viewer · save-poll Boundary check · security.py · Sequence participant Boundary check security.py Validator · survey-core · 30 s · Sequence participant Validator survey-core · 30 s Subscribers · store · mail · post · Sequence participant Subscribers store · mail · post Results store · ZODB / RDBMS · Sequence participant Results store ZODB / RDBMS Mail & webhook · SMTP · POST · Sequence participant Mail & webhook SMTP · POST Legend request return security async trace default message

Authorize at load time

  • • @@viewer issues a short-lived HS256 token bound to the form id and version
  • • Publishing a new form version invalidates every outstanding token
  • • Recording the token on disk gives replay protection (24 h TTL)

Fail closed, fail early

  • • Payload size is enforced before JSON parsing (413)
  • • Access mode, token and replay checks reject with 403
  • • An unavailable token cache rejects (503) instead of allowing

Actions are independent

  • • One subscriber per side effect: store, mail, mail-notification, post
  • • A failing mail host or webhook is logged, never raised
  • • The submission stays accepted: { isSuccess: true }