45 lines
2.1 KiB
Python
45 lines
2.1 KiB
Python
"""Site walkthrough analyzer: structured report from observations."""
|
|
import json, sys, os, re
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
|
|
from lib.db import now
|
|
|
|
# Issue patterns to flag
|
|
ISSUE_PATTERNS = {
|
|
r"water\s*damage|moisture|leak|mold": {"severity": "high", "category": "water_damage", "cost_impact": 1200},
|
|
r"crack|structural|foundation\s*issue|settling": {"severity": "high", "category": "structural", "cost_impact": 3000},
|
|
r"rot|decay|termite|pest": {"severity": "high", "category": "pest_damage", "cost_impact": 2000},
|
|
r"asbestos|lead\s*paint|hazmat": {"severity": "critical", "category": "hazmat", "cost_impact": 5000},
|
|
r"outdated\s*wiring|knob.and.tube|electrical\s*issue": {"severity": "medium", "category": "electrical", "cost_impact": 2500},
|
|
r"rust|corrosion|pipe": {"severity": "medium", "category": "plumbing", "cost_impact": 1500},
|
|
}
|
|
|
|
def analyze(observations, job_id=None, photos_description=None):
|
|
"""Analyze site observations and flag issues."""
|
|
combined = f"{observations} {photos_description or ''}"
|
|
issues = []
|
|
total_impact = 0
|
|
for pattern, info in ISSUE_PATTERNS.items():
|
|
if re.search(pattern, combined, re.I):
|
|
issues.append({
|
|
"category": info["category"],
|
|
"severity": info["severity"],
|
|
"estimated_cost_impact": info["cost_impact"],
|
|
"matched": re.search(pattern, combined, re.I).group(0)
|
|
})
|
|
total_impact += info["cost_impact"]
|
|
|
|
return {
|
|
"job_id": job_id,
|
|
"analyzed_at": now(),
|
|
"observations": observations,
|
|
"photos_description": photos_description,
|
|
"issues_found": len(issues),
|
|
"issues": issues,
|
|
"total_cost_impact": total_impact,
|
|
"recommendation": f"Add ${total_impact:,.0f} to estimate for remediation" if issues else "No significant issues detected"
|
|
}
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2: print(json.dumps({"error": "usage: site_analyzer.py <observations> [photos_desc]"}))
|
|
else: print(json.dumps(analyze(sys.argv[1], photos_description=sys.argv[2] if len(sys.argv)>2 else None), indent=2))
|