This commit is contained in:
2026-07-14 14:17:18 -05:00
parent d8d62fa371
commit db8e6cce21

View File

@@ -99,6 +99,7 @@ interface VisionRaw {
info_sheet_count: number;
info_page: number | null;
ca_page: number | null;
notes_page: number | null;
name_company: string | null;
prospective_buyer: string | null;
company: string | null;
@@ -272,7 +273,7 @@ const RESPONSE_SCHEMA = {
type: "object",
additionalProperties: false,
required: [
"doc_type", "info_sheet_count", "info_page", "ca_page", "name_company",
"doc_type", "info_sheet_count", "info_page", "ca_page", "notes_page", "name_company",
"prospective_buyer", "company", "phone", "cell", "email", "address",
"state", "how_did_you_hear", "interested_in_updates",
"types_of_business_raw", "notes_business_raw", "background_experience",
@@ -283,6 +284,7 @@ const RESPONSE_SCHEMA = {
info_sheet_count: { type: "integer" },
info_page: nullableInt,
ca_page: nullableInt,
notes_page: nullableInt,
name_company: nullableString,
prospective_buyer: nullableString,
company: nullableString,
@@ -310,29 +312,38 @@ const SYSTEM_PROMPT =
const USER_PROMPT = `You see all pages of one PDF, in order (image 1 = page 1).
Task: Classify the document and transcribe form fields from a business brokerage "BUYER INFORMATION SHEET" package.
Task: Identify the page types by their headings, then transcribe form fields from a business brokerage "BUYER INFORMATION SHEET" package.
1. doc_type:
- "buyer_sheet": at least one page with the heading "BUYER INFORMATION SHEET" exists.
- "ca_only": no such page, but a confidentiality agreement page exists (text like "PROSPECTIVE BUYER AGREES TO KEEP AND HOLD CONFIDENTIAL").
- "other": neither (notes, listing, letter, other form) — then return null for every field and 0 for info_sheet_count.
2. info_sheet_count: how many separate BUYER INFORMATION SHEET pages the document contains (some files contain two filled sheets). 0 if none. If more than one, transcribe the fields from the FIRST sheet only.
3. info_page: page number (1-based) of the (first) BUYER INFORMATION SHEET page, else null.
4. ca_page: page number of the (first) confidentiality agreement page, else null.
5. If doc_type is "buyer_sheet", transcribe from the info page VERBATIM (exactly as written, do not normalize, do not expand abbreviations):
- name_company: value of the "Name/Company" line
- prospective_buyer: value of the "Prospective Buyer" line
- company: value of a separate "Company" line if present
STEP 1 — Identify each page by its UNIQUE marker text (pages can appear in ANY order):
- NOTES page: contains the text "Date NDA Scanned". It is a handwritten cover sheet with "Name:", "Date NDA Scanned:", a two-column table headed "Business Interested In:", and a free-text "Notes" area at the bottom. NOT every package has one.
- INFO SHEET page: contains the heading "BUYER INFORMATION SHEET".
- CA page: contains "CONFIDENTIALITY AGREEMENT" or "PROSPECTIVE BUYER AGREES TO KEEP AND HOLD CONFIDENTIAL".
Set notes_page, info_page, ca_page to the respective 1-based page numbers, or null if that page type is absent.
CRITICAL: a page with "Date NDA Scanned" is the NOTES page, NEVER the info sheet — even if it is page 1.
STEP 2 — doc_type:
- "buyer_sheet": an INFO SHEET page exists.
- "ca_only": no info sheet, but a CA page exists.
- "other": none of the above — return null for every field and 0 for info_sheet_count.
2. info_sheet_count: how many separate INFO SHEET pages exist (some files contain two). 0 if none. If more than one, transcribe from the FIRST info sheet only.
STEP 3 — Transcribe VERBATIM (exactly as written, do not normalize or expand abbreviations), each field ONLY from the page type named:
5. From the INFO SHEET page (only if info_page is set):
- name_company: "Name/Company" line
- prospective_buyer: "Prospective Buyer" line
- company: separate "Company" line if present
- phone, cell, email, address, state
- how_did_you_hear: "How did you hear about us"
- interested_in_updates: answer/checkbox for receiving updates (transcribe what is marked, e.g. "Yes" or "No"), else null
- types_of_business_raw: "Type(s) of business interested in" from the INFO SHEET only (may span multiple lines — join with a space). Do NOT put Notes-page content here.
- interested_in_updates: the marked updates answer/checkbox ("Yes"/"No"), else null
- types_of_business_raw: the "Type(s) of business interested in" list FROM THE INFO SHEET ONLY (may span multiple lines — join with a space). This must come from the info sheet page, NEVER from the notes page.
- background_experience: "Background/Experience" (may span multiple lines)
- total_purchase_price: "Total Purchase Price" as written
- down_payment_raw: "Down Payment" as written (e.g. "$350,000", "1.5M", "TBD")
6. If doc_type is "ca_only": transcribe what the confidentiality agreement page offers — the prospective buyer's printed or signed name into prospective_buyer, plus address/phone/email if they appear on that page. Everything not present stays null.
7. date_of_introduction_raw: the date written next to the buyer's signature on the confidentiality agreement page, verbatim (e.g. "6/25/26"), else null.
8. notes_business_raw (applies to ANY doc_type): Some packages contain a separate scanned "Notes" cover page — a handwritten sheet with fields like "Name:", "Date NDA Scanned:", and a two-column table headed "Business Interested In:". If such a Notes page is present, transcribe the business name(s) written in that table here, verbatim (join multiple entries with a comma). This is a DIFFERENT and INDEPENDENT source from types_of_business_raw (which comes from the info sheet) — never merge the two. If no Notes page exists or its table is empty, return null.
6. If doc_type is "ca_only": transcribe from the CA page — the prospective buyer's printed/signed name into prospective_buyer, plus address/phone/email if present. Everything else null.
7. date_of_introduction_raw: the date next to the buyer's signature on the CA page, verbatim (e.g. "6/25/26"), else null.
8. From the NOTES page (only if notes_page is set):
- notes_business_raw: the business name(s) written in the "Business Interested In" TABLE of the notes page, verbatim (join multiple with a comma). Take ONLY the table entries — do NOT include the free-text "Notes" area at the bottom of the page. If the table is empty, null.
The notes page and the info sheet are INDEPENDENT sources; never copy content from one into the other's field.
A blank field, "N/A", "n", or an empty line = transcribe it as written; if truly empty, use null.
Handwriting rules: Transcribe handwritten values letter by letter — do NOT complete them from context or from other fields. Email addresses are the most reliable spelling source on the page: read the email character by character, and if a handwritten name is ambiguous (e.g. B vs D), prefer the spelling that appears in the email address. Never alter the email itself to match your reading of the name.
@@ -419,7 +430,7 @@ function mergeRecord(det: BuyerRecord, vis: VisionRaw, model: string): BuyerReco
delete (base as Record<string, unknown>)["_vision_error"];
if (vis.doc_type === "other") {
return { ...base, is_buyer_sheet: false, _doc_type: "other", _info_page: null, _ca_page: null };
return { ...base, is_buyer_sheet: false, _doc_type: "other", _info_page: null, _ca_page: null, _notes_page: vis.notes_page ?? null };
}
// buyer_sheet ODER ca_only: alles übernehmen, was das Dokument hergibt
@@ -449,6 +460,7 @@ function mergeRecord(det: BuyerRecord, vis: VisionRaw, model: string): BuyerReco
date_of_introduction: normDate(vis.date_of_introduction_raw) ?? (det.date_of_introduction as string | null) ?? null,
_info_page: vis.info_page,
_ca_page: vis.ca_page,
_notes_page: vis.notes_page,
};
}