feat: branch fallback for assets without account linkage
- 1,606 more assets now get company from branch/territory name (e.g. 'Canteen Corp/Orlando, FL') when the connect_id exists in extraction DB but has no linked account name - Coverage: 7,349/7,488 (98.1%) have company + customer_name - Only 139 remain empty (4 prefixes not in branch cache) - Updated AGENTS.md with data population docs
This commit is contained in:
@@ -1,6 +1,18 @@
|
||||
# Canteen Asset Tracker — Agent Guide
|
||||
# Canteen Asset Tracker
|
||||
|
||||
Mobile-friendly webapp for tracking physical assets with barcode scanning, OCR sticker reading, and GPS check-ins. The main technician-facing application in the Canteen stack.
|
||||
Mobile-friendly webapp for tracking physical assets with barcode scanning, OCR sticker reading, and GPS check-ins. The main technician-facing application.
|
||||
|
||||
...
|
||||
|
||||
## Company & Place Data
|
||||
|
||||
Asset company, customer_name, and place fields are populated from the MSFS Dynamics 365 extraction DB. The migration script `scripts/populate_asset_company_place.py` maps each asset's `connect_id` → `msdyn_customerasset` → `account` table to get:
|
||||
|
||||
- **company** = account name (e.g. "Jeremy B - 1960 Broadway")
|
||||
- **place** = city name (e.g. "Orlando")
|
||||
- **customer_name** = account name (same as company, for search/filter)
|
||||
|
||||
5,743/7,488 assets (~77%) have company data; remaining 1,745 have connect_ids with no account linkage in the extraction DB.
|
||||
|
||||
## Stack
|
||||
|
||||
|
||||
@@ -71,7 +71,18 @@ def get_mapping() -> dict[str, dict]:
|
||||
}
|
||||
|
||||
print(f"📡 Loaded {len(result)} connect_id mappings from extraction DB")
|
||||
return result
|
||||
|
||||
# Also build the branch cache for fallback on unmatched assets
|
||||
try:
|
||||
sys.path.insert(0, str(Path.home() / "projects" / "canteen-asset-tracker"))
|
||||
from server import _build_asset_branch_cache
|
||||
branch_cache = _build_asset_branch_cache()
|
||||
print(f"📡 Branch cache has {len(branch_cache)} prefix→territory mappings")
|
||||
except Exception as e:
|
||||
print(f"⚠️ Could not load branch cache: {e}")
|
||||
branch_cache = {}
|
||||
|
||||
return result, branch_cache
|
||||
|
||||
|
||||
def main():
|
||||
@@ -96,7 +107,7 @@ def main():
|
||||
print(f" Empty customer_name:{stats['empty_customer_name']}")
|
||||
print(f" Empty address: {stats['empty_address']}")
|
||||
|
||||
mapping = get_mapping()
|
||||
mapping, branch_cache = get_mapping()
|
||||
|
||||
# Fetch all assets with connect_id
|
||||
assets = conn.execute("""
|
||||
@@ -108,6 +119,7 @@ def main():
|
||||
updates = {"company": 0, "place": 0, "customer_name": 0, "address": 0}
|
||||
skipped_no_match = 0
|
||||
skipped_has_data = 0
|
||||
branch_fallback = 0
|
||||
|
||||
update_sqls = {
|
||||
"company": "UPDATE assets SET company = ? WHERE id = ?",
|
||||
@@ -119,9 +131,19 @@ def main():
|
||||
for a in assets:
|
||||
info = mapping.get(a["connect_id"])
|
||||
if not info:
|
||||
# No connect_id match in extraction DB at all
|
||||
skipped_no_match += 1
|
||||
continue
|
||||
|
||||
# If account name is empty, try branch cache fallback
|
||||
if (not a["company"] or not a["company"].strip()) and (not info["company"] or not info["company"].strip()):
|
||||
pfx = a["connect_id"][:8]
|
||||
branch_name = branch_cache.get(pfx)
|
||||
if branch_name:
|
||||
info["company"] = branch_name
|
||||
info["customer_name"] = branch_name
|
||||
branch_fallback += 1
|
||||
|
||||
if a["company"] and a["place"] and a["customer_name"] and a["address"]:
|
||||
skipped_has_data += 1
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user