Sales Rep Account Assignment & Quote Revisions

Account-level sales rep persistence, Game One geo-search by ZIP, quote revisions audit trail with status/cancel RPCs, and simplified quote form with auth gate.

Overview

This release adds account-level sales rep assignment with two assignment sources (brand template and geo-search by ZIP), an audit trail for quote changes via quote_revisions, and a simplified quote form with inline auth for guests.

Sales Rep Assignment — Account-Level Persistence

Account Migration

Migration 20260220010840_account_sales_rep_assignment.sql adds columns to public.accounts for storing assigned sales rep data:

ColumnPurpose
assigned_rep_idGame One rep_id
assigned_rep_nameFull name
assigned_rep_emailEmail
assigned_rep_phonePhone (optional)
assigned_rep_headshot_urlHeadshot image URL
assigned_rep_source'brand_template' or 'geo_search'
assigned_rep_atTimestamp of assignment

Server Actions

ActionPurpose
assignSalesRepFromTemplatePersists rep from applied brand template to the user's personal account. Fire-and-forget on confirm.
assignSalesRepByZipLooks up nearest sales rep via Game One geo-search by US ZIP; assigns to account. For standalone sign-up callback.

Game One API Client

game-one-api.ts exposes fetchNearestSalesRep(zip) — calls Game One /salesreps/geo-search with JWT auth. Returns the closest rep by distance, or null when none found.

Environment: GAMEONE_API_BASE_URL, GAMEONE_API_JWT_TOKEN

Integration Points

  • Brand Template panel — calls assignSalesRepFromTemplate when user confirms applying a brand
  • Quote Auth Gate — assigns rep when guest signs up with valid ZIP (geo-search preview) or brand template applied

Quote Revisions — Audit Trail

Migration

20260220120000_quote_revisions.sql creates public.quote_revisions:

ColumnPurpose
change_typestatus_change, customization_update, cancellation
change_summaryJSONB field-level diffs
previous_snapshotFull customization JSONB (for design updates)

Security-Definer RPCs

FunctionPurpose
update_quote_status(uuid, text)Validates access, records revision, updates quote status. Bypasses restrictive RLS.
cancel_quote(uuid)Validates state (no cancel of ordered), records cancellation revision.
create_quote_revision(uuid, jsonb, jsonb)Records customization updates on quote re-submit from builder.

Quote Detail View

Status dropdown and Cancel button now use these RPCs. Revision history is displayed in the timeline.

Quote Form Refactor

QuoteFinalStep

New component with special instructions textarea and submit button. Shown directly for authenticated users.

Simplified Flow

  • Guest → Auth gate (sign-in / sign-up with MFA and email OTP)
  • Authenticated → Single final step (notes + submit)

The auth gate collects profile (name, ZIP, etc.) for guests and supports geo-search rep preview.

Submit Quote — Edit Mode

When editingQuoteId is provided:

  1. Fetches existing quote and computes change_summary (colors, roster count, design, text, graphics)
  2. Records revision via create_quote_revision RPC
  3. Updates quote in-place; preserves quote_number, status, submitted_at
  4. Saves previous snapshot to builder_shared_configs for 3D diff view

Sign-Up Flow — ZIP for Geo-Assignment

  • Password sign-up schema — ZIP code now mandatory (USA format, 5-digit validated via zipcodes)
  • user_metadatazip stored for post-sign-up assignment hooks
  • assignSalesRepByZip — Server action ready for standalone sign-up callback when session is established

Database Summary

MigrationDescription
20260220010840_account_sales_rep_assignmentSales rep columns on accounts
20260220120000_quote_revisionsquote_revisions table, RPCs for status/cancel/revision