Spaces:
Runtime error
Runtime error
Commit ·
7a26ec6
1
Parent(s): f041270
Site RA
Browse files
README.md
CHANGED
|
@@ -1040,3 +1040,226 @@ For support and questions:
|
|
| 1040 |
---
|
| 1041 |
|
| 1042 |
**Built with ❤️ for enterprise risk management and business continuity**
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1040 |
---
|
| 1041 |
|
| 1042 |
**Built with ❤️ for enterprise risk management and business continuity**
|
| 1043 |
+
|
| 1044 |
+
---
|
| 1045 |
+
|
| 1046 |
+
## Site Risk Assessment Endpoint
|
| 1047 |
+
|
| 1048 |
+
### Overview
|
| 1049 |
+
The Site Risk Assessment endpoint provides comprehensive risk analysis for physical locations based on detailed site characteristics, building information, and compliance status. This endpoint is specifically designed for facilities management and safety assessment.
|
| 1050 |
+
|
| 1051 |
+
### Endpoint Details
|
| 1052 |
+
- **Method**: `POST`
|
| 1053 |
+
- **URL**: `/api/site-risk-assessment`
|
| 1054 |
+
- **Purpose**: Generate detailed site-specific risk assessments based on physical location characteristics
|
| 1055 |
+
|
| 1056 |
+
### Use Cases
|
| 1057 |
+
- **Facilities Risk Management**: Comprehensive assessment of physical site risks
|
| 1058 |
+
- **Fire Safety Compliance**: Detailed fire risk analysis for commercial buildings
|
| 1059 |
+
- **Insurance Risk Assessment**: Site-specific risk evaluation for insurance purposes
|
| 1060 |
+
- **Regulatory Compliance**: Assessment against building codes and safety standards
|
| 1061 |
+
- **Emergency Planning**: Risk analysis for emergency response planning
|
| 1062 |
+
- **Property Management**: Ongoing risk monitoring for managed properties
|
| 1063 |
+
|
| 1064 |
+
### Request Body
|
| 1065 |
+
```json
|
| 1066 |
+
{
|
| 1067 |
+
"riskCategory": "Fire Safety",
|
| 1068 |
+
"controlQuestion": "Are fire extinguishers available and regularly inspected?",
|
| 1069 |
+
"complianceStatus": "Yes, fire extinguishers are available on each floor and inspected monthly.",
|
| 1070 |
+
"address_of_location": "123 Corporate Park, Mumbai",
|
| 1071 |
+
"nature_of_occupancy": "Office space with attached cafeteria",
|
| 1072 |
+
"building_construction_details": "RCC framed structure with glass facade",
|
| 1073 |
+
"nature_of_other_occupancies": "Shared with retail stores on ground floor, clear separation exists",
|
| 1074 |
+
"total_floors_and_communication": "10 floors with 2 staircases and 3 elevators",
|
| 1075 |
+
"total_floor_area": "25,000 sq. ft.",
|
| 1076 |
+
"maximum_undivided_area": "3,000 sq. ft.",
|
| 1077 |
+
"floors_occupied": "3",
|
| 1078 |
+
"building_age": "12 years",
|
| 1079 |
+
"stability_certificate": "Yes",
|
| 1080 |
+
"fire_noc_availability": "Yes, renewed annually",
|
| 1081 |
+
"people_working_floor_wise": "Ground: 10, 1st: 50, 2nd: 45",
|
| 1082 |
+
"max_visitors_peak_day": "Around 80",
|
| 1083 |
+
"business_hours": "Mon–Fri, 9:00 AM to 6:00 PM",
|
| 1084 |
+
"power_backup_details": "100 kVA DG installed with 8-hour backup",
|
| 1085 |
+
"store_room_stacking": "Properly labeled, no obstruction to exits",
|
| 1086 |
+
"floor_covering_nature": "Antistatic carpet in work areas",
|
| 1087 |
+
"false_ceiling_details": "Gypsum tiles with concealed lighting",
|
| 1088 |
+
"hvac_system_details": "Centralized HVAC with AHUs on each floor",
|
| 1089 |
+
"area_passage_around_building": "2-meter fire vehicle access on all sides"
|
| 1090 |
+
}
|
| 1091 |
+
```
|
| 1092 |
+
|
| 1093 |
+
### Response Format
|
| 1094 |
+
```json
|
| 1095 |
+
{
|
| 1096 |
+
"risk_id": "RISK-001",
|
| 1097 |
+
"category": "Fire Safety",
|
| 1098 |
+
"business_unit": "Facilities",
|
| 1099 |
+
"risk_owner": "Fire Safety Officer",
|
| 1100 |
+
"timeline": "Immediate",
|
| 1101 |
+
"risk_name": "Inadequate fire suppression coverage for office complex",
|
| 1102 |
+
"question": "Are fire extinguishers available and regularly inspected?",
|
| 1103 |
+
"compliance_status": "Yes, fire extinguishers are available on each floor and inspected monthly.",
|
| 1104 |
+
"identified_threat": "Fire spread risk due to limited suppression systems in high-occupancy areas",
|
| 1105 |
+
"likelihood": 6,
|
| 1106 |
+
"impact": 8,
|
| 1107 |
+
"risk_value": 48,
|
| 1108 |
+
"residual_risk": "High",
|
| 1109 |
+
"current_control_description": "Manual fire extinguishers with monthly inspections, no automated suppression",
|
| 1110 |
+
"current_control_rating": "Fair",
|
| 1111 |
+
"mitigation_plan": "Install automated fire suppression systems in high-risk areas, upgrade emergency evacuation systems, and enhance fire detection coverage",
|
| 1112 |
+
"site_details": {
|
| 1113 |
+
"site_name": "Corporate Office Complex - Mumbai",
|
| 1114 |
+
"address": "123 Corporate Park, Mumbai",
|
| 1115 |
+
"building_type": "Commercial Office",
|
| 1116 |
+
"floor_area_sq_ft": 25000,
|
| 1117 |
+
"occupancy_type": "Office space with attached cafeteria",
|
| 1118 |
+
"year_of_construction": 2012,
|
| 1119 |
+
"no_of_floors": 10
|
| 1120 |
+
},
|
| 1121 |
+
"risk_classification_summary": "High-priority fire safety risk due to building age, occupancy density, and limited automated suppression systems. Requires immediate attention per NFPA guidelines.",
|
| 1122 |
+
"mitigation_suggestions": [
|
| 1123 |
+
"Install automatic sprinkler systems per NFPA 13 standards",
|
| 1124 |
+
"Upgrade fire alarm systems with voice evacuation capabilities",
|
| 1125 |
+
"Implement quarterly fire drills and emergency response training",
|
| 1126 |
+
"Establish fire safety committee and regular risk assessments"
|
| 1127 |
+
],
|
| 1128 |
+
"risk_trends": {
|
| 1129 |
+
"top_category": "Fire Safety",
|
| 1130 |
+
"risk_severity": "High",
|
| 1131 |
+
"observations": [
|
| 1132 |
+
"Buildings over 10 years require enhanced fire safety measures",
|
| 1133 |
+
"High-density office occupancy increases evacuation complexity",
|
| 1134 |
+
"Mixed-use buildings require comprehensive fire separation strategies"
|
| 1135 |
+
]
|
| 1136 |
+
}
|
| 1137 |
+
}
|
| 1138 |
+
```
|
| 1139 |
+
|
| 1140 |
+
### Key Features
|
| 1141 |
+
|
| 1142 |
+
#### **Comprehensive Site Analysis**
|
| 1143 |
+
- **Building Characteristics**: Construction type, age, and structural details
|
| 1144 |
+
- **Occupancy Patterns**: Personnel distribution, visitor capacity, and usage patterns
|
| 1145 |
+
- **Safety Systems**: Fire protection, HVAC, electrical, and emergency systems
|
| 1146 |
+
- **Compliance Status**: Regulatory certifications and inspection records
|
| 1147 |
+
|
| 1148 |
+
#### **Evidence-Based Assessment**
|
| 1149 |
+
- **Building Code References**: NFPA standards, International Building Code (IBC)
|
| 1150 |
+
- **Occupancy Load Analysis**: Egress capacity and evacuation requirements
|
| 1151 |
+
- **Historical Risk Data**: Industry-specific incident patterns and trends
|
| 1152 |
+
- **Regulatory Compliance**: Local fire codes and safety regulations
|
| 1153 |
+
|
| 1154 |
+
#### **Actionable Recommendations**
|
| 1155 |
+
- **Specific Mitigation Plans**: Targeted improvements based on site characteristics
|
| 1156 |
+
- **Timeline Prioritization**: Risk-based scheduling for remediation activities
|
| 1157 |
+
- **Cost-Effectiveness**: Practical solutions considering budget constraints
|
| 1158 |
+
- **Compliance Alignment**: Recommendations aligned with regulatory requirements
|
| 1159 |
+
|
| 1160 |
+
### Integration Examples
|
| 1161 |
+
|
| 1162 |
+
#### **cURL Example**
|
| 1163 |
+
```bash
|
| 1164 |
+
curl -X POST "http://localhost:8000/api/site-risk-assessment" \
|
| 1165 |
+
-H "Content-Type: application/json" \
|
| 1166 |
+
-d '{
|
| 1167 |
+
"riskCategory": "Fire Safety",
|
| 1168 |
+
"controlQuestion": "Are fire extinguishers available and regularly inspected?",
|
| 1169 |
+
"complianceStatus": "Yes, fire extinguishers are available on each floor and inspected monthly.",
|
| 1170 |
+
"address_of_location": "123 Corporate Park, Mumbai",
|
| 1171 |
+
"nature_of_occupancy": "Office space with attached cafeteria",
|
| 1172 |
+
"building_construction_details": "RCC framed structure with glass facade",
|
| 1173 |
+
"nature_of_other_occupancies": "Shared with retail stores on ground floor, clear separation exists",
|
| 1174 |
+
"total_floors_and_communication": "10 floors with 2 staircases and 3 elevators",
|
| 1175 |
+
"total_floor_area": "25,000 sq. ft.",
|
| 1176 |
+
"maximum_undivided_area": "3,000 sq. ft.",
|
| 1177 |
+
"floors_occupied": "3",
|
| 1178 |
+
"building_age": "12 years",
|
| 1179 |
+
"stability_certificate": "Yes",
|
| 1180 |
+
"fire_noc_availability": "Yes, renewed annually",
|
| 1181 |
+
"people_working_floor_wise": "Ground: 10, 1st: 50, 2nd: 45",
|
| 1182 |
+
"max_visitors_peak_day": "Around 80",
|
| 1183 |
+
"business_hours": "Mon–Fri, 9:00 AM to 6:00 PM",
|
| 1184 |
+
"power_backup_details": "100 kVA DG installed with 8-hour backup",
|
| 1185 |
+
"store_room_stacking": "Properly labeled, no obstruction to exits",
|
| 1186 |
+
"floor_covering_nature": "Antistatic carpet in work areas",
|
| 1187 |
+
"false_ceiling_details": "Gypsum tiles with concealed lighting",
|
| 1188 |
+
"hvac_system_details": "Centralized HVAC with AHUs on each floor",
|
| 1189 |
+
"area_passage_around_building": "2-meter fire vehicle access on all sides"
|
| 1190 |
+
}'
|
| 1191 |
+
```
|
| 1192 |
+
|
| 1193 |
+
#### **Python Integration**
|
| 1194 |
+
```python
|
| 1195 |
+
import requests
|
| 1196 |
+
|
| 1197 |
+
# Site risk assessment request
|
| 1198 |
+
site_data = {
|
| 1199 |
+
"riskCategory": "Fire Safety",
|
| 1200 |
+
"controlQuestion": "Are fire extinguishers available and regularly inspected?",
|
| 1201 |
+
"complianceStatus": "Yes, fire extinguishers are available on each floor and inspected monthly.",
|
| 1202 |
+
"address_of_location": "123 Corporate Park, Mumbai",
|
| 1203 |
+
"nature_of_occupancy": "Office space with attached cafeteria",
|
| 1204 |
+
# ... other site details
|
| 1205 |
+
}
|
| 1206 |
+
|
| 1207 |
+
response = requests.post(
|
| 1208 |
+
"http://localhost:8000/api/site-risk-assessment",
|
| 1209 |
+
json=site_data
|
| 1210 |
+
)
|
| 1211 |
+
|
| 1212 |
+
if response.status_code == 200:
|
| 1213 |
+
assessment = response.json()
|
| 1214 |
+
print(f"Risk Level: {assessment['residual_risk']}")
|
| 1215 |
+
print(f"Risk Score: {assessment['risk_value']}")
|
| 1216 |
+
print(f"Mitigation Plan: {assessment['mitigation_plan']}")
|
| 1217 |
+
else:
|
| 1218 |
+
print(f"Error: {response.text}")
|
| 1219 |
+
```
|
| 1220 |
+
|
| 1221 |
+
#### **JavaScript Integration**
|
| 1222 |
+
```javascript
|
| 1223 |
+
const siteAssessment = async (siteData) => {
|
| 1224 |
+
try {
|
| 1225 |
+
const response = await fetch('/api/site-risk-assessment', {
|
| 1226 |
+
method: 'POST',
|
| 1227 |
+
headers: {
|
| 1228 |
+
'Content-Type': 'application/json',
|
| 1229 |
+
},
|
| 1230 |
+
body: JSON.stringify(siteData)
|
| 1231 |
+
});
|
| 1232 |
+
|
| 1233 |
+
if (response.ok) {
|
| 1234 |
+
const assessment = await response.json();
|
| 1235 |
+
return {
|
| 1236 |
+
riskId: assessment.risk_id,
|
| 1237 |
+
riskLevel: assessment.residual_risk,
|
| 1238 |
+
mitigationPlan: assessment.mitigation_plan,
|
| 1239 |
+
siteDetails: assessment.site_details
|
| 1240 |
+
};
|
| 1241 |
+
} else {
|
| 1242 |
+
throw new Error('Assessment failed');
|
| 1243 |
+
}
|
| 1244 |
+
} catch (error) {
|
| 1245 |
+
console.error('Site assessment error:', error);
|
| 1246 |
+
return null;
|
| 1247 |
+
}
|
| 1248 |
+
};
|
| 1249 |
+
```
|
| 1250 |
+
|
| 1251 |
+
### Error Handling
|
| 1252 |
+
|
| 1253 |
+
The endpoint provides comprehensive error handling with specific error codes:
|
| 1254 |
+
|
| 1255 |
+
- **400 Bad Request**: Invalid input data or missing required fields
|
| 1256 |
+
- **422 Validation Error**: Data validation failures
|
| 1257 |
+
- **500 Internal Server Error**: AI processing errors with fallback responses
|
| 1258 |
+
|
| 1259 |
+
### Fallback Mechanism
|
| 1260 |
+
|
| 1261 |
+
If AI processing fails, the endpoint provides intelligent fallback responses based on:
|
| 1262 |
+
- **Building Age Analysis**: Risk assessment based on construction year
|
| 1263 |
+
- **Occupancy Density**: Risk factors related to personnel count
|
| 1264 |
+
- **Floor Area Considerations**: Space-based risk calculations
|
| 1265 |
+
- **Compliance Status**: Assessment based on current safety measures
|
app.py
CHANGED
|
@@ -1,10 +1,12 @@
|
|
| 1 |
# app.py
|
| 2 |
-
from fastapi import FastAPI
|
| 3 |
from pydantic import BaseModel
|
| 4 |
from typing import List, Optional
|
| 5 |
import os
|
| 6 |
import openai
|
| 7 |
import json
|
|
|
|
|
|
|
| 8 |
|
| 9 |
# Import the new routers
|
| 10 |
from enterprise_ra import enterprise_ra_router
|
|
@@ -264,6 +266,68 @@ class RiskAnalysis(BaseModel):
|
|
| 264 |
class RiskMitigationResponse(BaseModel):
|
| 265 |
risk_analysis: RiskAnalysis
|
| 266 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 267 |
@app.post("/api/risk-mitigation", response_model=RiskMitigationResponse)
|
| 268 |
def generate_risk_mitigation(request: RiskRequestModel):
|
| 269 |
"""
|
|
@@ -569,3 +633,250 @@ Provide a comprehensive risk analysis with mitigation plan based on this respons
|
|
| 569 |
)
|
| 570 |
|
| 571 |
return RiskMitigationResponse(risk_analysis=risk_analysis)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
# app.py
|
| 2 |
+
from fastapi import FastAPI, HTTPException
|
| 3 |
from pydantic import BaseModel
|
| 4 |
from typing import List, Optional
|
| 5 |
import os
|
| 6 |
import openai
|
| 7 |
import json
|
| 8 |
+
import uuid
|
| 9 |
+
import re
|
| 10 |
|
| 11 |
# Import the new routers
|
| 12 |
from enterprise_ra import enterprise_ra_router
|
|
|
|
| 266 |
class RiskMitigationResponse(BaseModel):
|
| 267 |
risk_analysis: RiskAnalysis
|
| 268 |
|
| 269 |
+
# Site Risk Assessment Models
|
| 270 |
+
class SiteDetails(BaseModel):
|
| 271 |
+
site_name: Optional[str] = ""
|
| 272 |
+
address: str
|
| 273 |
+
building_type: Optional[str] = ""
|
| 274 |
+
floor_area_sq_ft: Optional[int] = 0
|
| 275 |
+
occupancy_type: str
|
| 276 |
+
year_of_construction: Optional[int] = 0
|
| 277 |
+
no_of_floors: Optional[int] = 0
|
| 278 |
+
|
| 279 |
+
class SiteRiskAssessmentRequest(BaseModel):
|
| 280 |
+
riskCategory: str
|
| 281 |
+
controlQuestion: str
|
| 282 |
+
complianceStatus: str
|
| 283 |
+
address_of_location: str
|
| 284 |
+
nature_of_occupancy: str
|
| 285 |
+
building_construction_details: str
|
| 286 |
+
nature_of_other_occupancies: str
|
| 287 |
+
total_floors_and_communication: str
|
| 288 |
+
total_floor_area: str
|
| 289 |
+
maximum_undivided_area: str
|
| 290 |
+
floors_occupied: str
|
| 291 |
+
building_age: str
|
| 292 |
+
stability_certificate: str
|
| 293 |
+
fire_noc_availability: str
|
| 294 |
+
people_working_floor_wise: str
|
| 295 |
+
max_visitors_peak_day: str
|
| 296 |
+
business_hours: str
|
| 297 |
+
power_backup_details: str
|
| 298 |
+
store_room_stacking: str
|
| 299 |
+
floor_covering_nature: str
|
| 300 |
+
false_ceiling_details: str
|
| 301 |
+
hvac_system_details: str
|
| 302 |
+
area_passage_around_building: str
|
| 303 |
+
|
| 304 |
+
class SiteRiskTrends(BaseModel):
|
| 305 |
+
top_category: str
|
| 306 |
+
risk_severity: str
|
| 307 |
+
observations: List[str]
|
| 308 |
+
|
| 309 |
+
class SiteRiskAssessmentResponse(BaseModel):
|
| 310 |
+
risk_id: str
|
| 311 |
+
category: str
|
| 312 |
+
business_unit: str
|
| 313 |
+
risk_owner: str
|
| 314 |
+
timeline: str
|
| 315 |
+
risk_name: str
|
| 316 |
+
question: str
|
| 317 |
+
compliance_status: str
|
| 318 |
+
identified_threat: str
|
| 319 |
+
likelihood: int
|
| 320 |
+
impact: int
|
| 321 |
+
risk_value: int
|
| 322 |
+
residual_risk: str
|
| 323 |
+
current_control_description: str
|
| 324 |
+
current_control_rating: str
|
| 325 |
+
mitigation_plan: str
|
| 326 |
+
site_details: SiteDetails
|
| 327 |
+
risk_classification_summary: str
|
| 328 |
+
mitigation_suggestions: List[str]
|
| 329 |
+
risk_trends: SiteRiskTrends
|
| 330 |
+
|
| 331 |
@app.post("/api/risk-mitigation", response_model=RiskMitigationResponse)
|
| 332 |
def generate_risk_mitigation(request: RiskRequestModel):
|
| 333 |
"""
|
|
|
|
| 633 |
)
|
| 634 |
|
| 635 |
return RiskMitigationResponse(risk_analysis=risk_analysis)
|
| 636 |
+
|
| 637 |
+
@app.post("/api/site-risk-assessment", response_model=SiteRiskAssessmentResponse)
|
| 638 |
+
def generate_site_risk_assessment(request: SiteRiskAssessmentRequest):
|
| 639 |
+
"""
|
| 640 |
+
Generate comprehensive site-specific risk assessment based on physical location details
|
| 641 |
+
"""
|
| 642 |
+
|
| 643 |
+
system_prompt = """You are a comprehensive risk assessment expert specializing in site-specific risk analysis. Your task is to analyze physical site details and generate detailed risk assessments based on the provided information.
|
| 644 |
+
|
| 645 |
+
CRITICAL: You must respond with ONLY a valid JSON object. Do not include any markdown formatting, code blocks, or additional text.
|
| 646 |
+
|
| 647 |
+
For the site risk assessment, consider:
|
| 648 |
+
- Physical building characteristics and construction details
|
| 649 |
+
- Occupancy patterns and usage
|
| 650 |
+
- Fire safety systems and compliance status
|
| 651 |
+
- Emergency egress and accessibility
|
| 652 |
+
- HVAC and electrical systems
|
| 653 |
+
- Regulatory compliance (fire NOC, stability certificates)
|
| 654 |
+
- Site-specific vulnerabilities and threats
|
| 655 |
+
- Industry standards (NFPA, building codes, occupational safety)
|
| 656 |
+
|
| 657 |
+
Provide evidence-based assessments that reference:
|
| 658 |
+
- Building codes and fire safety standards (NFPA 101, IBC)
|
| 659 |
+
- Occupancy load calculations and egress requirements
|
| 660 |
+
- Construction type fire ratings and vulnerability factors
|
| 661 |
+
- Historical incident data for similar occupancies
|
| 662 |
+
- Industry best practices for risk mitigation
|
| 663 |
+
- Regulatory compliance requirements
|
| 664 |
+
|
| 665 |
+
RESPOND WITH ONLY THIS EXACT JSON FORMAT:
|
| 666 |
+
{
|
| 667 |
+
"risk_id": "Unique risk identifier starting with RISK-",
|
| 668 |
+
"category": "Risk category from input",
|
| 669 |
+
"business_unit": "Relevant business unit",
|
| 670 |
+
"risk_owner": "Appropriate risk owner role",
|
| 671 |
+
"timeline": "Risk mitigation timeline",
|
| 672 |
+
"risk_name": "Specific risk name based on site analysis",
|
| 673 |
+
"question": "Control question from input",
|
| 674 |
+
"compliance_status": "Compliance status from input",
|
| 675 |
+
"identified_threat": "Specific threat based on site characteristics",
|
| 676 |
+
"likelihood": "Numeric likelihood score 1-10",
|
| 677 |
+
"impact": "Numeric impact score 1-10",
|
| 678 |
+
"risk_value": "Calculated risk value",
|
| 679 |
+
"residual_risk": "Risk level (Low/Medium/High/Critical)",
|
| 680 |
+
"current_control_description": "Description of current controls",
|
| 681 |
+
"current_control_rating": "Rating of current controls",
|
| 682 |
+
"mitigation_plan": "Specific mitigation recommendations",
|
| 683 |
+
"site_details": {
|
| 684 |
+
"site_name": "Derived site name",
|
| 685 |
+
"address": "Address from input",
|
| 686 |
+
"building_type": "Building type derived from occupancy",
|
| 687 |
+
"floor_area_sq_ft": "Numeric floor area",
|
| 688 |
+
"occupancy_type": "Occupancy type from input",
|
| 689 |
+
"year_of_construction": "Calculated year",
|
| 690 |
+
"no_of_floors": "Number of floors from input"
|
| 691 |
+
},
|
| 692 |
+
"risk_classification_summary": "Summary of risk classification and reasoning",
|
| 693 |
+
"mitigation_suggestions": ["List of specific mitigation suggestions"],
|
| 694 |
+
"risk_trends": {
|
| 695 |
+
"top_category": "Risk category",
|
| 696 |
+
"risk_severity": "Severity level",
|
| 697 |
+
"observations": ["List of trend observations"]
|
| 698 |
+
}
|
| 699 |
+
}"""
|
| 700 |
+
|
| 701 |
+
# Convert request to structured input
|
| 702 |
+
input_data = {
|
| 703 |
+
"risk_category": request.riskCategory,
|
| 704 |
+
"control_question": request.controlQuestion,
|
| 705 |
+
"compliance_status": request.complianceStatus,
|
| 706 |
+
"site_information": {
|
| 707 |
+
"address": request.address_of_location,
|
| 708 |
+
"occupancy_nature": request.nature_of_occupancy,
|
| 709 |
+
"building_construction": request.building_construction_details,
|
| 710 |
+
"neighboring_occupancies": request.nature_of_other_occupancies,
|
| 711 |
+
"floors_and_communication": request.total_floors_and_communication,
|
| 712 |
+
"total_floor_area": request.total_floor_area,
|
| 713 |
+
"max_undivided_area": request.maximum_undivided_area,
|
| 714 |
+
"floors_occupied": request.floors_occupied,
|
| 715 |
+
"building_age": request.building_age,
|
| 716 |
+
"stability_certificate": request.stability_certificate,
|
| 717 |
+
"fire_noc": request.fire_noc_availability,
|
| 718 |
+
"occupancy_details": request.people_working_floor_wise,
|
| 719 |
+
"visitor_capacity": request.max_visitors_peak_day,
|
| 720 |
+
"operating_hours": request.business_hours,
|
| 721 |
+
"power_systems": request.power_backup_details,
|
| 722 |
+
"storage_conditions": request.store_room_stacking,
|
| 723 |
+
"flooring": request.floor_covering_nature,
|
| 724 |
+
"ceiling_details": request.false_ceiling_details,
|
| 725 |
+
"hvac_system": request.hvac_system_details,
|
| 726 |
+
"building_access": request.area_passage_around_building
|
| 727 |
+
}
|
| 728 |
+
}
|
| 729 |
+
|
| 730 |
+
user_message = f"""Analyze the following site information and generate a comprehensive risk assessment:
|
| 731 |
+
|
| 732 |
+
{json.dumps(input_data, indent=2)}
|
| 733 |
+
|
| 734 |
+
Provide a detailed site-specific risk assessment considering all physical characteristics, occupancy patterns, compliance status, and potential vulnerabilities. Include specific recommendations based on the building details and current control status."""
|
| 735 |
+
|
| 736 |
+
try:
|
| 737 |
+
result = generate_response(system_prompt, user_message)
|
| 738 |
+
|
| 739 |
+
# Clean the response - remove markdown code blocks if present
|
| 740 |
+
cleaned_result = result.strip()
|
| 741 |
+
if cleaned_result.startswith('```json'):
|
| 742 |
+
cleaned_result = cleaned_result[7:]
|
| 743 |
+
elif cleaned_result.startswith('```'):
|
| 744 |
+
cleaned_result = cleaned_result[3:]
|
| 745 |
+
if cleaned_result.endswith('```'):
|
| 746 |
+
cleaned_result = cleaned_result[:-3]
|
| 747 |
+
cleaned_result = cleaned_result.strip()
|
| 748 |
+
|
| 749 |
+
# Extract JSON from the response
|
| 750 |
+
json_start = cleaned_result.find('{')
|
| 751 |
+
json_end = cleaned_result.rfind('}') + 1
|
| 752 |
+
|
| 753 |
+
if json_start != -1 and json_end > json_start:
|
| 754 |
+
json_str = cleaned_result[json_start:json_end]
|
| 755 |
+
# Clean up any problematic characters
|
| 756 |
+
json_str = re.sub(r'\r\s*', ' ', json_str)
|
| 757 |
+
json_str = re.sub(r'\t+', ' ', json_str)
|
| 758 |
+
json_str = re.sub(r'\s+', ' ', json_str)
|
| 759 |
+
assessment_data = json.loads(json_str)
|
| 760 |
+
|
| 761 |
+
# Extract site details
|
| 762 |
+
site_info = assessment_data.get("site_details", {})
|
| 763 |
+
site_details = SiteDetails(
|
| 764 |
+
site_name=site_info.get("site_name", ""),
|
| 765 |
+
address=site_info.get("address", request.address_of_location),
|
| 766 |
+
building_type=site_info.get("building_type", ""),
|
| 767 |
+
floor_area_sq_ft=site_info.get("floor_area_sq_ft", 0),
|
| 768 |
+
occupancy_type=site_info.get("occupancy_type", request.nature_of_occupancy),
|
| 769 |
+
year_of_construction=site_info.get("year_of_construction", 0),
|
| 770 |
+
no_of_floors=site_info.get("no_of_floors", 0)
|
| 771 |
+
)
|
| 772 |
+
|
| 773 |
+
# Extract risk trends
|
| 774 |
+
trends_info = assessment_data.get("risk_trends", {})
|
| 775 |
+
risk_trends = SiteRiskTrends(
|
| 776 |
+
top_category=trends_info.get("top_category", request.riskCategory),
|
| 777 |
+
risk_severity=trends_info.get("risk_severity", "Medium"),
|
| 778 |
+
observations=trends_info.get("observations", [])
|
| 779 |
+
)
|
| 780 |
+
|
| 781 |
+
return SiteRiskAssessmentResponse(
|
| 782 |
+
risk_id=assessment_data.get("risk_id", f"RISK-{str(uuid.uuid4())[:8].upper()}"),
|
| 783 |
+
category=assessment_data.get("category", request.riskCategory),
|
| 784 |
+
business_unit=assessment_data.get("business_unit", "Facilities"),
|
| 785 |
+
risk_owner=assessment_data.get("risk_owner", "Risk Manager"),
|
| 786 |
+
timeline=assessment_data.get("timeline", "Short-term"),
|
| 787 |
+
risk_name=assessment_data.get("risk_name", f"Site-specific {request.riskCategory} risk"),
|
| 788 |
+
question=assessment_data.get("question", request.controlQuestion),
|
| 789 |
+
compliance_status=assessment_data.get("compliance_status", request.complianceStatus),
|
| 790 |
+
identified_threat=assessment_data.get("identified_threat", f"Site-specific {request.riskCategory} vulnerability"),
|
| 791 |
+
likelihood=assessment_data.get("likelihood", 5),
|
| 792 |
+
impact=assessment_data.get("impact", 5),
|
| 793 |
+
risk_value=assessment_data.get("risk_value", 25),
|
| 794 |
+
residual_risk=assessment_data.get("residual_risk", "Medium"),
|
| 795 |
+
current_control_description=assessment_data.get("current_control_description", "Standard site controls in place"),
|
| 796 |
+
current_control_rating=assessment_data.get("current_control_rating", "Fair"),
|
| 797 |
+
mitigation_plan=assessment_data.get("mitigation_plan", "Implement enhanced site-specific controls"),
|
| 798 |
+
site_details=site_details,
|
| 799 |
+
risk_classification_summary=assessment_data.get("risk_classification_summary", "Site risk requiring attention"),
|
| 800 |
+
mitigation_suggestions=assessment_data.get("mitigation_suggestions", []),
|
| 801 |
+
risk_trends=risk_trends
|
| 802 |
+
)
|
| 803 |
+
else:
|
| 804 |
+
raise ValueError("No valid JSON found in response")
|
| 805 |
+
|
| 806 |
+
except (json.JSONDecodeError, ValueError) as e:
|
| 807 |
+
# Fallback response based on input data
|
| 808 |
+
building_age_num = 0
|
| 809 |
+
try:
|
| 810 |
+
# Extract numeric age from building age string
|
| 811 |
+
age_match = re.search(r'\d+', request.building_age)
|
| 812 |
+
if age_match:
|
| 813 |
+
building_age_num = int(age_match.group())
|
| 814 |
+
except:
|
| 815 |
+
building_age_num = 10
|
| 816 |
+
|
| 817 |
+
# Extract floor area
|
| 818 |
+
floor_area_num = 0
|
| 819 |
+
try:
|
| 820 |
+
area_match = re.search(r'[\d,]+', request.total_floor_area.replace(',', ''))
|
| 821 |
+
if area_match:
|
| 822 |
+
floor_area_num = int(area_match.group().replace(',', ''))
|
| 823 |
+
except:
|
| 824 |
+
floor_area_num = 25000
|
| 825 |
+
|
| 826 |
+
# Extract number of floors
|
| 827 |
+
floors_num = 0
|
| 828 |
+
try:
|
| 829 |
+
floors_match = re.search(r'\d+', request.total_floors_and_communication)
|
| 830 |
+
if floors_match:
|
| 831 |
+
floors_num = int(floors_match.group())
|
| 832 |
+
except:
|
| 833 |
+
floors_num = 3
|
| 834 |
+
|
| 835 |
+
fallback_response = SiteRiskAssessmentResponse(
|
| 836 |
+
risk_id=f"RISK-{str(uuid.uuid4())[:8].upper()}",
|
| 837 |
+
category=request.riskCategory,
|
| 838 |
+
business_unit="Facilities Management",
|
| 839 |
+
risk_owner="Fire Safety Officer" if "fire" in request.riskCategory.lower() else "Risk Manager",
|
| 840 |
+
timeline="Immediate" if "critical" in request.complianceStatus.lower() else "Short-term",
|
| 841 |
+
risk_name=f"Site-specific {request.riskCategory} control deficiency",
|
| 842 |
+
question=request.controlQuestion,
|
| 843 |
+
compliance_status=request.complianceStatus,
|
| 844 |
+
identified_threat=f"Inadequate {request.riskCategory.lower()} controls may lead to property damage, personnel injury, and operational disruption",
|
| 845 |
+
likelihood=7 if building_age_num > 15 else 5,
|
| 846 |
+
impact=8 if floor_area_num > 20000 else 6,
|
| 847 |
+
risk_value=56 if building_age_num > 15 and floor_area_num > 20000 else 30,
|
| 848 |
+
residual_risk="High" if building_age_num > 15 and floor_area_num > 20000 else "Medium",
|
| 849 |
+
current_control_description=f"Current {request.riskCategory.lower()} controls include basic safety measures as described in compliance status",
|
| 850 |
+
current_control_rating="Fair" if "yes" in request.complianceStatus.lower() else "Poor",
|
| 851 |
+
mitigation_plan=f"Enhance {request.riskCategory.lower()} control systems, implement regular inspections, and ensure compliance with relevant safety standards",
|
| 852 |
+
site_details=SiteDetails(
|
| 853 |
+
site_name=f"Commercial Facility - {request.address_of_location.split(',')[-1].strip() if ',' in request.address_of_location else 'Location'}",
|
| 854 |
+
address=request.address_of_location,
|
| 855 |
+
building_type=request.nature_of_occupancy.split()[0] if request.nature_of_occupancy else "Commercial",
|
| 856 |
+
floor_area_sq_ft=floor_area_num,
|
| 857 |
+
occupancy_type=request.nature_of_occupancy,
|
| 858 |
+
year_of_construction=2024 - building_age_num if building_age_num > 0 else 2010,
|
| 859 |
+
no_of_floors=floors_num
|
| 860 |
+
),
|
| 861 |
+
risk_classification_summary=f"Site-specific {request.riskCategory} risk assessment based on building characteristics and current control status",
|
| 862 |
+
mitigation_suggestions=[
|
| 863 |
+
f"Upgrade {request.riskCategory.lower()} detection and suppression systems",
|
| 864 |
+
"Conduct regular safety training and emergency drills",
|
| 865 |
+
"Implement preventive maintenance programs",
|
| 866 |
+
"Ensure compliance with local safety regulations"
|
| 867 |
+
],
|
| 868 |
+
risk_trends=SiteRiskTrends(
|
| 869 |
+
top_category=request.riskCategory,
|
| 870 |
+
risk_severity="High" if building_age_num > 15 else "Medium",
|
| 871 |
+
observations=[
|
| 872 |
+
f"Building age of {building_age_num} years increases maintenance requirements",
|
| 873 |
+
f"Floor area of {floor_area_num:,} sq ft requires comprehensive safety systems",
|
| 874 |
+
f"Multi-floor occupancy increases emergency response complexity"
|
| 875 |
+
]
|
| 876 |
+
)
|
| 877 |
+
)
|
| 878 |
+
|
| 879 |
+
return fallback_response
|
| 880 |
+
|
| 881 |
+
except Exception as e:
|
| 882 |
+
raise HTTPException(status_code=500, detail=f"Error generating site risk assessment: {str(e)}")
|