Acceptance Spec — Tuesday Prep Pack signup on the Prep Desk
Why (one paragraph)
The funnel's owned-audience asset is the email list, not YouTube subs (strategy.md §1, §6). The Tuesday Sermon Prep Pack is the lectionary-keyed weekly email; the prep-desk pages are its natural capture surface (the hub, not the Short, captures email). PR #896 shipped the section with a deliberate component seam where this form belongs. This spec fills it.
Component
src/components/sermons/TuesdaySignup.tsx — 'use client', self-contained, no props required.
Expected output (Pastor Ruth test)
An inline signup block:
- Copy: "The Tuesday Sermon Prep Pack" + "Next Sunday's text, prepped, in your inbox every Tuesday. Free."
- Form: one email field (type=email, required, labeled for a11y) + one submit button (
.btn-gold). - Submit: posts JSON
{ email, tag: 'tuesday_prep_pack', source: 'sermonwise' }to/api/newsletter— the public capture endpoint that writesemail_subscribersand syncs MailerLite viatagToGroup(). No page reload (client fetch viapostJsonWithFallback). NOTE:/api/mailerlite/subscribeis the secret-gated cross-property proxy (x-ml-proxy-key) and is NOT browser-callable; it shares the sametagToGroup()map, so the new tag works there too for sister-site callers. - MailerLite routing: tag
tuesday_prep_pack→ grouptuesday-prep-pack(id190107266612987702) insrc/lib/mailerlite-groups.ts. - Success state: form replaced by "You're in — see you Tuesday." No reload.
- Error state: inline message, form still usable, button re-enabled.
- CASL note under the form: "Unsubscribe anytime."
- Placement: prep-desk episode pages — below the discussion prompt, above the footer cross-links. Prep-desk index — below the "What's on the desk each week" card, above the footer.
Non-goals
- No MailerLite automation/campaign is created or activated by code — founder-gated, done in the MailerLite UI.
- No double opt-in flow changes; whatever the group/account is configured for applies.
- No name field, no church field — email only (lowest-friction capture).
Edge cases
- Already-subscribed email → still shows success (endpoint returns
alreadySubscribed: true; copy stays "You're in — see you Tuesday."). - JS network failure → error state, never a silent no-op (three-tier transport in
postJsonWithFallback). - Component renders identically with or without a
youtubeVideoIdon the episode.
Verification gate (evidence-or-nothing)
pnpm lint(touched files) +pnpm buildgreen.- Deployed-URL check: form visible on
/prep-deskand/prep-desk/matthew-13-the-sower(sermonwise.ai host); submit a test email; observe success copy without reload; subscriber appears in MailerLite grouptuesday-prep-pack.