From 5a86b3c96b3c0d9732ba7a60aea5a3db840cf458 Mon Sep 17 00:00:00 2001 From: Adam Moussa <166072409+amoussa1229@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:42:09 -0400 Subject: [PATCH] Add site_code and structured address fields to extraction prompt The Claude extraction prompt now explicitly asks for site_code (the Amazon facility code) and structured ship_to address fields (street, city, state, zip). The site-extractor Lambda prefers these direct fields when available, falling back to regex for older PO records. --- lambdas/email_processor/handler.py | 12 ++++++++++++ lambdas/site_extractor/handler.py | 16 ++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/lambdas/email_processor/handler.py b/lambdas/email_processor/handler.py index 4f28086..eea5a8e 100644 --- a/lambdas/email_processor/handler.py +++ b/lambdas/email_processor/handler.py @@ -52,9 +52,14 @@ Analyze the following email and extract structured data. Return ONLY valid JSON "supplier": { "name": "string or null" }, + "site_code": "string or null", "ship_to": { "name": "string or null", "address": "string or null", + "street": "string or null", + "city": "string or null", + "state": "string or null", + "zip": "string or null", "location_code": "string or null", "attn": "string or null" }, @@ -80,6 +85,13 @@ Rules: - Extract the PO number from the email (e.g., "2D-18206023") - Extract all line items with their descriptions, amounts, and metadata - Ship-to address should include the full address, location code, and attention line +- Ship-to street, city, state, and zip should be parsed from the address into separate fields +- "site_code" is the Amazon facility code (e.g., "SNY5", "DFW6", "WND1") — a 3-5 character alphanumeric code identifying the delivery site. Look for it in: + - The ship-to name, e.g., "Amazon.com Services LLC - SNY5" or "Amazon.com Services LLC (WFB1)" + - The ATTN line, e.g., "ATTN: Wagon Wheel DS - WTN1" + - Line item descriptions, e.g., "WND1 - 2024 - Plumbing PM" + - Anywhere else in the email where a facility code appears + - If the ship-to name IS the site code (e.g., just "DBU2"), use that - total_amount should be the numeric total in USD - If a field is not present in the email, set it to null - Do NOT invent or infer data that is not explicitly in the email diff --git a/lambdas/site_extractor/handler.py b/lambdas/site_extractor/handler.py index 7d8027f..2a187d1 100644 --- a/lambdas/site_extractor/handler.py +++ b/lambdas/site_extractor/handler.py @@ -27,6 +27,11 @@ def deserialize_image(image: dict) -> dict: def extract_site_code(record: dict) -> str | None: + # Prefer the explicit site_code field (set by updated extraction prompt) + direct = (record.get("site_code") or "").strip().upper() + if direct and SITE_CODE_PATTERN.match(direct): + return direct + ship_to = record.get("ship_to") or {} ship_to_name = ship_to.get("name", "") @@ -68,6 +73,17 @@ def parse_address(record: dict) -> dict: } ship_to = record.get("ship_to") or {} + + # Prefer structured fields if the extraction prompt provided them + if ship_to.get("street") and ship_to.get("state"): + result["address"] = ship_to["street"] + result["city"] = ship_to.get("city") + result["state"] = ship_to["state"] + result["zip"] = ship_to.get("zip") + parts = [p for p in [result["address"], result["city"], result["state"], result["zip"]] if p] + result["fullAddress"] = ", ".join(parts) + return result + address_text = ship_to.get("address", "") if not address_text: return result