fix: require completed photo review before pdf render
This commit is contained in:
@@ -100,12 +100,14 @@ Current behavior:
|
||||
- does not require recipient email(s) for the analysis-only run
|
||||
- asks for recipient email(s) only when PDF rendering is explicitly requested
|
||||
- does not render/send the PDF from a preliminary helper payload with `decision: pending`
|
||||
- does not render/send the PDF when `photoReview.status` is not `completed`
|
||||
- only renders the fixed-template PDF after a decision-grade verdict and fair-value range are actually present
|
||||
|
||||
Expected agent behavior:
|
||||
|
||||
- if the user asked for the full assessment, continue beyond the preliminary helper output
|
||||
- fill the remaining gaps with listing facts, comp work, condition interpretation, and valuation logic
|
||||
- require completed subject-unit photo review before treating the report as decision-grade enough for PDF delivery
|
||||
- only stop early when there is a real blocker, not merely because the helper stopped at a checkpoint
|
||||
|
||||
Important limitation:
|
||||
|
||||
@@ -120,12 +120,14 @@ scripts/property-assessor render-report --input "<report-payload-json>" --output
|
||||
- only stop and ask for recipient email(s) when the user is explicitly rendering or sending the PDF
|
||||
- render the PDF only after recipient email(s) are known
|
||||
- do **not** render or send a PDF from the helper's preliminary payload while verdict is still `pending` or fair value is not established
|
||||
- do **not** render or send a decision-grade PDF while `photoReview.status` is anything other than `completed`
|
||||
- if comps, valuation, or decision-grade condition interpretation are still incomplete, return the preliminary payload and say that the PDF/send step must wait
|
||||
|
||||
Agent follow-through rule:
|
||||
- When the user asked for a full property assessment or asked for the PDF/email result, do not stop at the helper output.
|
||||
- After `assess` returns a preliminary payload, continue with the remaining manual/model-driven steps needed to reach a decision-grade report.
|
||||
- Only after the verdict and fair-value range are established should you render/send the PDF.
|
||||
- A verdict and fair-value range are still not enough by themselves; the subject-unit photo review must also be completed before the PDF/send step.
|
||||
- If the analysis still cannot be completed, explain the first real blocker, not just that the helper was preliminary.
|
||||
- If the user sends `update?`, `and?`, or similar mid-run, answer with status and keep the original assessment going. Do not treat that message as a reset or a cue to stop at the last helper checkpoint.
|
||||
- In WhatsApp or similar messaging runs, do **not** start a background `assess` helper and then wait on repeated zero-output polls. That counts as a failed path; abandon it and continue with native search/fetch/browser work.
|
||||
|
||||
@@ -28,8 +28,10 @@ export interface ReportPayload {
|
||||
export function isDecisionGradeReportPayload(payload: ReportPayload): boolean {
|
||||
const decision = String(payload.verdict?.decision || "").trim().toLowerCase();
|
||||
const fairValueRange = String(payload.verdict?.fairValueRange || "").trim().toLowerCase();
|
||||
const photoReviewStatus = String(payload.photoReview?.status || "").trim().toLowerCase();
|
||||
if (!decision || decision === "pending") return false;
|
||||
if (!fairValueRange || fairValueRange === "not established") return false;
|
||||
if (photoReviewStatus !== "completed") return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -79,7 +81,7 @@ export function validateReportPayload(payload: ReportPayload): string[] {
|
||||
}
|
||||
if (!isDecisionGradeReportPayload(payload)) {
|
||||
throw new ReportValidationError(
|
||||
"The report payload is still preliminary. Stop and complete the decision-grade analysis before generating or sending the property assessment PDF."
|
||||
"The report payload is still preliminary. Stop and complete the decision-grade analysis, including subject-unit photo review, before generating or sending the property assessment PDF."
|
||||
);
|
||||
}
|
||||
return recipients;
|
||||
|
||||
@@ -87,3 +87,23 @@ test("renderReportPdf rejects a preliminary report with pending verdict", async
|
||||
/decision-grade|preliminary|pending/i
|
||||
);
|
||||
});
|
||||
|
||||
test("renderReportPdf rejects a report when subject-unit photo review is not completed", async () => {
|
||||
const outputPath = path.join(os.tmpdir(), `property-assessor-missing-photos-${Date.now()}.pdf`);
|
||||
await assert.rejects(
|
||||
() =>
|
||||
renderReportPdf(
|
||||
{
|
||||
...samplePayload,
|
||||
photoReview: {
|
||||
status: "not completed",
|
||||
source: "accessible listing-photo source not reliably exposed for unit 235",
|
||||
attempts: ["Zillow and HAR photo review did not complete."],
|
||||
summary: "Condition review is incomplete."
|
||||
}
|
||||
},
|
||||
outputPath
|
||||
),
|
||||
/photo review|decision-grade|incomplete/i
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user