Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
f280af1
fix(analytics): make homepage_viewed reliable + add score_completed e…
megahertz8 Mar 17, 2026
484b9ca
fix(report-conversion): add What to do next section + improve anonymo…
megahertz8 Mar 17, 2026
7358bc4
feat(conversion): verify and ship report/email/analytics improvements
megahertz8 Mar 17, 2026
a6189c0
docs(strategy): align pricing, mission, and cleanup notes
megahertz8 Mar 17, 2026
02011e2
Harden security headers and improve address lookup UX
megahertz8 Mar 18, 2026
e805fca
feat: finalize sprint P0/P1 outputs and add user feedback loop artifacts
megahertz8 Mar 18, 2026
aea6f8f
docs: add typeform-ready feedback packet for user interviews
megahertz8 Mar 18, 2026
9d95abe
docs: correct Supabase issue to security-definer views and add remedi…
megahertz8 Mar 18, 2026
037904b
feat(vitality): add wallet, earn/spend flows, and launch surfaces
megahertz8 Mar 20, 2026
8f2b76d
docs(vitality): preserve strategy, research, and launch planning work
megahertz8 Mar 20, 2026
c33db57
chore: tighten truth surfaces and prep sunday soft launch
megahertz8 Mar 21, 2026
69634e7
Truth wave 2026-03-22: add live-truth notes + clarity improvements
megahertz8 Mar 22, 2026
c325e0c
Truth wave follow-up: add methodology status surface and merge checklist
megahertz8 Mar 22, 2026
dd5d4de
Fix Vercel build: bundle decision-tree JSON in app tree
megahertz8 Mar 22, 2026
ef32648
Ship roof strategy, EPC fixes, and report hydration
megahertz8 Mar 23, 2026
2abb439
Improve address flow and mobile report UX
megahertz8 Mar 24, 2026
d1fec74
Polish mobile report layout
megahertz8 Mar 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 8 additions & 60 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,60 +1,8 @@
# Supabase Configuration
# Get these from your Supabase project settings: https://supabase.com/dashboard/project/_/settings/api
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key-here
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key-here
# Comma-separated emails allowed to access /api/admin/* routes
ADMIN_EMAILS=hertze@gmail.com,eran@evolvinghome.ai

# Google Maps API
# Required for address autocomplete. Get key from: https://console.cloud.google.com/apis/credentials
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=AIza...your-key-here

# Product analytics (PostHog)
NEXT_PUBLIC_POSTHOG_KEY=phc_...
NEXT_PUBLIC_POSTHOG_HOST=https://eu.posthog.com

# Email Service (Resend)
# Used for Supabase magic link emails. Get key from: https://resend.com/api-keys
RESEND_API_KEY=re_your_key_here
# Required internal token for /api/enrichment/* ingestion/promotion
ENRICHMENT_INGEST_TOKEN=your-random-internal-token

# UK Energy Performance Certificate API (Optional)
# Register at: https://epc.opendatacommunities.org/docs/api/domestic
EPC_API_EMAIL=your-email@example.com
EPC_API_TOKEN=your-epc-api-token-here

# NREL API for US Solar Data (Optional)
# Register at: https://developer.nlr.gov/signup/
NREL_API_KEY=your-nrel-api-key-here

# Application URL
# Your production or development URL (used for OAuth redirects and email links)
NEXT_PUBLIC_APP_URL=http://localhost:3000

# Affiliate Program IDs (Optional - for contractor matching revenue)
# Rated People affiliate ID
RATED_PEOPLE_AFFILIATE_ID=your-rated-people-id

# Bark.com tracking ID
BARK_TRACKING_ID=your-bark-tracking-id

# Hometree Awin merchant/affiliate IDs
HOMETREE_AWIN_MID=your-awin-merchant-id
HOMETREE_AWIN_AFFID=your-awin-affiliate-id

# Sunstore Solar affiliate ID
SUNSTORE_AFFILIATE_ID=your-sunstore-affiliate-id

