mirror of
https://github.com/Hestia-Homes/assessment-model.git
synced 2026-07-12 13:28:55 +00:00
fix(plans): source headline SAP/EPC from baseline for new properties
The plans page computed the plan uplift as postSapPoints - currentSapPoints, but current_sap_points is unwritten on the property row for new-approach properties (null -> 0), so the uplift showed the full post score (e.g. +71.39) and no current rating. property-meta now backfills currentSapPoints / currentEpcRating from property_baseline_performance (lodged_sap_score / lodged_epc_band) for new-approach properties, fixing every propertyMeta consumer (plans page, hero cards, building passport). e.g. 709634: current 60 (D), uplift now +11.39. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
14f06abb6d
commit
5d87481b6b
2 changed files with 49 additions and 9 deletions
|
|
@ -1,7 +1,10 @@
|
|||
import { db } from "@/app/db/db";
|
||||
import { property } from "@/app/db/schema/property";
|
||||
import { serializeBigInt } from "@/app/utils";
|
||||
import { resolveDetailsEpcMeta } from "@/lib/services/epcSources";
|
||||
import {
|
||||
resolveDetailsEpcMeta,
|
||||
resolvePropertyHeadline,
|
||||
} from "@/lib/services/epcSources";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
|
||||
|
|
@ -38,15 +41,26 @@ export async function GET(request: NextRequest, props: { params: Promise<{ prope
|
|||
return new NextResponse(null, { status: 404 });
|
||||
}
|
||||
|
||||
// `detailsEpc` is resolved via the cutoff: legacy properties read
|
||||
// property_details_epc; new-approach ones read epc_property +
|
||||
// property_baseline_performance. See src/lib/services/epcSources.ts.
|
||||
const detailsEpc = await resolveDetailsEpcMeta(
|
||||
propertyMeta.id,
|
||||
propertyMeta.updatedAt,
|
||||
);
|
||||
// `detailsEpc` and the headline SAP/EPC are resolved via the cutoff: legacy
|
||||
// properties read property_details_epc / the property row; new-approach ones
|
||||
// read property_baseline_performance (the property-row headline columns aren't
|
||||
// written yet). See src/lib/services/epcSources.ts.
|
||||
const [detailsEpc, headline] = await Promise.all([
|
||||
resolveDetailsEpcMeta(propertyMeta.id, propertyMeta.updatedAt),
|
||||
resolvePropertyHeadline(propertyMeta.id, propertyMeta.updatedAt),
|
||||
]);
|
||||
|
||||
return new NextResponse(
|
||||
JSON.stringify({ ...propertyMeta, detailsEpc }, serializeBigInt),
|
||||
JSON.stringify(
|
||||
{
|
||||
...propertyMeta,
|
||||
currentSapPoints:
|
||||
headline.currentSapPoints ?? propertyMeta.currentSapPoints,
|
||||
currentEpcRating:
|
||||
headline.currentEpcRating ?? propertyMeta.currentEpcRating,
|
||||
detailsEpc,
|
||||
},
|
||||
serializeBigInt,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -381,6 +381,32 @@ export async function resolveConditionReport(
|
|||
return legacyConditionReport((legacy ?? {}) as Record<string, unknown>);
|
||||
}
|
||||
|
||||
/**
|
||||
* Headline SAP score + EPC band for the property meta. New-approach properties
|
||||
* don't have `current_sap_points` / `current_epc_rating` written on the row yet,
|
||||
* so we fall back to the lodged baseline (property_baseline_performance). Returns
|
||||
* nulls for legacy properties, signalling the caller to keep the row values.
|
||||
*
|
||||
* Uses lodged_* (gov-registry actual) to match the rest of the EPC reads; swap to
|
||||
* effective_* for the modelling-adjusted baseline.
|
||||
*/
|
||||
export async function resolvePropertyHeadline(
|
||||
propertyId: bigint,
|
||||
updatedAt: Date | string | null | undefined,
|
||||
): Promise<{ currentSapPoints: number | null; currentEpcRating: string | null }> {
|
||||
if (!isNewApproach(updatedAt)) {
|
||||
return { currentSapPoints: null, currentEpcRating: null };
|
||||
}
|
||||
const baseline = await db.query.propertyBaselinePerformance.findFirst({
|
||||
columns: { lodgedSapScore: true, lodgedEpcBand: true },
|
||||
where: eq(propertyBaselinePerformance.propertyId, propertyId),
|
||||
});
|
||||
return {
|
||||
currentSapPoints: baseline?.lodgedSapScore ?? null,
|
||||
currentEpcRating: baseline?.lodgedEpcBand ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
/** The minimal EPC meta the `/api/property-meta` route embeds as `detailsEpc`. */
|
||||
export interface DetailsEpcMeta {
|
||||
currentEnergyDemand: number | null;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue