Build on the analysis.
HomeLens AI is one Next.js app. The website, the demo and the analysis endpoint ship together, with no separate backend.
Overview
The app ships Rithik’s anonymized artifacts as static JSON and runs a TypeScript port of his masking rules, complaint-phrase dictionary and TF–IDF logistic-regression model inside a route handler. A parity test checks the port against the Python model’s outputs.
POST /api/analyze
Scores one review. Send JSON with a text string of 3–5,000 characters. Anything else returns 400.
# request
curl -s -X POST https://homelensai.vercel.app/api/analyze \
-H 'content-type: application/json' \
-d '{"text":"They never showed up and overcharged me."}'Response
The actual response for the first demo example, trimmed. management_attention is true when the review risk meets the operating threshold; it is null when the model is unavailable and only dictionary signals remain.
{
"model": {
"name": "TF–IDF Logistic Regression",
"threshold": 0.585,
"available": true,
"is_primary": false,
"note": "Scored with the TF–IDF Logistic Regression model shipped in artifacts/ (the notebook's DistilBERT is not bundled with the web app)."
},
"risk_probability": 0.9629,
"operating_threshold": 0.585,
"management_attention": true,
"primary_aspect": "Pricing / Billing",
"detected_aspects": [
"Pricing / Billing",
"Timeliness",
"Workmanship"
],
"evidence": {
"index": 0,
"sentence": "The technician was three hours late, charged more than the quote, and the repair failed again two days later.",
"aspect": "Pricing / Billing",
"matched_phrases": {
"Workmanship": [
"repair failed"
],
"Timeliness": [
"hours late"
],
"Pricing / Billing": [
"charged more"
]
},
"risk_probability": 0.9629,
"has_dictionary_match": true
},
"recommended_action": "Review estimate accuracy, change-order approvals, and fee disclosure.",
"…": "sentences[], weights, matched_phrases, masking_applied, disclaimer"
}Risk tiers
Provider tiers are relative to this corpus. They rank providers; they are not probabilities of any outcome.
Stable Score below 50 (126 providers) Watch Score 50–75 (75 providers) Elevated Score 75–90 (47 providers) High concern Score 90 and above (6 providers)
Data files
Generated by scripts/export_frontend_data.py from artifacts/ and app/risk_logic.py. Never edit them by hand; CI fails if they are stale.
frontend/data/providers.json anonymized provider scores, tiers, yearly history frontend/data/aspects.json 8 aspects: lift, frequency, keywords, actions frontend/data/overview.json KPIs, tier counts, service groups, model metrics frontend/data/facts.json validated notebook facts (corpus size, splits) frontend/data/risk_config.json masking rules and phrase dictionary frontend/data/tfidf_model.json TF–IDF vocabulary, IDF and coefficients
Run locally
cd frontend npm install npm run dev # http://localhost:3000 npm run build && npm start
Optional environment variables: NEXT_PUBLIC_CONTACT_EMAIL, NEXT_PUBLIC_REPO_URL, NEXT_PUBLIC_SITE_URL. None are required.
Testing
npm test # 14 parity tests vs data/golden.json (Python outputs) npm run typecheck
Refresh the data after rebuilding artifacts: python scripts/build_artifacts.py && python scripts/export_frontend_data.py.
Responsible-use notes are on the Responsible AI page.
