Skip to main content

Service Times Editor — Agent-Only Plans

Why this exists (incident, 2026-09-06)

First paying voice customer (Iglesia, starter_voice) emailed: "I tried to do it online but couldn't find the right box" while trying to correct wrong mass times. Root cause: the voice + chat agents answer service-time questions from premium_churches.custom_hours, but the only editor for that field lived in the Website tab (Website → Services), which is hidden for every plan without Pro Website (planIncludesProWebsite). The Church Knowledge section's own subtitle promised "Staff, ministries, hours & documents" — with no hours editor inside. starter-voice.md line 102 already lists "Service times & directions" as a plan feature. The spec promised it; the UI never delivered it. Logged P1 in FOUNDER_ACTIONS 2026-09-07; founder approved build same day.

User state matrix

Plan situationService Times card in Train AI → Church Knowledge?Rationale
Agent plan (chat, voice, or both) WITHOUT Pro Website accessVISIBLE — full editorThis is the gap. No other surface can edit custom_hours.
Any plan WITH Pro Website access (planIncludesProWebsite(premium) true)HIDDENThey already edit service times in Website → Services via the draft/publish flow. A second canonical-writing editor would recreate the dual-editor overwrite class bug fixed 2026-04-23 (a Training-tab edit would be silently reverted by the next Website Publish copying draft_custom_hourscustom_hours).
No-agent / site-onlyHIDDEN (they never reach this panel — Train AI is upsell-carded; feedback_no_agent_surfaces_must_be_gated)No agent quotes the times.
Funeral / vet verticalsUNCHANGED — church panel only; funeral hours live in Funeral Home KnowledgeVertical-scoped fix.

Gate expression (must mirror the Website-tab predicate exactly, as its complement): hasAnyAgent(premium) && !planIncludesProWebsite(premium).

Touchpoints

T1 — Card on the Church Knowledge grid

  • Position: FIRST card (service times are the #1 caller question).
  • Title "Service Times", clock icon, agent badge (Voice Agent / Chatbot / Voice + Chatbot) matching the other cards.
  • Summary line, empty state: "No service times yet — the #1 thing callers ask about".
  • Summary line, filled: "Services listed on N day(s) of the week" (N = days in custom_hours with at least one non-empty entry).

T2 — Editor sheet

  • Same SectionEditorSheet shell as every other card (eyebrow "Church Knowledge").
  • One text input per day, Sunday → Saturday, name="hours_{Day}" (capitalized day names — must match the API's DAYS constant exactly).
  • Prefill: existing custom_hours[day] entries joined with "; " (a day holding multiple array entries — e.g. two Sunday masses stored as separate strings — must ALL be visible; rendering only entry [0] silently hides and then destroys the rest on save. This is a live bug in the ListingTab hours form; do not copy it).
  • Helper copy states: leave a day blank for no services; list multiple services on one line; office hours belong in Settings → Hours, not here.
  • Saves via the existing SaveFormPOST /api/premium/update with section=service_hours (no API change; that section already writes canonical custom_hours for non-draft posts).

T3 — Save semantics

  • Non-empty day input → custom_hours[day] = [<entire input string>] (single-element array; free text). Multi-entry arrays collapse to one joined string on first save — acceptable: voice + chat prompt-builders render entries as text, and non-website plans have no public template rendering the array shape.
  • All inputs blank → custom_hours = null. Voice agent then uses the honest no-hours fallback (deployed 2026-09-06): it says it doesn't have service times and offers the office number — it must NOT invent times.

T4 — Ministries banner truth

The blue info banner in the Ministries sheet previously told everyone to put service times inside ministries text (a band-aid). With this feature:

  • Card visible → banner points to the Service Times card.
  • Card hidden (website plans) → banner points to Website → Services. It must never again instruct putting canonical service times into ministries.

Acceptance criteria (Playwright, deployed URL, demo church token only)

  1. Demo church (cwa_pro_both — includes agents, does NOT include website): Service Times card renders first on the Church Knowledge grid.
  2. Opening the card shows 7 day inputs prefilled with the joined entries of the demo's current custom_hours (multi-entry Sunday shows BOTH entries).
  3. Editing + Save → reload → values persist (round-trip against the deployed URL).
  4. A Pro-Website-plan church does NOT render the card (assert absence).
  5. No behavior change to Website → Services, ListingTab, or the hours (office hours) section.

Explicitly out of scope

  • Multi-input-per-day array editing (free text per day matches every existing hours form).
  • Pointer/upsell card for website plans inside Church Knowledge.
  • Funeral/vet service-schedule editing.
  • Deep-link hash (#training-service-times) — may be added later with the HASH_TO_TAB map.