Spaces:
Sleeping
Sleeping
| """ | |
| cost_matrix.py | |
| ββββββββββββββ | |
| Deterministic INR cost lookup table for GharScan. | |
| No model hallucination here β pure market-rate data (Delhi/NCR, 2026). | |
| Cost ranges sourced from: HouseYog, Comaron, UrbanCompany quoted rates, | |
| and standard PWD schedule-of-rates for residential repairs. | |
| Lower bound = Tier-2/3 city rates OR small affected area (< 2 sq ft) | |
| Upper bound = Delhi/NCR metro rates OR large affected area (> 10 sq ft) | |
| """ | |
| from dataclasses import dataclass | |
| from typing import Optional | |
| class CostEntry: | |
| cost_range_inr: str | |
| professional_type: str # painter | mason | waterproofing_contractor | civil_engineer | |
| urgency_timeline: str # next_renovation | within_6_months | within_1_month | this_week | immediately | |
| disclaimer: Optional[str] = None | |
| requires_engineer: bool = False | |
| # ββ Severity labels ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| SEVERITY_LABELS = { | |
| 1: "Cosmetic", | |
| 2: "Minor", | |
| 3: "Moderate", | |
| 4: "Serious", | |
| 5: "Critical", | |
| } | |
| SEVERITY_COLORS = { | |
| 1: "#22c55e", # green | |
| 2: "#84cc16", # lime | |
| 3: "#f59e0b", # amber | |
| 4: "#ef4444", # red | |
| 5: "#7f1d1d", # dark red | |
| } | |
| # ββ Main cost matrix βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
| # Structure: COST_MATRIX[defect_type][severity_1_to_5] = CostEntry | |
| COST_MATRIX: dict[str, dict[int, CostEntry]] = { | |
| "hairline_crack": { | |
| 1: CostEntry("βΉ200ββΉ400", "painter", "next_renovation"), | |
| 2: CostEntry("βΉ400ββΉ800", "painter", "next_renovation"), | |
| 3: CostEntry("βΉ800ββΉ1,500", "mason", "within_6_months"), | |
| 4: CostEntry("βΉ1,500ββΉ3,000","mason", "within_1_month"), | |
| 5: CostEntry("βΉ3,000ββΉ6,000","civil_engineer", "this_week", | |
| disclaimer="Multiple hairline cracks over large area β professional assessment strongly advised."), | |
| }, | |
| "settlement_crack": { | |
| 1: CostEntry("βΉ400ββΉ600", "mason", "next_renovation"), | |
| 2: CostEntry("βΉ600ββΉ1,200", "mason", "within_6_months"), | |
| 3: CostEntry("βΉ1,500ββΉ4,000", "mason", "within_6_months"), | |
| 4: CostEntry("βΉ5,000ββΉ15,000", "civil_engineer", "within_1_month", | |
| disclaimer="Severity 4 settlement cracks indicate significant differential movement. Professional structural assessment required before any repair.", | |
| requires_engineer=True), | |
| 5: CostEntry("Assessment required", "civil_engineer", "this_week", | |
| disclaimer="URGENT: Wide or active settlement cracks may indicate ongoing foundation failure. Do not delay professional structural inspection.", | |
| requires_engineer=True), | |
| }, | |
| "structural_crack": { | |
| 1: CostEntry("βΉ800ββΉ1,500", "mason", "within_6_months"), | |
| 2: CostEntry("βΉ2,000ββΉ6,000", "civil_engineer", "within_1_month"), | |
| 3: CostEntry("βΉ8,000ββΉ25,000", "civil_engineer", "this_week", | |
| requires_engineer=True), | |
| 4: CostEntry("Assessment required", "civil_engineer", "this_week", | |
| disclaimer="SERIOUS: Structural cracks at this severity require immediate professional inspection. Do not attempt DIY repairs.", | |
| requires_engineer=True), | |
| 5: CostEntry("Vacate and call engineer", "civil_engineer", "immediately", | |
| disclaimer="CRITICAL STRUCTURAL RISK: This defect may compromise load-bearing capacity. Vacate the area immediately and contact a structural engineer.", | |
| requires_engineer=True), | |
| }, | |
| "water_seepage": { | |
| 1: CostEntry("βΉ500ββΉ1,000", "mason", "next_renovation"), | |
| 2: CostEntry("βΉ1,500ββΉ4,000", "waterproofing_contractor", "within_6_months"), | |
| 3: CostEntry("βΉ4,000ββΉ12,000", "waterproofing_contractor", "within_1_month"), | |
| 4: CostEntry("βΉ10,000ββΉ25,000","waterproofing_contractor", "this_week", | |
| disclaimer="Extensive seepage can weaken structural elements over time. Address before next monsoon season."), | |
| 5: CostEntry("βΉ20,000ββΉ60,000","waterproofing_contractor", "this_week", | |
| disclaimer="Active water ingress at this scale indicates waterproofing system failure. Professional treatment of source (terrace/external wall) is required, not just surface patching.", | |
| requires_engineer=True), | |
| }, | |
| "efflorescence": { | |
| 1: CostEntry("βΉ200ββΉ500", "painter", "next_renovation"), | |
| 2: CostEntry("βΉ500ββΉ1,500", "mason", "next_renovation"), | |
| 3: CostEntry("βΉ1,500ββΉ4,000","waterproofing_contractor", "within_6_months"), | |
| 4: CostEntry("βΉ4,000ββΉ10,000","waterproofing_contractor", "within_1_month", | |
| disclaimer="Heavy efflorescence indicates sustained moisture migration β treat the moisture source, not just the surface deposits."), | |
| 5: CostEntry("βΉ10,000ββΉ20,000","waterproofing_contractor", "this_week", | |
| disclaimer="Severe salt deposits with visible masonry deterioration. Source moisture must be identified and stopped before cosmetic repair."), | |
| }, | |
| "spalling": { | |
| 1: CostEntry("βΉ1,000ββΉ2,500", "mason", "within_6_months"), | |
| 2: CostEntry("βΉ3,000ββΉ8,000", "mason", "within_1_month"), | |
| 3: CostEntry("βΉ8,000ββΉ20,000", "civil_engineer", "this_week", | |
| requires_engineer=True), | |
| 4: CostEntry("Assessment required", "civil_engineer", "this_week", | |
| disclaimer="SERIOUS: Concrete spalling with exposed reinforcement requires professional structural assessment β the scope of repair cannot be estimated from image alone.", | |
| requires_engineer=True), | |
| 5: CostEntry("Vacate area β engineer required", "civil_engineer", "immediately", | |
| disclaimer="CRITICAL: Extensive spalling with exposed steel poses imminent risk of further concrete fall. Vacate the area below.", | |
| requires_engineer=True), | |
| }, | |
| "rebar_rust": { | |
| 1: CostEntry("βΉ2,000ββΉ5,000", "mason", "within_1_month"), | |
| 2: CostEntry("βΉ5,000ββΉ15,000", "civil_engineer", "this_week", | |
| requires_engineer=True), | |
| 3: CostEntry("βΉ15,000ββΉ40,000", "civil_engineer", "this_week", | |
| disclaimer="Rebar corrosion reduces structural capacity. Extent of rust along rebar length must be assessed by a structural engineer.", | |
| requires_engineer=True), | |
| 4: CostEntry("Assessment required", "civil_engineer", "immediately", | |
| disclaimer="SERIOUS: Visible rebar corrosion with concrete delamination. Structural capacity may be significantly compromised.", | |
| requires_engineer=True), | |
| 5: CostEntry("Vacate area β urgent inspection", "civil_engineer", "immediately", | |
| disclaimer="CRITICAL STRUCTURAL RISK: Extensive rebar corrosion threatens structural integrity. Immediate professional inspection mandatory.", | |
| requires_engineer=True), | |
| }, | |
| "plaster_delamination": { | |
| 1: CostEntry("βΉ300ββΉ600", "painter", "next_renovation"), | |
| 2: CostEntry("βΉ600ββΉ1,500", "mason", "next_renovation"), | |
| 3: CostEntry("βΉ1,500ββΉ5,000", "mason", "within_6_months"), | |
| 4: CostEntry("βΉ5,000ββΉ12,000","mason", "within_1_month", | |
| disclaimer="Large-area delamination often indicates substrate moisture. Identify and treat moisture source before replastering."), | |
| 5: CostEntry("βΉ12,000ββΉ25,000","mason", "this_week", | |
| disclaimer="Extensive plaster delamination over large wall area. Complete replastering required after identifying and treating root cause."), | |
| }, | |
| "no_defect": { | |
| 1: CostEntry("βΉ0 β No action needed", "none", "next_renovation"), | |
| 2: CostEntry("βΉ0 β No action needed", "none", "next_renovation"), | |
| 3: CostEntry("βΉ0 β No action needed", "none", "next_renovation"), | |
| 4: CostEntry("βΉ0 β No action needed", "none", "next_renovation"), | |
| 5: CostEntry("βΉ0 β No action needed", "none", "next_renovation"), | |
| }, | |
| } | |
| # ββ Professional display names βββββββββββββββββββββββββββββββββββββββββββββββββ | |
| PROFESSIONAL_DISPLAY = { | |
| "painter": "Local Painter / Decorator", | |
| "mason": "Licensed Mason (Raj Mistri)", | |
| "waterproofing_contractor": "Waterproofing Contractor", | |
| "civil_engineer": "Licensed Civil / Structural Engineer", | |
| "none": "No professional required", | |
| } | |
| TIMELINE_DISPLAY = { | |
| "next_renovation": "At your next renovation", | |
| "within_6_months": "Within 6 months", | |
| "within_1_month": "Within 1 month", | |
| "this_week": "This week", | |
| "immediately": "IMMEDIATELY", | |
| } | |
| def get_cost_entry(defect_type: str, severity: int) -> CostEntry: | |
| """ | |
| Primary lookup function. | |
| Returns CostEntry for a given defect_type Γ severity combination. | |
| Falls back to a safe default if defect type is not in matrix. | |
| """ | |
| if defect_type not in COST_MATRIX: | |
| return CostEntry( | |
| cost_range_inr="Assessment required", | |
| professional_type="civil_engineer", | |
| urgency_timeline="within_1_month", | |
| disclaimer="Unrecognized defect type. Please consult a professional for assessment.", | |
| requires_engineer=True, | |
| ) | |
| severity = max(1, min(5, int(severity))) # Clamp to valid range | |
| return COST_MATRIX[defect_type][severity] | |
| def build_cost_response(defect_type: str, severity: int) -> dict: | |
| """ | |
| Returns a fully-structured dict ready for the frontend renderer. | |
| Includes display-friendly strings + disclaimer flag. | |
| """ | |
| entry = get_cost_entry(defect_type, severity) | |
| return { | |
| "cost_range_inr": entry.cost_range_inr, | |
| "professional_type": entry.professional_type, | |
| "professional_display": PROFESSIONAL_DISPLAY.get(entry.professional_type, entry.professional_type), | |
| "urgency_timeline": entry.urgency_timeline, | |
| "urgency_display": TIMELINE_DISPLAY.get(entry.urgency_timeline, entry.urgency_timeline), | |
| "severity_label": SEVERITY_LABELS.get(severity, "Unknown"), | |
| "severity_color": SEVERITY_COLORS.get(severity, "#6b7280"), | |
| "requires_engineer": entry.requires_engineer, | |
| "disclaimer": entry.disclaimer, | |
| # Hard disclaimer for all Severity 4-5 (Watch-Out 2) | |
| "show_liability_banner": severity >= 4, | |
| "liability_text": ( | |
| "β οΈ These are estimated market rates only. " | |
| "For Severity 4β5 defects, always obtain a professional site assessment " | |
| "before starting any repair work. GharScan is a triage tool, not a substitute " | |
| "for a licensed engineer or contractor." | |
| ) if severity >= 4 else None, | |
| } | |