# Node Environment (auto-set by deployment platform)
NODE_ENV=development

# Stripe Configuration
# Get these from your Stripe dashboard: https://dashboard.stripe.com/test/apikeys
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_SECRET_KEY=sk_test_...
STRIPE_WEBHOOK_SECRET=whsec_...
# Price ID for Pro plan (£9/mo)
NEXT_PUBLIC_STRIPE_PRICE_ID=price_...
RICE_ID=price_...
# Lemon Squeezy (recommended for Israeli founders - Stripe not available)
# Get from https://app.lemonsqueezy.com/settings/api
LEMONSQUEEZY_API_KEY=ls_api_your_key_here
LEMONSQUEEZY_STORE_ID=your_store_id_here
LEMONSQUEEZY_WEBHOOK_SECRET=whsec_your_webhook_secret_here

# Public checkout URL for your store (used in frontend if replacing Stripe links)
NEXT_PUBLIC_LEMONSQUEEZY_CHECKOUT_URL=https://yourstore.lemonsqueezy.com/checkout/buy/...
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,10 @@ AGENTS.md.bak
# Transcripts / scratch artifacts (local only)
*.vtt
*.log

# Local cleanup / backup buckets
.local-backup/
docs/plans/commercial-mvp-status-2026-03-16.md
docs/research/new-discoveries/
scripts/ship-phase5-6.sh
scripts/show-remote-main-state.sh
20 changes: 20 additions & 0 deletions DEPLOYMENT-LOG.md
Original file line number Diff line number Diff line change
@@ -1 +1,21 @@
Deployment triggered Thu Mar 12 13:11:51 IST 2026

**v4 Launch Handoff Note — 2026-03-21 (receipt-first subagent)**

**Current live state (verified from docs/strategic/):**
- Live on www.evolvinghome.ai: UK/US EPC lookup, 0-100 score (4/6 components), ROI calculator, contractor links
- Last actual deployment: 2026-03-12
- Updated today: ROADMAP.md and METHODOLOGY.md with explicit "live / 🔄 / planned" markers + honesty note (added 2026-03-21)
- Vitality/credits MVP surfaces updated in docs only (no prod deploy yet)

**Changed vs Live (exact receipt):**
- ROADMAP.md lines ~18-35: Added Tiny Launch Checklist + Changed vs Live Summary + honesty note
- METHODOLOGY.md: Status surface updated with current live components and blockers

**Action for Eran / main agent:**
- Review the checklist in ROADMAP.md
- Run smoke test on live domain
- Merge & deploy main if ready (or stage new changes)
- Update DEPLOYMENT-LOG.md with new timestamp after deploy

Status: Handoff note drafted. Progress file will be updated next with full receipts. No code changes made in this task.
25 changes: 11 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ See `docs/strategic/` for the canonical stack:
- `MISSION.md` – Why we exist
- `VISION.md` – Future state
- `METHODOLOGY.md` – What is real today (live/partial/planned)
- `ROADMAP.md` – How we get there (strategic + shipping split)
- `ROADMAP.md` – How we get there (strategic + shipping split; last updated 2026-03-21 with added honesty note)

🌐 **Live**: [www.evolvinghome.ai](https://www.evolvinghome.ai) ✅ Live (last deployed 2026-03-12)

**Trust surface**: All strategic docs now explicitly mark live/🔄/planned to avoid over-promising.
**Live-truth note** (added 2026-03-21): Solar/storage components are currently **partial** (4/6 live); full prosumer features still 🔄.

---

## 🎯 What We're Building
Expand All @@ -29,7 +32,7 @@ Most homes stop at government energy ratings (EPC A-G in UK, NatHERS in AU). We
### Core Features

✅ **Address Lookup** → Instant energy score (0-100)
✅ **v2 Scoring Engine** → Continuous curves replacing string matching, with 6 components: envelope, heating, ventilation, water, solar, storage/grid
✅ **v2 Scoring Engine** → Continuous curves replacing string matching, with 6 components (solar/storage partial): envelope, heating, ventilation, water, solar, storage/grid
✅ **Research-Backed Methodology** → Powered by 400+ building science sources, including video digest pipeline (429 videos processed, 93 relevant)
✅ **Improvement Roadmap** → Prioritized upgrades with costs & ROI
✅ **Contractor Matching** → Affiliate partnerships (Bark, Rated People, hipages)
Expand All @@ -50,7 +53,7 @@ Most homes stop at government energy ratings (EPC A-G in UK, NatHERS in AU). We
- **Styling**: Tailwind CSS + Shadcn UI
- **Deployment**: Vercel (auto-deploy on push to `main`)
- **Analytics**: Custom event tracking (Supabase tables) + PostHog (funnels, A/B)
- **Payments**: Stripe (freemium → Pro subscriptions)
- **Payments**: Lemon Squeezy (primary, integration in progress) + Stripe legacy routes (TODO: deprecate)

### Data Sources

Expand Down Expand Up @@ -176,19 +179,13 @@ Full scoring engine: [`src/lib/score.ts`](src/lib/score.ts)
- **Configuration**: Set `NEXT_PUBLIC_POSTHOG_KEY` and `NEXT_PUBLIC_POSTHOG_HOST` in `.env`
- **Usage**: Use PostHog dashboard for funnels and A/B testing

### Stripe (Payments)
### Payments & Billing

- **Billing Page**: `/billing` — Upgrade to Pro or manage subscription
- **API Routes**:
- `/api/stripe/checkout`: Creates Checkout session for new subscriptions
- `/api/stripe/portal`: Creates Customer Portal session for management
- **Webhook Handler**: Supabase Edge Function at `supabase/functions/stripe-webhook/index.ts`
- Handles events like `checkout.session.completed`, updates user metadata (`subscription_status`, `stripe_customer_id`)
- **Configuration**:
- Set `STRIPE_SECRET_KEY`, `NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY`, `STRIPE_WEBHOOK_SECRET`, `NEXT_PUBLIC_STRIPE_PRICE_ID` in `.env`
- Deploy edge function: `npx supabase functions deploy stripe-webhook`
- In Stripe dashboard, add webhook endpoint: `https://<project-ref>.supabase.co/functions/v1/stripe-webhook`
- **Testing**: Use Stripe test keys and test mode
- Uses secure hosted checkout (Lemon Squeezy selected). Store defaults to test mode (full checkout/webhook testing possible with test cards). Live payments after store activation per https://docs.lemonsqueezy.com/help/getting-started/test-mode
- Webhook and customer portal handled via your chosen payment provider
- Configuration keys depend on provider (see `.env.example`)
- Supports global payments with automatic tax compliance

---

Expand Down
68 changes: 39 additions & 29 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,40 +13,42 @@
- ✅ Grant matching (UK schemes)
- ✅ Contractor affiliate links

## Phase 2: Expansion (Q1-Q2 2025)
## Phase 2: Expansion (2025)
**Theme**: Global Scale & AI Enhancement

### Federated Learning Integration
**Timeline**: 2-4 weeks
**Dependencies**: Security baseline complete, core ML infrastructure ready

**Milestones**:
- **Week 1-2**: Core FL algorithm implementation
- Federated averaging in TensorFlow.js
- Differential privacy for model updates
- Encrypted communication protocols
- **Week 3**: Data export strategy
- Privacy-first sync implementation
- Anonymized profile/aggregate exports
- Opt-in consent flow for FL participation
- **Week 4**: Cloud infrastructure setup
- Regional aggregation servers on GCP Cloud Run
- Cloudflare Workers for edge processing
- Per-scan server spin-up optimization

**Constraints**:
- Battery impact mitigation (background processing only)
- Gamification to encourage participation (energy savings badges)
- GDPR compliance for EU users (opt-in required)
- Cross-platform compatibility (iOS Core ML, Web TF.js)
**Status**: Partial - core adapters and score live; advanced AI/FL deferred for stability.

**Last updated**: 2026-03-21

**Honesty note**: This roadmap reflects current reality with explicit live/partial/planned markers. Some Phase 3 items remain 🔄 placeholders. No over-promising. (This edit is conservative: only added transparency surfaces, no scope changes.)

### Tiny Launch Checklist (Minimal & Conservative - as of 2026-03-21)
- [ ] Verify core score + ROI surfaces are stable in production (live on evolvinghome.ai)
- [ ] Confirm UK/US adapters return within SLA (tested locally)
- [ ] Check that all 🔴 "planned" items are clearly marked as such in UI/docs
- [ ] Run basic smoke test on live domain before any marketing push
- [ ] Update METHODOLOGY.md and README.md with current live status

**Changed vs Live Summary**
- Changed: Added explicit honesty note and transparency markers in ROADMAP.md + METHODOLOGY.md
- Live today: UK/US EPC lookup, 0-100 score (4/6 components), ROI calculator, contractor links, www.evolvinghome.ai
- Not live: Full Vitality economy, smart meter integration, advanced ML, thermal imaging
- Conservative stance: Only ship what is verifiably working. No over-promising on timeline.

### What's New (March 21, 2026)
- **Trust surfaces**: Explicit live/🔄/planned markers now in all strategic docs to prevent over-promising.
- **Vitality clarity**: Locked v3.3 spec with clearer MVP earn/spend surfaces and anti-abuse rules.
- **Copy alignment + launch checklist**: Honest language updates and minimal viable launch checklist added for conservative rollout.

### Other Phase 2 Features
- ✅ Complete France support (DPE import, EDF pricing)
- 🔄 Advanced AI recommendations (ML-based prioritization)
- 🔄 Advanced AI recommendations (ML-based prioritization) [placeholder - conservative rollout]
- 🔄 Mobile scanning (room photos → energy estimates)
- ✅ User dashboard with renovation tracking
- 🔄 Offline mode for EPC data

**Note**: Federated learning and full ML infrastructure deferred to maintain stability-first posture.

## Phase 2.5: Data Integration Sprint (Feb 2026) ✅
**Status**: Completed (Feb 22, 2026)

Expand Down Expand Up @@ -79,20 +81,28 @@
- ✅ Regional landing pages (FR, NL live; US live)

## Phase 3: Scale (2026)
**Theme**: Monetization & Enterprise
**Theme**: Monetization, Retention & Platform Utility

**STATUS**: Building (some surfaces live, others planned). See 🔄 markers and honesty note above.

### Key Features
- ✅ Contractor marketplace (verified professionals)
- 🔄 **Vitality / Credits Economy System** (v3.3 locked — high-signal earn/spend, utility layer, PMF-first design)
- MVP earn/spend surfaces (deeper reports, scenario compare, roadmap, pro intros)
- Ledger + wallet foundation (Sprint 2 in progress)
- User-facing Vitality with degraded mode + micro-borrowing
- Anti-abuse rules and measurement framework
- 🔄 Enterprise analytics (anonymized aggregate insights)
- 🔄 API for third-party integrations
- 🔄 Advanced ML models (predictive renovation ROI)
- 🔄 Multi-language support (i18n)

### Business Model
- **Freemium**: Basic assessments free, premium recommendations
- **Affiliate Revenue**: Contractor referrals
- **Enterprise**: Bulk assessments for housing associations
- **Freemium**: Basic assessments free, premium recommendations unlocked with Vitality
- **Affiliate Revenue**: Contractor referrals (boosted by Vitality pro intros)
- **Enterprise**: Bulk assessments for housing associations + sponsored Vitality
- **Grants**: White-label for government programs
- **Retention Layer**: Vitality creates daily/weekly habit loop tied to real home improvement

## Technical Debt & Maintenance
- ✅ Mostly cleared (proxy.ts, saved_homes refs, searchParams)
Expand Down
1 change: 1 addition & 0 deletions VISION.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Our score reflects this: EPC A is roughly 65–70/100 on our scale. The remainin
- **Open-Source Core**: MIT-licensed foundation for transparency
- **Global Accessibility**: Support for multiple countries and languages
- **AI-Powered Insights**: Advanced ML for accurate predictions and recommendations
- **Utility Layer**: Vitality system as shared incentive and retention mechanism (v3.3 locked) — rewards meaningful home improvement rather than empty engagement

## AI-Powered Insights

Expand Down
115 changes: 115 additions & 0 deletions app/api/decision-tree/update/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { NextRequest, NextResponse } from 'next/server'
import { promises as fs } from 'fs'
import path from 'path'
import { createSupabaseServerClient } from '@/lib/supabase-server'

const ADMIN_EMAILS = ['eran@evolvinghome.ai']
const TREE_PATH = path.join(process.cwd(), 'docs/decision-tree/decision-tree-v1.json')
const HISTORY_PATH = path.join(process.cwd(), 'docs/decision-tree/decision-history.json')

async function ensureAuthorized() {
const hasSupabaseAuth = !!process.env.NEXT_PUBLIC_SUPABASE_URL && !!process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY

if (!hasSupabaseAuth) {
if (process.env.NODE_ENV !== 'production') return true
return false
}

const supabase = createSupabaseServerClient()
const {
data: { user },
} = await supabase.auth.getUser()

return !!user?.email && ADMIN_EMAILS.includes(user.email)
}

function findNode(tree: any, nodeId: string) {
if (nodeId === 'root') return tree.root
if (tree.decisions?.[nodeId]) return tree.decisions[nodeId]
if (Array.isArray(tree['unresolved-branches'])) {
return tree['unresolved-branches'].find((node: any) => node.nodeId === nodeId) || null
}
return null
}

export async function POST(req: NextRequest) {
try {
const allowed = await ensureAuthorized()
if (!allowed) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}

const body = await req.json().catch(() => ({}))
const nodeId = String(body.nodeId || '').trim()
const humanInput = body.humanInput
const status = body.status
const publicReady = body.publicReady

if (!nodeId) {
return NextResponse.json({ error: 'Missing nodeId' }, { status: 400 })
}

const raw = await fs.readFile(TREE_PATH, 'utf8')
const tree = JSON.parse(raw)
const target = findNode(tree, nodeId)

if (!target) {
return NextResponse.json({ error: 'Node not found' }, { status: 404 })
}

const before = {
humanInput: target.humanInput || '',
status: target.status,
publicReady: target.publicReady,
}

if (typeof humanInput === 'string') {
target.humanInput = humanInput.trim()
}
if (typeof status === 'string' && ['live', 'partial', 'planned', 'unresolved'].includes(status)) {
target.status = status
}
if (typeof publicReady === 'boolean') {
target.publicReady = publicReady
}

target.lastUpdated = new Date().toISOString().slice(0, 10)
tree.lastUpdated = new Date().toISOString()

await fs.writeFile(TREE_PATH, JSON.stringify(tree, null, 2) + '\n', 'utf8')

let history: any[] = []
try {
const historyRaw = await fs.readFile(HISTORY_PATH, 'utf8')
history = JSON.parse(historyRaw)
if (!Array.isArray(history)) history = []
} catch {
history = []
}

history.unshift({
timestamp: new Date().toISOString(),
nodeId,
before,
after: {
humanInput: target.humanInput || '',
status: target.status,
publicReady: target.publicReady,
},
})

await fs.writeFile(HISTORY_PATH, JSON.stringify(history.slice(0, 100), null, 2) + '\n', 'utf8')

return NextResponse.json({
ok: true,
nodeId,
humanInput: target.humanInput || '',
status: target.status,
publicReady: target.publicReady,
lastUpdated: target.lastUpdated,
})
} catch (error) {
console.error('decision-tree update error:', error)
return NextResponse.json({ error: 'Failed to update decision tree' }, { status: 500 })
}
}
Loading