add double opt-in email verification for quote requests
Guest quote submissions now require email verification before the lead goes live. The verification click also creates a user account and logs them in. Logged-in users submitting with their own email skip verification. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
59
CHANGELOG.md
59
CHANGELOG.md
@@ -6,6 +6,65 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- **Double opt-in email verification for quote requests** — guest quote
|
||||
submissions now require email verification before the lead goes live;
|
||||
verification click also creates a user account and logs them in
|
||||
automatically (GDPR-friendly consent trail)
|
||||
- `GET /leads/verify` route — validates token, activates lead
|
||||
(`pending_verification` → `new`, sets `verified_at`), logs user in, sends
|
||||
admin notification and welcome email
|
||||
- `send_quote_verification` worker task — branded verification email with
|
||||
project details and "Verify & Activate Quote" CTA button (DEBUG mode
|
||||
prints link to console)
|
||||
- `quote_verify_sent.html` template — "Check your email" page shown after
|
||||
guest quote submission
|
||||
- Migration 0006 — adds `verified_at TEXT` column to `lead_requests`
|
||||
- 9 new tests in `TestQuoteVerification` class covering the full
|
||||
verification flow, expired tokens, duplicate verification, and user
|
||||
creation
|
||||
|
||||
### Changed
|
||||
- **Inline CTA full copy** — mobile/narrow-screen inline quote CTA now matches
|
||||
sidebar: "Next Step" label, full title, description, 4 checkmark benefits,
|
||||
"Get Supplier Quotes" button, and "Takes ~2 minutes" hint
|
||||
- **Signup bar simplified** — removed `×` close button from guest signup bar;
|
||||
now a non-dismissable nudge (still only shown on results tabs via JS)
|
||||
- **Investment tab narrower** — CAPEX tab content constrained to 800px max-width
|
||||
so 3-column card grid, table, and chart don't stretch across full 1100px on
|
||||
wide screens
|
||||
|
||||
### Changed
|
||||
- **Quote form → standalone 9-step HTMX wizard** — extracted "Get Quotes" from
|
||||
planner Step 5 into a standalone multi-step wizard at `/leads/quote` using
|
||||
server-rendered HTMX partials; each step validates server-side and swaps via
|
||||
`hx-post`/`hx-get` with OOB dot progress updates; accumulated state passed
|
||||
forward as hidden JSON field (no JS state management)
|
||||
- **Planner reduced to 4 steps** — removed embedded quote form (Step 5) from
|
||||
planner wizard; Step 4 "Get Quotes →" now navigates to `/leads/quote` with
|
||||
pre-filled params (venue, courts, glass, lighting, country, budget)
|
||||
- **Planner sidebar CTA** — "Get Supplier Quotes" button now links to standalone
|
||||
quote wizard instead of scrolling to embedded Step 5; sidebar now visible on
|
||||
all tabs including assumptions (was results-only)
|
||||
- **Sticky wizard nav** — planner preview bar (CAPEX/CF/IRR) and back/next
|
||||
buttons now stick to the bottom of the viewport so users don't have to scroll
|
||||
to navigate between steps
|
||||
- **Mobile quote CTA** — inline "Get Quotes" card shown below main content on
|
||||
screens narrower than 1400px (where the fixed sidebar is hidden)
|
||||
- **Step 4 → "Show Results"** — final planner wizard step now says "Show Results"
|
||||
instead of "Get Quotes" since quote flow is a separate standalone wizard
|
||||
- **Removed "2-5 suppliers" cap language** — replaced specific supplier count
|
||||
promises with "matched suppliers" across landing page, supplier FAQ, planner
|
||||
sidebar, and quote form privacy box
|
||||
|
||||
### Removed
|
||||
- Inline quote form from planner (Step 5 HTML, `#wizSuccess`, hidden inputs)
|
||||
- `populateWizAutoFill()`, `submitQuote()`, `COUNTRY_NAMES` from planner.js
|
||||
- `__PADELNOMICS_QUOTE_URL__` JS variable from planner template
|
||||
- Step 5 scoped CSS (~155 lines): `#wizQuoteForm`, `.wiz-autofill-summary`,
|
||||
`.wiz-input`, `.wiz-privacy-box`, `.consent-group`, `.wiz-success`,
|
||||
`.wiz-signup-nudge`, `.wiz-checkbox-label`
|
||||
|
||||
### Added
|
||||
- **Supplier tier system** — Migration 0005 adds `tier` (free/growth/pro),
|
||||
`logo_url`, `is_verified`, `highlight`, `sticky_until`, `sticky_country`
|
||||
|
||||
Reference in New Issue
Block a user