Files
Waters ChurchandClaude Fable 5.1 78cd0cc550 Plan Your Visit landing page for visit.waterschurch.org
Next.js 16 static export + PHP 8 API for cPanel/Apache hosting.

- Location-aware campus finder (IP estimate, optional precise location, ZIP search)
- Three-step Plan Your Visit form with separate email/SMS consent
- PHP API: validation, anti-spam, rate limiting, SQLite lead store,
  Mailchimp and Sinch Engage adapters, idempotent retries via cron
- Attribution capture (utm_*, gclid/gbraid/wbraid, fbclid, ttclid, twclid) and
  consent-aware analytics hooks
- Vitest and PHP test suites, cPanel deployment script and docs

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-22 13:22:26 -04:00

6.8 KiB

Launch checklist

A. Items that require Waters Church approval before launch

Nothing below was fabricated; each item is either unverified or a legal/policy decision.

Facts to confirm (config/campuses.json → verify)

  • Coordinates for every campus (derived from Google Maps links / OpenStreetMap; spot-check each pin).
  • North Attleboro service times — campus page says 7:30, 9:30, 11:30 AM; the locations index page shows "11:30p" (assumed typo).
  • Parking and arrival notes for each campus (currently empty; generic copy is shown instead).
  • Woonsocket and Southcoast phone numbers — the main office number is used because the campus pages list none.
  • Orlando — marked launching (launch team only) and excluded from recommendations. Flip status to open and add an SMS number when it opens.
  • Central "Text Us" number (NEXT_PUBLIC_CENTRAL_SMS_NUMBER, default +1 508-695-1300) — who answers general texts?
  • Norwood uses info@waterschurchnorwood.org and 781-762-3357 per its own page — confirm these are current.

Content placeholders (src/content)

  • faqs.ts items flagged confirm: true: service length ("a little over an hour"), parking ("free on-site parking at every location"), accessibility ("step-free entrances").
  • kids.ts items flagged placeholder: true: first-time check-in steps, "arrive 15 minutes early", what to bring, special-needs accommodations.
  • testimonials.ts is empty → section is hidden. Add real, permissioned quotes or leave hidden.
  • Headline and copy tone (copy.ts).
  • SMS consent language (consent.ts → sms.detail): TCPA/CTIA disclosures, frequency, "Msg & data rates may apply", STOP/HELP, consent not a condition. Confirm the number is registered (10DLC campaign / toll-free verification) for this use case.
  • Email consent language and single vs. double opt-in (MAILCHIMP_DOUBLE_OPTIN).
  • Privacy Policy at waterschurch.org/privacy covers this subdomain, SMS, geolocation estimate, analytics and ad pixels. Add a Terms URL (NEXT_PUBLIC_TERMS_URL) if one exists.
  • Data retention: set LEAD_RETENTION_DAYS (0 = keep forever). Decide who may run export-leads.php and where exports live.
  • Analytics consent mode: implied (default) vs opt-in banner.
  • Location estimation wording (consent.ts → locationBlurb).
  • Bump consent.version if any consent text changes.

B. Post-deployment verification

Hosting

  • https://visit.waterschurch.org/ loads; http:// and www. redirect (301) to https://visit.waterschurch.org/.
  • SSL padlock valid (AutoSSL) — check with https://www.ssllabs.com/ssltest/.
  • /BUILD.txt shows the expected build; /404.html and a random URL return the branded 404.
  • /api/health.php → "ok": true, integration_mode: "live".
  • /api/lib/Config.php, /api/config/campuses.json, /api/cron/retry-integrations.php → 403.
  • Response headers include Strict-Transport-Security, X-Content-Type-Options, cache headers (immutable on /_next/static, must-revalidate on HTML), Content-Encoding: br|gzip.
  • Old Church Center redirect removed.

Location detection

  • On a phone off Wi-Fi: a campus is recommended with the "based on your general area" badge.
  • Deny "Use my precise location" → friendly message, page still usable.
  • ZIP search: 02763 → North Attleboro, 02062 → Norwood, 02895 → Woonsocket, 02878 → Southcoast, 33572 → Apollo Beach, 32789 → Apollo Beach (far away notice), 90210 → far away notice.
  • Bad ZIP (abc, 1234) → inline error, no crash.
  • Choose a different campus → form step 1 updates to match.
  • Email consent only → Mailchimp contact created with tags; no text sent.
  • SMS consent without phone → blocked with an inline error.
  • SMS + phone → confirmation text arrives from the campus number within a minute; Mailchimp Visit:SMS Opt-In tag present.
  • Neither box → lead stored (export shows it), nothing sent.
  • Reply STOP to the text → opt-out confirmed by Sinch; resubscribe afterwards.
  • Double-tap "Send" / refresh and resubmit → one lead, one text (duplicate: true in the network response).
  • Temporarily set a wrong SINCH_API_SECRET → submit → confirmation still shows, sms_status = retry, cron log shows retry; fix the secret → text arrives on the next cron run.
  • Confirmation screen shows campus, times, directions, "Text Us a Question" with the campus number.
  • Mailchimp journey/automation fires for the new contact.

Attribution and analytics

  • Visit with ?utm_source=facebook&utm_campaign=test&fbclid=abc&v=b, submit → export shows the attribution JSON and variant = b; Mailchimp tags include Visit:Platform Facebook, Visit:Campaign test.
  • Visit with no parameters and with malformed ones (?utm_source=<script>) → still works, values sanitised.
  • GTM/GA4 debug view shows landing_page_view, campus_recommended, campus_selected, plan_visit_started, plan_visit_step_completed, plan_visit_submitted, plan_visit_success, text_us_clicked, directions_clicked with campus, platform, campaign, device_category, variant.
  • Conversion events fire only after plan_visit_success (check Meta Events Manager / Google Ads test conversion).
  • No email/phone/name appears in any analytics payload.

Text Us

  • iPhone and Android: header, hero, floating button and campus cards open Messages with the pre-filled text, editable, to the right number.
  • Desktop: the sms: link degrades gracefully (Messages app on macOS, otherwise no-op) — consider a visible phone number if desktop traffic is significant.
  • Export a lead: consent_version, consent_at, email_consent, sms_consent, hashed IP present; no raw IP or precise coordinates stored.

Performance & accessibility

  • Lighthouse mobile (Chrome DevTools, "Slow 4G"): Performance ≥ 90, Accessibility ≥ 95, no CLS from hero/fonts.
  • 320 px, 375 px, 430 px, 768 px, 1280 px widths: no horizontal scroll, tap targets ≥ 44 px.
  • Keyboard only: skip link → header → campus cards → FAQ accordions → form steps → submit; focus always visible.
  • Screen reader: form errors announced (role="alert"), step heading focused on step change, confirmation announced (role="status").
  • prefers-reduced-motion: no animation.

Operations

  • Cron job runs every 5 minutes (cron.log grows with retry: lines).
  • Someone owns app.log review and the leads export cadence.
  • .env backed up somewhere safe (it is not in the repo).