4.2 KiB
4.2 KiB
Status
Approved
Story
As an inquirer, I want a guided contact form, so that I can convey project essentials quickly.
Acceptance Criteria
- Fields: project type, timeline, budget range, references/links; validation via zod.
- Success page with next steps/SLA.
- Optional route to persist submissions (or email integration) without breaking existing auth.
- API response contract is explicit and enforced: returns JSON
{ ok: boolean, message?: string }on both success and error. - Basic server-side abuse mitigation in place: rate limiting of 5 requests per minute per client IP with appropriate error messaging in the response shape.
Tasks / Subtasks
- Form fields and validation (AC: 1)
- Extend
src/app/contact/page.tsxwith fields:projectType(select),timeline(select or free text),budgetRange(select),references(textarea or list of URLs) - Convert to React Hook Form + Zod schema for client-side validation; enforce valid email and optional URL list parsing
- Keep existing first/last/subject/message fields; align labels and helper text with tokens
- Extend
- Submission handling (AC: 1, 3)
- Replace direct Web3Forms POST with internal API route
src/app/api/contact/route.tsthat forwards to: a) Web3Forms (current behavior) if configured, or b) Cloudflare Worker/D1 endpoint if env vars provided (optional persistence) - Sanitize inputs server-side; add basic rate limiting (IP-based, 5 requests/minute per IP)
- Return structured JSON
{ ok: boolean, message?: string }
- Replace direct Web3Forms POST with internal API route
- Success page (AC: 2)
- Add
src/app/contact/success/page.tsxwith confirmation content and what happens next (SLA) - After successful submission, navigate to
/contact/successwith a minimal state (no PII in URL)
- Add
- A11y and UX
- Error messaging announced to screen readers; inputs with
aria-invalidandaria-describedby - Disabled submit state and spinner while submitting; keyboard-friendly focus order
- Privacy note near submit; link to
/privacy
- Error messaging announced to screen readers; inputs with
- Quality and Integration Verification
- Lint/build pass:
npm run lint/npm run build - IV1: Rate limiting or basic abuse mitigation is active (manual check)
- IV2: Error states accessible and clear (screen reader test)
- IV3: No PII leakage in logs (log only metadata, never form body)
- Lint/build pass:
Dev Notes
- Context
- PRD Story 1.7. Contact page exists and posts to Web3Forms. This story moves submission to an internal API, adds guided fields, and adds a success page. Cloudflare D1 is optional and must not affect Prisma schema.
- Relevant Source Tree
- Contact page:
src/app/contact/page.tsx - New success page:
src/app/contact/success/page.tsx - New API:
src/app/api/contact/route.ts(POST) - Utilities:
src/components/Forms.tsx(reuse Input/Textarea components);src/lib/utils.ts
- Contact page:
- Implementation Guidance
- Zod schema example fields:
projectType: enum(['Commercial','Music Video','Narrative','Other']),timeline: string,budgetRange: enum(['<10k','10–50k','50–200k','200k+','TBD']),references: string(parse to URLs),firstName/lastName/email/subject/message. - API route: forward payload; for Cloudflare, use
fetch(CF_CONTACT_ENDPOINT, { method:'POST', headers: { Authorization: CF_CONTACT_AUTH, 'Content-Type': 'application/json' }, body }); do not include secrets in client bundle. - Environment variables:
NEXT_PUBLIC_WEB3FORMS_ACCESS_KEY(existing), optionalCF_CONTACT_ENDPOINT,CF_CONTACT_AUTH. - Rate limit: simple in-memory map 5/min/IP; acceptable for MVP.
- Zod schema example fields:
Testing
- Manual
- Validation: invalid email blocks submit; references accept comma/newline separated URLs
- After success, user lands on
/contact/success; browser back shows preserved inputs or reset as designed - Privacy and Terms links open and are accessible
- Regression
- Ensure no auth flows are affected; admin pages continue to work
- Logs contain no PII
Change Log
| Date | Version | Description | Author |
|---|---|---|---|
| 2025-09-24 | v1 | Initial draft from PRD Story 1.7 | Scrum Master |
Dev Agent Record
Agent Model Used
{{agent_model_name_version}}
Debug Log References
Completion Notes List
File List
QA Results