diff --git a/backend/src/modules/health-scores/health-scores.service.ts b/backend/src/modules/health-scores/health-scores.service.ts index 762d516..ffd73a2 100644 --- a/backend/src/modules/health-scores/health-scores.service.ts +++ b/backend/src/modules/health-scores/health-scores.service.ts @@ -220,6 +220,14 @@ export class HealthScoresService { missing.push(`No budget found for ${year}. Upload or create an annual budget.`); } + // Should have reserve components (warn but don't block) + const components = await qr.query( + `SELECT COUNT(*) as cnt FROM reserve_components`, + ); + if (parseInt(components[0].cnt) === 0) { + missing.push('No reserve components found. Add reserve components (roof, parking, pool, etc.) with replacement costs for an accurate funded-ratio calculation.'); + } + // Should have capital projects (warn but don't block) const projects = await qr.query( `SELECT COUNT(*) as cnt FROM projects WHERE is_active = true`, @@ -997,8 +1005,8 @@ Reserve Cash (bank accounts): $${data.reserveCash.toFixed(2)} Reserve Investments: $${data.totalInvestments.toFixed(2)} Total Reserve Fund: $${data.totalReserveFund.toFixed(2)} -Total Replacement Cost (all components): $${data.totalReplacementCost.toFixed(2)} -Percent Funded: ${data.percentFunded.toFixed(1)}% +Total Replacement Cost (all components): ${data.totalReplacementCost > 0 ? '$' + data.totalReplacementCost.toFixed(2) : '$0.00 (no reserve components entered — funded ratio cannot be calculated)'} +Percent Funded: ${data.totalReplacementCost > 0 ? data.percentFunded.toFixed(1) + '%' : 'N/A — no reserve components with replacement costs have been entered. Do NOT report a 0% funded ratio; instead note that funded ratio is unavailable due to missing component data.'} Annual Reserve Contribution (budgeted income): $${data.annualReserveContribution.toFixed(2)} Annual Reserve Expenses (budgeted): $${data.annualReserveExpenses.toFixed(2)}