Files
resolutionflow/docs/plans/2026-03-04-survey-invite-tracking-design.md
2026-03-05 01:33:17 -05:00

3.1 KiB

Survey Invite Tracking — Design

Date: 2026-03-04 Status: Approved

Goal

Add invite tracking to the FlowPilot survey so Michael can create personalized links, optionally email them, and see who has/hasn't responded. Each invite token is single-use — one submission per token.

Data Model

New table: survey_invites

Column Type Notes
id UUID PK
token VARCHAR(32) UNIQUE Random URL-safe token
recipient_name VARCHAR(255) NOT NULL Who it's for
recipient_email VARCHAR(255) NULL Only if emailing
status VARCHAR(20) DEFAULT 'pending' pending or completed
email_sent BOOLEAN DEFAULT false Whether Resend email was sent
created_at TIMESTAMPTZ NOT NULL
completed_at TIMESTAMPTZ NULL Set on submission

Modified table: survey_responses

Add invite_id UUID FK nullable → survey_invites.id. Responses from tokenless /survey have invite_id = NULL.

API Endpoints

Public (no auth)

  • GET /api/v1/survey/invite/{token} — Returns invite status ({ name, status }). If completed, frontend shows "already submitted" screen. Returns 404 for invalid tokens.
  • POST /api/v1/survey/submit — Modified: accepts optional token field. If token provided, validates it's pending, links the response, and marks invite as completed. Returns 409 if token already used.

Admin (super_admin auth)

  • POST /api/v1/admin/survey-invites — Create invite. Body: { recipient_name, recipient_email?, send_email? }. Generates token, optionally sends email. Returns the invite with the full survey URL.
  • GET /api/v1/admin/survey-invites — List all invites with status.

Frontend

Survey page changes (/survey)

  • On load, reads ?t=<token> from URL params
  • If token present: calls GET /survey/invite/{token}
    • If completed → show "already submitted" screen
    • If pending → show survey, include token in submission payload
    • If 404 → show survey without token (treat as open link)
  • If no token: show survey as-is (open access)

Admin page (/admin/survey-invites)

Top section: Create Invite

  • Name input (required) + Email input (optional)
  • "Generate Link" button → creates invite, shows URL with copy button
  • "Send Email" button → creates invite with send_email: true, shows confirmation toast
  • "Send Email" only enabled when email field is filled

Bottom section: Invite Table

  • Columns: Name, Email, Status badge (pending amber / completed green), Sent (email icon or dash), Created date, Completed date
  • Sorted by created_at descending

Email Template

Uses existing EmailService + Resend pattern. Dark-themed email matching Slate & Ice aesthetic:

  • Subject: "FlowPilot Survey — Your expertise matters"
  • Body: Brief intro, CTA button linking to /survey?t=<token>, ~5 minutes note
  • From: existing FROM_EMAIL config

Constraints

  • No token expiration
  • No reminder/resend (keep it simple)
  • Tokenless survey still works for open sharing
  • One submission per invite token (enforced backend + frontend)