Gathr

v1.0 Beta Launch

July 31, 2026 commit 83f528c branch release/v1.0-beta-launch

Core platform

Foundation

Multi-tenant architecture, auth, and data integrity rules that everything else builds on.

Magic link authentication

One-click login via email. Supabase auth chain: auth.uid() → person → membership → tenant. Auth callback activates membership on entry.

Shipped

Multi-tenant hierarchy

org_group → tenant → event → event_session. Tenant slug unique per org group. All PKs are UUID. Tenant branding injected via useTenantBranding().

Shipped

Row-level security

RLS enabled across all tables. Service role for admin operations, auth.uid() for all client queries. No bypass paths in production code.

Shipped

Soft delete everywhere

deleted_at timestamptz on every table. No hard deletes. All queries filter WHERE deleted_at IS NULL.

Shipped

PWA — add to home screen

Installable on iOS and Android. Web manifest, apple-touch-icon, and favicon all in place. Add-to-home nudge included in invitation and welcome emails.

Shipped

Organizer tools

Dashboard & event management

Everything an organizer needs from the moment they create an event to after it ends.

Organizer dashboard

Full event management: create, edit, publish, track RSVPs. Desktop sidebar + mobile bottom tab nav (Home · Members · Events · More). Multi-org switcher for organizers with more than one tenant.

Shipped

UP NEXT event card

Directive-first layout: title / status / date up top, then a single guidance line telling the organizer exactly what to do next and why. Share link, RSVP counts, declined member list. Card-level field editing with one Save.

Shipped

Contact import

Drag-and-drop email import. Parsed, deduped, and added to roster. Invitation send triggered from the same flow.

Shipped

Share link + join flow

Prospective members submit a join request via share link. Known roster members are fast-tracked: membership activated, magic link generated, redirected straight to their dashboard — no approval queue.

Shipped

Organizer approval flow

Approve or deny join requests from the dashboard. Acknowledgment email sent on submission; welcome email (with magic link) sent on approval.

Shipped

Guidance & data engine

The system that plans for you

The nudge engine is the beginning of the "software plans, you approve" stage. It surfaces the right action at the right time — and logs every decision in a form the system can eventually learn from.

decision_inputs

Every guidance decision records the exact inputs and threshold values that drove it — RSVP rate, weeks out, roster size, last reminder date. When an outcome lands later, the inputs are there to correlate against it.

Actor types

actor_type = 'system' when the platform surfaces an action. actor_type = 'person' when a human clicks. This distinction is what makes outcome analysis trainable — conflating them corrupts the signal.

Named thresholds

Every numeric rule is a named constant: REMINDER_COOLDOWN_DAYS, URGENCY_WEEKS_THRESHOLD, INTEREST_RATIO_THRESHOLD. Constants are the handles the AI layer needs to adjust them per-organizer over time.

Activity logging

nudge.shown / nudge.dismissed / nudge.acted logged to activity_event on every interaction. Conversion rate queryable today; becomes the training signal tomorrow.

In-app notification bell

Supabase realtime subscription. Unread count badge, dismissal, View CTA. Shown in mobile top bar and desktop header. Cron (compute-guidance-notifications) confirmed running weekly.

Pure function contract

getGuidanceLine never queries the database. All state is passed in. Any decision is replayable by reconstructing the inputs — a requirement for reproducible AI evaluation.

organizer.draft_setup organizer.teaser_share organizer.teaser_interest_gathering organizer.teaser_ready_to_publish organizer.teaser_stalled organizer.teaser_prompt_suggest organizer.published_waiting organizer.published_rsvp_coming_in organizer.published_uninvited_roster organizer.published_response_slow organizer.published_final_push organizer.rsvp_closed organizer.reminder_sent_cooldown organizer.post_event_recap_prompt organizer.post_event_no_recap organizer.roster_empty organizer.roster_growth_stalled organizer.roster_complete organizer.plan_shown organizer.prompt_replies_ready rsvp.low_response_rate rsvp.reminder_overdue invitation.batch_unsent event.headcount_near_target event.no_communication_sent event.day_before_reminder member.post_event_recap_available member.profile_completion

Email flows

Seven flows, one sender

All flows send from invitations@mail.getgathr.co via Resend. Every outbound message is recorded in communication + communication_recipient for delivery tracking and multi-sender support.

Flow Trigger Variants
Invitation Organizer imports + sends Magic link embedded directly. Add-to-home-screen nudge included.
Join acknowledgment Member submits via share link Single variant — "request received, under review."
Approval welcome Organizer approves request Single variant — "you're in." Magic link included.
Publish notification Event goes live Active members only. Does not create invitation records.
Manual reminder Organizer sends from UP NEXT card Confirmed: "see you soon." Undecided: "RSVPs still open." Declined excluded.
Day-before reminder Cron, 14:00 UTC daily Confirmed: "see you tomorrow." Undecided: "are you coming?" Declined excluded.
Post-event recap Organizer sends after last session Full recap text + "see the event page" CTA. All active members who haven't opted out.
Email trust pass complete. Raw Supabase URLs removed from all email copy. From-names standardized. Warmed copy throughout. planwithgather.com in all footers.

Member experience

What members see

The member dashboard and join flow — built to make someone feel like they belong to something specific, not like they received a blast email.

Member dashboard

Event cards with RSVP flow (yes / decline), session cards, post-event recap display. Mobile bottom nav: Home · People · Events. Design system tokens applied throughout.

Shipped

Profile gate

First-login screen collects name, photo, phone, and SMS opt-in. Skippable (session-snoozed), re-shown until confirmed. Logs member.profile_completion nudge events.

Shipped

Fast-track join for known members

Roster members who hit the share link are recognized, membership activated, and redirected via magic link — no waiting for approval. New members go through the standard queue.

Shipped

SMS

Twilio SMS — code complete, blocked on carrier registration

The routing logic is built and tested. What's missing is carrier approval, not code.

SMS routing in send-event-reminder

Members with sms_opt_in = true and a phone number on file receive reminders via Twilio SMS. All others get email. Both manual and day-before reminder flows use this routing.

Blocked

Twilio credentials

Account SID, auth token, and from-number (+13176614390) are set as Supabase secrets. Sending fails with Error 30034 — unregistered number — until A2P 10DLC brand and campaign registration is complete in Twilio Trust Hub. Toll-free verification is an alternative path.

Blocked

Not in this release

Explicitly out of scope

Apple Wallet passes

Button exists but is commented out. Not production-ready.

Not included

Google & Facebook OAuth

Supabase auth supports it; not yet wired in the app.

Not included

Per-commit preview deployments

Cloudflare Pages preview URLs still point at prod Supabase. Dev environment is seeded but the env var wiring for preview builds is unresolved.

Not included

Stripe Connect / payments

Architecture decided, tables set up. Implementation not started.

Not included

Rollback reference

To restore this exact state

Branch release/v1.0-beta-launch
Commit 83f528c6a1969b5645a93b567bb0c6ef7ada5f60
Date 2026-07-31

To roll back: reset main to this branch and push, or use Cloudflare Pages → Deployments → Rollback to restore the build instantly without touching git.