🤖 AI Deal Analysis Agent
Autonomous Deal Analyzer
The AI Deal Analyzer scores any US property across BRRRR viability, flip profit potential, and market health using real-time data from 7 sources.
Enter any property and get a complete investment analysis grounded in real market data — comps, rehab estimates, cash flow, and a go/no-go recommendation.
🏠
AI-Powered Deal Analysis
Fill in the property details and click Analyze to get a complete investment breakdown — comps, rehab budget, cash flow model, and go/no-go score.
✅ Market comps
✅ Rehab estimate
✅ Cash flow model
🔒 Go/No-Go score
🔒 Risk analysis
⚙️
Running deal analysis...
Fetching market data...
Export
🔒 PDF Export (Premium)
⚠
Financial estimates only — not professional advice.
Results are calculated projections based on your inputs. Actual results vary. This is for illustration purposes only. Consult a financial advisor before making investment decisions.
Real estate investments involve risk. Consult a licensed
financial advisor, CPA, or real estate attorney before making investment decisions.
Full disclaimer →
✅ Credit purchased successfully! You can now run your analysis.
🔒
Daily Limit Reached
You've used your 3 free analyses today. Unlock more with a single purchase or go unlimited.
Maybe later
🏛️ Tax Implications
Planning to sell a property? A 1031 exchange can defer your capital gains tax by rolling proceeds into a new investment property.
'
);
}
// ── Section G: Sensitivity Analysis ──────────────────────────────────────
var G = sections.G_sensitivity || null;
if (G) {
if (G.locked) {
html += da2Section('📊', 'G. Sensitivity Analysis', 'Premium', '' +
'
📊
' +
'
Sensitivity Analysis Locked ' +
'
See how your returns change across rent, vacancy, and rate scenarios — instantly spot the deal's most vulnerable assumptions.
' +
'
');
} else {
var sensHtml = '';
// Rent sensitivity table
sensHtml += 'Rent Scenarios (holding vacancy + rate constant) ' +
'
' +
'Rent Change Monthly Rent Monthly CF Cap Rate CoC Return ' +
' ';
(G.rentSensitivity || []).forEach(function(row) {
var isBase = row.rentPct === 0;
sensHtml += '' +
'' + (row.rentPct > 0 ? '+' : '') + row.rentPct + '%' + (isBase ? ' (base)' : '') + ' ' +
'' + fmt$(row.rent) + '/mo ' +
'' + (row.monthlyNetCashFlow >= 0 ? '+' : '') + fmt$(row.monthlyNetCashFlow) + ' ' +
'' + row.capRate + '% ' +
'' + row.cocReturn + '% ' +
' ';
});
sensHtml += '
';
// Vacancy sensitivity table
sensHtml += 'Vacancy Scenarios (holding rent + rate constant) ' +
'
' +
'Vacancy Rate Monthly CF Cap Rate CoC Return ' +
' ';
(G.vacancySensitivity || []).forEach(function(row) {
var isBase = row.vacancy === Math.round(G.baseVacancy || 0);
sensHtml += '' +
'' + row.vacancy + '%' + (isBase ? ' (base)' : '') + ' ' +
'' + (row.monthlyNetCashFlow >= 0 ? '+' : '') + fmt$(row.monthlyNetCashFlow) + ' ' +
'' + row.capRate + '% ' +
'' + row.cocReturn + '% ' +
' ';
});
sensHtml += '
';
// Rate sensitivity table
sensHtml += 'Interest Rate Scenarios (holding rent + vacancy constant) ' +
'
' +
'Interest Rate Monthly CF Cap Rate CoC Return ' +
' ';
(G.rateSensitivity || []).forEach(function(row) {
var isBase = row.rate === (G.baseRate || 0);
sensHtml += '' +
'' + row.rate + '%' + (isBase ? ' (base)' : '') + ' ' +
'' + (row.monthlyNetCashFlow >= 0 ? '+' : '') + fmt$(row.monthlyNetCashFlow) + ' ' +
'' + row.capRate + '% ' +
'' + row.cocReturn + '% ' +
' ';
});
sensHtml += '
';
html += da2Section('📊', 'G. Sensitivity Analysis', '', sensHtml);
}
}
// Inject into page
var spinnerEl = document.getElementById('da2Spinner');
if (spinnerEl) {
spinnerEl.insertAdjacentHTML('afterend', html);
} else {
// Fallback: inject into results container directly
var _r = document.getElementById('da2Results');
if (_r) _r.insertAdjacentHTML('beforeend', html);
}
// track (null-safe — E_recommendation may not exist for free tier)
try {
var _E = (d.sections || {}).E_recommendation || {};
if(window.resh) window.resh.track('deal_analysis_generated', { city: (d.inputs || {}).city, state: (d.inputs || {}).state, recommendation: _E.locked ? 'locked' : (_E.recommendation || 'unknown'), confidence: _E.locked ? null : (_E.confidence_score || null) });
} catch(e) { console.error('[deal-analyzer] tracking error:', e); }
}
// ─── Chat Panel ───────────────────────────────────────────────────────────────
function da2RenderChatPanel(d) {
// Remove existing chat panel if any
var existing = document.getElementById('da2ChatPanel');
if (existing) existing.remove();
var isPremium = _da2UserIsPremium;
var maxQ = isPremium ? null : 3;
var suggestionsHtml = '';
var suggs = d.followUpSuggestions || [];
suggs.forEach(function(s) {
suggestionsHtml += '' + s + ' ';
});
var panel = document.createElement('div');
panel.id = 'da2ChatPanel';
panel.style.cssText = 'background:#fff;border:1px solid var(--border);border-radius:12px;overflow:hidden;box-shadow:var(--shadow-sm);margin-top:0;';
panel.innerHTML =
'' +
'
' +
'
💬 Ask a Follow-Up Question ' +
'
Explore scenarios and get answers grounded in this deal's data
' +
'
' +
(!isPremium ? '
3 questions remaining ' : '') +
'
' +
'
' +
'' +
'
' + suggestionsHtml + '
' +
'
' +
' ' +
'Ask → ' +
'
' +
'
';
document.getElementById('da2Results').appendChild(panel);
}
function da2ChatSuggest(btn) {
var input = document.getElementById('da2ChatInput');
if (input) { input.value = btn.textContent; input.focus(); }
}
function da2SendChat() {
var input = document.getElementById('da2ChatInput');
var question = input ? input.value.trim() : '';
if (!question) return;
if (!_da2LastAnalysis) { alert('Run an analysis first.'); return; }
var maxQ = _da2UserIsPremium ? Infinity : 3;
if (_da2ChatQCount >= maxQ) {
da2ChatAppendMsg('system', '🔒 You've used all 3 free questions. Upgrade for unlimited Q&A → ');
return;
}
input.value = '';
da2ChatAppendMsg('user', question);
var loadingId = 'da2cl-' + Date.now();
da2ChatAppendMsg('loading', '...', loadingId);
// Hide suggestions while typing
var suggs = document.getElementById('da2ChatSuggestions');
if (suggs) suggs.style.display = 'none';
fetch('/api/v1/agents/deal-analysis/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({
question: question,
analysisContext: _da2LastAnalysis,
chatHistory: _da2ChatHistory,
questionCount: _da2ChatQCount,
}),
})
.then(function(r) { return r.json(); })
.then(function(data) {
var loadEl = document.getElementById(loadingId);
if (loadEl) loadEl.remove();
if (!data.success) {
if (data.code === 'CHAT_LIMIT_REACHED') {
da2ChatAppendMsg('system', '🔒 Free limit reached. Upgrade for unlimited Q&A → ');
} else {
da2ChatAppendMsg('system', '⚠️ ' + (data.message || 'Error — please try again.'));
}
return;
}
_da2ChatQCount++;
_da2ChatHistory.push({ role: 'user', content: question });
_da2ChatHistory.push({ role: 'assistant', content: data.answer });
da2ChatAppendMsg('assistant', data.answer);
// Update counter for free users
if (!_da2UserIsPremium) {
var counter = document.getElementById('da2ChatCounter');
var remaining = data.questionsRemaining != null ? data.questionsRemaining : Math.max(0, 3 - _da2ChatQCount);
if (counter) counter.textContent = remaining + ' question' + (remaining === 1 ? '' : 's') + ' remaining';
if (remaining <= 0) {
var inp = document.getElementById('da2ChatInput');
if (inp) { inp.disabled = true; inp.placeholder = 'Upgrade for unlimited Q&A'; }
var askBtn = document.querySelector('#da2ChatPanel button[onclick="da2SendChat()"]');
if (askBtn) askBtn.disabled = true;
}
}
// Show new suggestions
if (data.suggestions && suggs) {
suggs.style.display = 'flex';
suggs.innerHTML = '';
data.suggestions.forEach(function(s) {
suggs.innerHTML += '' + s + ' ';
});
}
})
.catch(function(e) {
var loadEl = document.getElementById(loadingId);
if (loadEl) loadEl.remove();
da2ChatAppendMsg('system', '⚠️ Network error — please try again.');
});
}
// ─── Phase 2 Scorecard ────────────────────────────────────────────────────────
function da2FetchScorecard(phase1Data) {
// Don't inject a second scorecard if one already exists
if (document.getElementById('da2ScorecardSection')) return;
// Placeholder while loading
var placeholder = document.createElement('div');
placeholder.id = 'da2ScorecardSection';
placeholder.className = 'da2-section';
placeholder.innerHTML =
'🏆
H. AI Deal Scorecard Phase 2 · Loading... ' +
'⚙️ Calculating BRRRR score, flip profit, market health...
';
var chatPanel = document.getElementById('da2ChatPanel');
if (chatPanel) {
chatPanel.insertAdjacentElement('beforebegin', placeholder);
} else {
var spinnerEl = document.getElementById('da2Spinner');
if (spinnerEl) spinnerEl.insertAdjacentElement('afterend', placeholder);
}
fetch('/api/v1/agents/deal-analysis/scorecard', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({
inputs: phase1Data.inputs,
sections: phase1Data.sections,
}),
})
.then(function(r) { return r.json(); })
.then(function(data) {
if (!data.success || !data.scorecard) {
placeholder.remove();
return;
}
var sc = data.scorecard;
var shareUrl = data.shareUrl;
var pdfUrl = data.pdfUrl;
var scoreColor = sc.overallColor || (sc.overallScore >= 75 ? '#16a34a' : sc.overallScore >= 55 ? '#d97706' : '#dc2626');
function fmtS(n) { return n != null ? '$' + Math.abs(Math.round(n || 0)).toLocaleString() : 'N/A'; }
function pctS(n) { return n != null ? parseFloat(n).toFixed(2) + '%' : 'N/A'; }
// Top-line scorecard (always shown)
var topHtml =
'' +
'
' +
'
Overall Score
' +
'
' + sc.overallScore + '
' +
'
' + (sc.overallLabel || '') + '
' +
'
' +
'
' +
'
Cash-on-Cash
' +
'
' + pctS(sc.topLine.cashOnCash) + '
' +
'
Annual return on cash
' +
'
' +
'
' +
'
Cap Rate
' +
'
' + pctS(sc.topLine.capRate) + '
' +
'
NOI ÷ purchase price
' +
'
' +
'
';
// AI 2-sentence summary (always shown if available)
if (sc.aiSummary) {
topHtml +=
'' +
'
🤖 AI Analysis
' +
'
' + sc.aiSummary + '
' +
'
';
}
// Premium extended metrics or lock prompt
var premiumHtml = '';
if (sc.brrrr && !sc.brrrr.locked) {
// BRRRR
var br = sc.brrrr;
var brColor = br.score >= 70 ? '#16a34a' : br.score >= 50 ? '#d97706' : '#dc2626';
premiumHtml +=
'' +
'
🔄 BRRRR Feasibility ' +
'
' +
'
' + br.score + '
' +
'
' + (br.feasible ? '✓ Feasible' : '✗ Not Recommended') + '
' +
'
' + (br.recommendation || '') + '
' +
'
' +
'
' +
'
ARV: ' + fmtS(br.arv) + ' (confidence: ' + (br.arvConfidence || 'low') + ')
' +
'
Refi (75% LTV): ' + fmtS(br.refiAmount) + '
' +
'
Cash left in: ' + fmtS(br.cashLeftIn) + '
' +
'
Post-refi CF: ' + fmtS(br.postRefiMonthlyCashFlow) + '/mo
' +
'
' +
'
ARV source: ' + (br.arvSource || 'market_benchmarks') + '
' +
'
';
// Flip
var fl = sc.flip;
if (fl && !fl.locked) {
var flipColor = fl.scenarios.base.profit >= 20000 ? '#16a34a' : fl.scenarios.base.profit >= 0 ? '#d97706' : '#dc2626';
premiumHtml +=
'' +
'
🏗️ Flip Profit Estimate ' +
'
' +
'
' +
'
Pessimistic
' +
'
' + fmtS(fl.scenarios.pessimistic.profit) + '
' +
'
' + fl.scenarios.pessimistic.roi + '% ROI
' +
'
' +
'
' +
'
Base Case
' +
'
' + fmtS(fl.scenarios.base.profit) + '
' +
'
' + fl.scenarios.base.roi + '% ROI
' +
'
' +
'
' +
'
Optimistic
' +
'
' + fmtS(fl.scenarios.optimistic.profit) + '
' +
'
' + fl.scenarios.optimistic.roi + '% ROI
' +
'
' +
'
' +
'
' +
'ARV: ' + fmtS(fl.arv) + ' ' +
'MAO (70% rule): ' + fmtS(fl.mao) + ' ' +
'
' +
'
' + (fl.viability || '') + '
' +
'
';
}
// Rental Yield
var ry = sc.rentalYield;
if (ry && !ry.locked) {
premiumHtml +=
'' +
'
📈 Rental Yield ' +
'
' +
'
Gross Yield
' + pctS(ry.grossYield) + '
' +
'
Net Yield
' + pctS(ry.netYield) + '
' +
'
' +
'
' + (ry.yieldRating || '') + '
' +
'
';
}
// Market Health
var mh = sc.marketHealth;
if (mh && !mh.locked) {
if (mh.available) {
var mhColor = mh.color || '#d97706';
premiumHtml +=
'' +
'
🗺️ Market Health — ' + (mh.city || '') + ' ' +
'
' +
'
' + mh.score + '
' +
'
' + (mh.label || '') + '
' +
'
' + (mh.isFallback ? 'State-level data' : 'City-level data') + ' · ' + (mh.dataSources.priceAppreciation || 'market_benchmarks') + '
' +
'
' +
'
' +
'
YoY Price Change: ' + (mh.yoyPriceChange != null ? (mh.yoyPriceChange >= 0 ? '+' : '') + mh.yoyPriceChange.toFixed(1) + '%' : 'N/A') + '
' +
'
Vacancy: ' + (mh.vacancyRate != null ? mh.vacancyRate.toFixed(1) + '%' : 'N/A') + '
' +
'
Avg Cap Rate: ' + (mh.avgCapRate != null ? mh.avgCapRate.toFixed(2) + '%' : 'N/A') + '
' +
'
Price-to-Rent: ' + (mh.priceToRentRatio != null ? mh.priceToRentRatio + '×' : 'N/A') + '
' +
'
' +
'
';
} else {
premiumHtml +=
'' +
'
🗺️ Market Health ' +
'
' + (mh.message || 'Market data unavailable for this city') + '
' +
'
';
}
}
// Risk Score
var rs = sc.riskScore;
if (rs && !rs.locked) {
var rsColor = rs.level === 'low' ? '#16a34a' : rs.level === 'medium' ? '#d97706' : '#dc2626';
var rsBg = rs.level === 'low' ? '#f0fdf4' : rs.level === 'medium' ? '#fffbeb' : '#fef2f2';
premiumHtml +=
'' +
'
⚠️ Risk Assessment ' +
'
' +
'' + (rs.level || 'N/A') + ' Risk ' +
'— ' + (rs.description || '') + ' ' +
'
' +
(rs.signals || []).slice(0, 5).map(function(s) {
var c = s.severity === 'high' ? '#b91c1c' : s.severity === 'medium' ? '#854d0e' : '#15803d';
var bg = s.severity === 'high' ? '#fee2e2' : s.severity === 'medium' ? '#fef9c3' : '#dcfce7';
return '
' +
'' + s.severity + ' ' +
'' + s.signal + ' ' +
'
';
}).join('') +
'
';
}
} else if (sc.brrrr && sc.brrrr.locked) {
// Locked premium upsell
premiumHtml =
'' +
'
🔒
' +
'
Unlock Phase 2 Scorecard ' +
'
Get BRRRR feasibility score, flip profit estimate (low/base/high), market health score, rental yield, and AI risk assessment.
' +
'
Hint: BRRRR score preview: ' + (sc.brrrr.previewScore || '?') + '/100 ' +
(sc.brrrr.previewFeasible ? ' — appears feasible ✓' : ' — may not be ideal') + '
' +
'
' +
'
';
}
// Share + PDF CTAs
var ctaHtml = '';
if (shareUrl || pdfUrl) {
ctaHtml =
'';
}
var bodyHtml = topHtml + premiumHtml + ctaHtml;
placeholder.innerHTML =
'🏆
H. AI Deal Scorecard (Phase 2) Powered by Polsia AI ' +
'' + bodyHtml + '
';
})
.catch(function(e) {
// Silently remove placeholder on failure — Phase 1 results are unaffected
if (placeholder && placeholder.parentNode) placeholder.remove();
});
}
function da2ChatAppendMsg(role, content, id) {
var msgs = document.getElementById('da2ChatMessages');
if (!msgs) return;
var div = document.createElement('div');
if (id) div.id = id;
if (role === 'user') {
div.style.cssText = 'align-self:flex-end;background:var(--accent);color:#fff;border-radius:10px 10px 2px 10px;padding:0.6rem 0.9rem;max-width:82%;font-size:0.875rem;line-height:1.5';
div.textContent = content;
} else if (role === 'assistant') {
div.style.cssText = 'align-self:flex-start;background:var(--bg2);border:1px solid var(--border);border-radius:10px 10px 10px 2px;padding:0.6rem 0.9rem;max-width:92%;font-size:0.875rem;line-height:1.65';
// Render markdown-ish: bold, bullets
var html = content
.replace(/**(.+?)**/g, '$1 ')
.replace(/^- (.+)$/gm, '• $1')
.replace(/
/g, ' ')
.replace(/
/g, ' ');
div.innerHTML = html;
} else if (role === 'loading') {
div.style.cssText = 'align-self:flex-start;background:var(--bg2);border:1px solid var(--border);border-radius:10px;padding:0.6rem 0.9rem;font-size:0.875rem;color:var(--text3)';
div.innerHTML = 'Analyzing your question... ';
} else {
div.style.cssText = 'text-align:center;font-size:0.8rem;color:var(--text3);padding:0.25rem';
div.innerHTML = content;
}
msgs.appendChild(div);
msgs.scrollTop = msgs.scrollHeight;
}