- Flask session-based login with styled dark-theme login page
- All routes gated behind password (configurable via SITE_PASSWORD env)
- /login and /api/health are public
- Wrong password shows red error, correct redirects to original page
- 30-day session persistence
- /logout to clear session
- Password: jv2026 (set in docker-compose.yml)
DATA FIXES:
- Dashboard insights now fully dynamic per date range
- Revenue/orders/newcust/AOV trend (splits data in half, compares)
- Channel concentration % computed from filtered data
- Repeat revenue % with date-range label
- All insights adapt when user changes date filter/preset
- Offer page charts now load from API (not hardcoded arrays)
- Revenue chart, new customer chart, channel donut = live data
- Hero stats (-84%, -42%, 85%) computed dynamically from API
- ROI calculator AOV pulled from latest year's actual data
REMAINING AUDIT FIXES:
- Fix#4: 'Built by' section on offer page (name, bio, contact)
- Fix#9: Before/After comparison block on homepage
- Side-by-side: current JV PDP flaws vs AI engine output
- 8 specific ✗/✓ comparison points
- Fix#6: Before/after serves as instant proof (no 90s wait)
All 10 audit fixes now implemented.
CRITICAL:
- Fix broken mailto: CTAs on /offer and /proposal (empty href!)
- Fix 97.4% channel dependency claim → actual 85% (verified from DB)
- Fix 37.3% repeat rate → 57.6% cohort return rate (verified)
- Fix revenue model payback math (was 2.6mo, actual 3.5mo at 100/mo)
- Fix cost-of-waiting claim with verifiable math
CONVERSION:
- Hero rewrite: 'Lost 84% of new customers' → client problem, not tech brag
- Nav: remove duplicate Proposal link, single 'The Proposal' → /offer
- Footer CTA: primary action is now 'See the Full Proposal'
- All CTAs now include properly formatted mailto with subject+body
- Replace unverified competitor claim with specific named competitors
DATA INTEGRITY:
- 15/23 claims verified SOURCE-LINKED from PostgreSQL (728K orders)
- 4 claims corrected (97.4%→85%, 37.3%→57.6%, payback, cost-of-waiting)
- Revenue calculator uses cohort-verified return rate
- Board summary updated with correct figures
- Gallery now shows only the 5 AI-generated product photos
- Each thumb shows model name (Nano Banana / Pro) + caption
- Caption overlay on main image describes the shot type
- Removed original scraped images from gallery display
Image Generation:
- Downloads actual product images from justvitamins.co.uk
- Sends real photo as reference to Gemini (image-to-image)
- Generates 5 ecommerce-grade variations maintaining product consistency:
Hero (clean studio), Lifestyle (kitchen scene), Scale (hand reference),
Detail (ingredients close-up), Banner (wide hero)
- Uses Nano Banana Pro for hero/lifestyle/banner, Nano Banana for fast shots
PDP Output:
- Demo A now renders as a real ecommerce product detail page
- Gallery: original + AI-generated images with clickable thumbnails
- Above the fold: H1, value props, price block, trust bar, CTAs
- Key Benefits: Feature → Benefit → Proof format, 5 icon cards
- Stats bar, Why This Formula, 5★ review, FAQ accordion
- Meta SEO (Google preview), Ad Hooks (5 platform-targeted), Email sequences
Prompts:
- Conversion-optimised based on Cialdini/Kahneman principles
- EFSA health claim compliance baked into every prompt
- Feature → Benefit → Proof bullet structure
- Price anchoring, social proof, urgency psychology
- Added PostgreSQL 16 Alpine service to Docker Swarm stack
- db.py: schema for 17 tables, auto-seed from jv_data.json on first boot
- /api/dashboard/data?start=&end= — server-side SQL filtering
All Time: 0.43s (was 4MB JSON download stuck loading)
Filtered (12mo): 0.20s with ~90% less data transferred
- Dashboard HTML patched: calls API instead of static JSON
- Integer casting for IsNewCustomer/HasDiscount/IsFreeShipping
- Advisory lock prevents race condition during parallel worker startup
- Returning Revenue now shows correctly: £14.5M (75% of total)