""" Curated knowledge base for the heat alert explanation RAG system. Contains real guidance from WHO, ILO, and East African occupational health authorities, adapted for extreme heat contexts in Nairobi, Dar es Salaam, Kampala, and Kigali. """ from __future__ import annotations from typing import Dict, List # -- WHO/ILO heat stress guidance for outdoor workers ---------------------- HEAT_SAFETY_GUIDANCE: list[str] = [ # Hydration "Drink water every 15-20 minutes even if you are not thirsty. " "Do not wait until you feel thirsty — by then you are already dehydrated.", "Carry at least 1 litre of clean water for every 2 hours of outdoor work. " "Avoid alcohol, strong tea, and sugary drinks which increase dehydration.", "Add a pinch of salt and sugar to drinking water to replace minerals " "lost through sweating (oral rehydration solution).", # Rest breaks "Take a 10-minute rest break in shade every 45 minutes when temperature " "exceeds 35C. In extreme heat above 37C, rest 15 minutes every 30 minutes.", "Schedule heavy physical work (carrying, digging, construction) for early " "morning (before 10am) or late afternoon (after 4pm). Avoid peak heat hours.", "If possible, rotate between outdoor and indoor tasks throughout the day " "to reduce cumulative heat exposure.", # Shade and clothing "Wear loose, light-colored clothing that covers the skin. A wide-brimmed " "hat or head covering protects against direct sun and reduces heat stroke risk.", "Work in shade whenever possible. If shade is not available, create " "temporary shade using tarps, umbrellas, or fabric canopies.", # Emergency signs (heat stroke) "DANGER SIGNS — seek medical help immediately if someone shows: confusion " "or strange behavior, inability to sweat despite heat, hot dry red skin, " "seizures, unconsciousness, or body temperature above 40C.", "If a co-worker collapses from heat: move them to shade immediately, pour " "cool water over their body, fan them, and call for emergency help. Do not " "give water to an unconscious person.", # Adjusted work hours "Employers should implement a heat action plan: shift start times earlier, " "provide free drinking water stations, and designate shaded rest areas.", "New workers and those returning after absence are at higher risk during " "the first 1-2 weeks. Gradually increase workload over 7-14 days " "(heat acclimatization).", ] # -- Zone-specific heat context ------------------------------------------- ZONE_HEAT_CONTEXT: Dict[str, str] = { # Nairobi "NBO-KIB": ( "Kibera's informal structures have corrugated tin roofs that absorb and " "re-radiate solar heat, creating indoor temperatures 10-15C above ambient. " "Most workers are outdoor traders, jua kali artisans, and transport workers. " "The zone's elevation (1720m) keeps ambient temperatures moderate, but the " "urban heat island effect is significant in the densely packed settlement." ), "NBO-EAS": ( "Eastleigh is a busy commercial district with thousands of street vendors " "and market porters working outdoors on concrete and asphalt surfaces. " "Heat radiating from buildings and pavement raises effective temperature. " "Nairobi's highland climate provides some relief, but midday temperatures " "during the dry season (Jan-Mar) can reach 28-30C." ), "NBO-MAT": ( "Mathare valley traps heat due to its low-lying topography and dense " "settlement. Air circulation is poor between tightly packed structures. " "Many residents work as construction laborers, scrap collectors, and " "informal transport operators — all with high outdoor exposure." ), "NBO-SBC": ( "South B/C is a formal residential area where most workers commute to " "indoor offices. Heat risk is lower but still affects outdoor guards, " "gardeners, and maintenance workers during peak afternoon hours." ), "NBO-WES": ( "Westlands commercial district has air-conditioned offices and shopping " "centers. Heat risk is minimal for most workers but affects outdoor " "security guards, construction crews, and delivery riders." ), "NBO-KAN": ( "Kangemi has a large population of jua kali (literally 'fierce sun') " "artisans — welders, carpenters, and mechanics who work outdoors with " "heat-generating equipment. Combined with ambient heat, occupational " "heat exposure can be significant." ), # Dar es Salaam "DAR-JAN": ( "Jangwani is Dar es Salaam's most heat-vulnerable zone. Located at sea " "level in an informal settlement with minimal shade and tin roofing, " "ground-level temperatures regularly exceed 40C during hot months. " "Humidity of 75-85% pushes WBGT into dangerous territory. Most workers " "are outdoor laborers, market vendors, and waste collectors." ), "DAR-MSA": ( "Msasani has a large fish market and coastal trading area where workers " "are exposed to direct sun reflected off the ocean surface. Coastal " "humidity compounds heat stress. Salt processing and fish drying are " "outdoor occupations with extended sun exposure." ), "DAR-KIN": ( "Kinondoni is more mixed with some tree cover, but humidity remains " "consistently high (75-85%). Street vendors and bodaboda riders face " "extended outdoor exposure. The concrete urban surface amplifies heat." ), "DAR-TEM": ( "Temeke is Dar es Salaam's industrial zone. Port workers, construction " "crews, and factory workers in poorly ventilated structures face extreme " "heat exposure. Heavy physical labor combined with high humidity creates " "the city's highest occupational heat stress." ), "DAR-KIG": ( "Kigamboni peninsula has fishing, salt panning, and coastal construction " "as primary outdoor occupations. Workers face combined heat from direct " "sun, sea surface reflection, and high humidity. Limited shade on the " "exposed peninsula." ), # Kampala "KLA-BWA": ( "Bwaise is built on former wetland, creating humid conditions even by " "Kampala standards. The low-lying settlement traps heat, and the high " "water table increases humidity. Market traders and small manufacturers " "work outdoors in congested conditions with poor air circulation." ), "KLA-NAT": ( "Natete market area has high concentrations of outdoor workers — porters, " "vendors, and boda-boda riders. Concrete market surfaces store and " "re-radiate heat. Lake Victoria moderates temperatures but also " "maintains high humidity." ), "KLA-NAK": ( "Nakivubo commercial corridor includes the main taxi park where drivers " "and conductors wait outdoors for extended periods. The concrete channel " "and surrounding paved areas create a heat sink." ), "KLA-LUB": ( "Lubaga is on higher ground with some hilltop breezes that provide relief. " "Heat risk is moderate, mainly affecting construction workers and " "outdoor service providers." ), "KLA-MAK": ( "Makindye is elevated and has better tree cover than lower-lying areas. " "Heat risk is lower, but outdoor security guards and gardeners in the " "residential area still face extended exposure." ), # Kigali "KGL-NYA": ( "Nyabugogo valley traps heat despite Kigali's highland elevation. The bus " "terminal and surrounding market create a hot, congested environment. " "Workers loading and unloading vehicles face combined heat stress from " "sun exposure and vehicle exhaust." ), "KGL-KIC": ( "Kicukiro is a growing residential area with moderate heat exposure. " "Construction workers on new building sites are the primary at-risk group. " "Kigali's elevation (1520m) keeps temperatures manageable most of the year." ), "KGL-GAS": ( "Gasabo is the administrative district on higher ground. Air-conditioned " "offices keep most workers comfortable. Outdoor workers (guards, cleaners, " "construction) face moderate heat during dry season peaks." ), "KGL-NYM": ( "Nyamirambo is a dense residential hillside neighborhood. Market traders " "and informal workers face heat stress during the dry season, particularly " "in the lower, more sheltered areas where air circulation is limited." ), } # -- Insurance product description ---------------------------------------- INSURANCE_PRODUCT_INFO: str = ( "This is a parametric heat insurance product for outdoor workers in East Africa. " "Unlike traditional insurance, payouts are triggered automatically when heat " "conditions exceed pre-defined thresholds — there is no need to file a claim.\n\n" "How it works:\n" "1. We continuously monitor temperature and humidity for your work zone.\n" "2. When heat conditions exceed the trigger threshold for the required number " "of consecutive days, a payout is initiated automatically.\n" "3. Payouts arrive via M-Pesa or mobile money within 48 hours of the trigger.\n\n" "Trigger levels:\n" "- WATCH: Temperature above 33C or WBGT above 28C for 1+ day. " "Payout: $5 per worker. Take precautions.\n" "- WARNING: Temperature above 35C or WBGT above 30C for 2+ consecutive days. " "Payout: $10 per worker. Reduce outdoor work.\n" "- CRITICAL: Temperature above 37C or WBGT above 32C for 3+ consecutive days. " "Payout: $15 per worker. Stop outdoor work during peak hours.\n\n" "Important: Parametric insurance pays based on the weather index, not on whether " "you personally experienced heat illness. This means you may receive a payout " "even if you felt fine (because conditions were dangerous), or you may not receive " "a payout even if you felt unwell (if the index did not reach the threshold). " "This gap is called 'basis risk' and we work continuously to minimize it." ) # -- Emergency contacts by city ------------------------------------------- EMERGENCY_CONTACTS: Dict[str, Dict[str, str]] = { "Nairobi": { "National Emergency": "999 or 112", "Kenya Red Cross": "1199", "Kenyatta National Hospital": "+254 20 272 6300", "Kenya Meteorological Department": "+254 20 386 7880", "Ambulance (St John)": "+254 20 221 0000", "Police Emergency": "999", }, "Dar es Salaam": { "Tanzania Emergency": "112 or 114", "Tanzania Red Cross": "+255 22 215 0330", "Muhimbili National Hospital": "+255 22 215 1599", "Tanzania Meteorological Authority": "+255 22 246 0706", "Ambulance": "114", }, "Kampala": { "Uganda Emergency": "999 or 112", "Uganda Red Cross": "+256 31 225 8701", "Mulago National Hospital": "+256 41 425 4106", "Uganda National Meteorological Authority": "+256 41 425 1798", "Ambulance": "911", }, "Kigali": { "Rwanda Emergency": "112", "Rwanda Red Cross": "+250 78 830 0086", "CHUK Hospital": "+250 78 830 1001", "Rwanda Meteorology Agency": "+250 78 218 5230", "Ambulance (SAMU)": "912", }, } # -- Swahili translations of key heat and insurance terms ---------------- SWAHILI_TERMS: Dict[str, str] = { "heat": "joto", "extreme heat": "joto kali", "heat stroke": "kiharusi cha joto", "heat stress": "msongo wa joto", "temperature": "joto la hewa", "humidity": "unyevunyevu", "warning": "onyo", "critical": "hali ya hatari", "watch": "tahadhari", "payout": "malipo", "insurance": "bima", "trigger": "kiwango cha hatari", "shade": "kivuli", "water": "maji", "rest break": "mapumziko", "dehydration": "upungufu wa maji mwilini", "outdoor worker": "mfanyakazi wa nje", "sun protection": "kinga ya jua", "emergency": "dharura", "ambulance": "gari la wagonjwa", "M-Pesa": "M-Pesa", "Red Cross": "Msalaba Mwekundu", } # -- Protective actions by trigger level ---------------------------------- PROTECTIVE_ACTIONS: Dict[str, list[str]] = { "critical": [ "STOP all outdoor work during peak heat hours (10am-4pm).", "Move to shade or indoors immediately. Do not continue working in direct sun.", "Drink water constantly — at least 250ml every 15 minutes.", "Watch for danger signs: confusion, no sweating, hot dry skin, dizziness.", "If someone collapses: move to shade, pour water on them, fan, call ambulance.", "Your payout of $15 will arrive via mobile money within 48 hours.", "Do not return to outdoor work until the heat alert is downgraded.", ], "warning": [ "Reduce outdoor work to early morning (before 10am) and late afternoon (after 4pm).", "Take 15-minute shade breaks every hour during outdoor work.", "Drink at least 1 cup of water every 20 minutes.", "Wear loose, light-colored clothing and a hat.", "Your payout of $10 will arrive via mobile money within 48 hours.", "Watch for heat illness signs in yourself and co-workers.", "Set up shade structures if working outdoors is unavoidable.", ], "watch": [ "Stay alert — heat conditions are developing.", "Increase water intake beyond normal levels.", "Plan your heavy work for cooler hours of the day.", "Ensure shade and water are available at your work site.", "Your payout of $5 will arrive via mobile money within 48 hours.", ], } # -- Retrieval function --------------------------------------------------- def get_zone_context(zone_id: str) -> str: """Assemble full knowledge base context for a zone. Returns a single text block suitable for injection into a Claude prompt. """ parts: list[str] = [] # Zone heat context context = ZONE_HEAT_CONTEXT.get(zone_id, "No heat vulnerability data available for this zone.") parts.append(f"ZONE HEAT VULNERABILITY:\n{context}") # Product info parts.append(f"INSURANCE PRODUCT:\n{INSURANCE_PRODUCT_INFO}") # Heat safety (first 8 most relevant) safety_text = "\n".join(f"- {s}" for s in HEAT_SAFETY_GUIDANCE[:8]) parts.append(f"HEAT SAFETY GUIDANCE (WHO/ILO):\n{safety_text}") return "\n\n---\n\n".join(parts) def get_emergency_contacts(city: str) -> Dict[str, str]: """Get emergency contacts for a city.""" return EMERGENCY_CONTACTS.get(city, EMERGENCY_CONTACTS.get("Nairobi", {})) def get_protective_actions(trigger_level: str) -> list[str]: """Get recommended protective actions for a trigger level.""" return PROTECTIVE_ACTIONS.get(trigger_level, PROTECTIVE_ACTIONS["watch"])