WIP: Custom support-request form at /support/new with stubbed /api/support backend - #21030
WIP: Custom support-request form at /support/new with stubbed /api/support backend#21030CamSoper wants to merge 2 commits into
Conversation
…port backend As support moves from Zendesk to Intercom, Intercom provides no prebuilt request form, so this adds our own: - /support/new/: a hand-built form (fields mirroring the Zendesk form) rendered by layouts/page/support-new.html from front matter, using the shared .form-* design system. Client-side validation, org-name normalization, sessionStorage draft persistence, char counter, query-param prefill, and a honeypot live in theme/src/ts/support-form.ts. - /api/support: a Lambda (Function URL) mounted same-origin via a new CloudFront origin + /api/support* behavior in infrastructure/index.ts, gated by the enableSupportForm stack config (on for www-testing and www-production). The Function URL is sealed by an x-origin-verify shared secret injected by CloudFront. - The handler validates submissions server-side (infrastructure/support-form/validation.ts, unit-tested via yarn test-support-form) and stubs the Intercom integration by logging accepted entries as structured JSON to CloudWatch (90-day retention). The Intercom ticket call and attachment upload land once the API spec is available; attachments currently submit metadata only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtyVE5R4oYsgzBU7x1AC45
There was a problem hiding this comment.
✅ No issues found
About Unblocked
Unblocked has been set up to automatically review your team's pull requests to identify genuine bugs and issues.
📖 Documentation — Learn more in our docs.
💬 Ask questions — Mention @unblocked to request a review or summary, or ask follow-up questions.
👍 Give feedback — React to comments with 👍 or 👎 to help us improve.
⚙️ Customize — Adjust settings in your preferences.
Pre-merge Review — Last updated 2026-08-21T15:35:11ZTip Summary: This PR adds a hand-built support-request form at Review confidence:
Investigation log
🔍 Verification trail34 claims extracted · 9 verified · 0 unverifiable · 0 contradicted
🚨 Outstanding in this PRNo outstanding findings.
|
|
Your site preview for commit e31402d is ready! 🎉 http://www-testing-pulumi-docs-origin-pr-21030-e31402d4.s3-website.us-west-2.amazonaws.com Changed pages: |
Lighthouse Performance ReportCommit: e31402d | Metric definitions
|
The fourth "I need help with:" option was carried over verbatim from the Zendesk form, typo included. The option value (docs) is unchanged, so the closed enum in infrastructure/support-form/validation.ts, the client-side validation, and the unit tests are unaffected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DtyVE5R4oYsgzBU7x1AC45
|
@claude #update-review Fixed the outstanding finding in e31402d: the category label now reads "Pulumi Documentation/Blog". The label was carried over verbatim from the Zendesk form, typo included; Notes on the four low-confidence findings, none of which I've acted on:
Generated by Claude Code |
|
🤖 Review updated on @CamSoper's request. |
Proposed changes
WIP — do not merge. First cut of the custom support form for the Zendesk → Intercom migration (context). Intercom has no prebuilt request form, so this builds our own, with the Intercom integration stubbed until the API spec is available.
Form page —
/support/new/(content/support/new/_index.md+layouts/page/support-new.html)<form>mirroring the Zendesk field set (email, full name, company, Pulumi org, "I need help with:" select, subject, description,pulumi aboutoutput, attachments), styled entirely with the shared.form-*/.btn/.cardprimitives — no new CSS. All copy lives in front matter; two-card layout (form → confirmation) modeled on/extend-trial.theme/src/ts/support-form.ts(registered inmain.ts): per-field validation mirroring the server rules (aria-invalid+.form-error, focus-first-invalid, clear-on-input), org-name normalization (pastedhttps://app.pulumi.com/<org>URLs reduce to the org name), sessionStorage draft persistence so a failed submit never loses the description, a character counter,?category=/?subject=prefill, a honeypot, and a graceful error banner for environments where the endpoint doesn't exist (PR previews, localmake serve).block_external_search_index: truefor now; the/support/Zendesk redirect and existing support links are untouched until cutover.Backend —
POST /api/support(infrastructure/supportForm.ts+infrastructure/support-form/)/api/support*behavior on the existing distribution — no CORS, and traffic stays behind the site's WAF rate limiting. The Function URL is AuthType NONE but rejects any request lacking thex-origin-verifyshared secret that only CloudFront injects (secret generated by@pulumi/random, delivered via Lambda env var; comma-separated rotation supported).422 {fields}errors the frontend maps back onto inputs. All responses areCache-Control: no-store(newapi-response-headerspolicy; the API behavior also drops the edge-redirect Lambda association and markdown-negotiation functions thatbaseCacheBehaviorwould otherwise attach).support_request_accepted) to a pre-created CloudWatch log group with 90-day retention (submissions contain PII), observable viaaws logs tail /aws/lambda/$(pulumi stack output supportFormFunctionName). ATODO(intercom)marks where the ticket-create call goes; the API key will arrive as a stack secret / ESC entry, never in this repo. Attachments currently submit metadata only (filename/size/type) — byte upload is deferred until the Intercom spec defines where files go.enableSupportFormstack config, on forwww-testingandwww-production; dev stacks and PR previews are unaffected (the form degrades to the error banner).cd infrastructure && yarn test-support-form(24 tests, passing).Verified:
make lintclean,make buildrenders/support/new/with the full form, webpack bundle compiles, infratscclean, unit tests pass.Follow-ups (not in this PR): Intercom ticket call + attachment upload, link cutover (
help-links.html,hand-raise-section.html, footer,/contact/quick links, the/support/redirect), optional OAC hardening of the Function URL, post-deploy health check for the endpoint.Unreleased product version (optional)
n/a
Related issues (optional)
Internal Slack thread: https://pulumi.slack.com/archives/D0BRR746EAD/p1787266575569169
🤖 Generated with Claude Code
https://claude.ai/code/session_01DtyVE5R4oYsgzBU7x1AC45
Generated by Claude Code