77from backend .mixpanel .mix import track_to_mp
88from backend .database .models .user import UserRole
99from backend .database .models .agency import Agency
10- from backend .routes .search import fetch_details , build_agency_result
10+ from backend .routes .search import (
11+ fetch_details , build_agency_result , build_unit_result )
1112from .tmp .pydantic .agencies import CreateAgency , UpdateAgency
1213from flask import Blueprint , abort , request , jsonify
1314from flask_jwt_extended .view_decorators import jwt_required
2324}
2425"""
2526
27+ LOCATION_CYPHER = """
28+ CALL (a) {
29+ MATCH (a)-[]-(city:CityNode)-[]-(:CountyNode)
30+ -[]-(state:StateNode)
31+ RETURN {
32+ coords: city.coordinates,
33+ city: city.name,
34+ state: state.name
35+ } AS location
36+ }
37+ """
38+
2639TOP_UNITS_BY_COMPLAINTS_CYPHER = """
2740CALL (a) {
2841 MATCH (a)-[]-(u:Unit)<-[]-(:Employment)-[]->(o:Officer)
2942 -[:ACCUSED_OF]->(:Allegation)-[:ALLEGED]-(c:Complaint)
3043 WITH
3144 u,
3245 count(DISTINCT c) AS complaint_count,
33- count(DISTINCT o ) AS officer_count
34- ORDER BY complaint_count DESC, coalesce(u.name, "") ASC
46+ count(DISTINCT a ) AS allegation_count
47+ ORDER BY complaint_count DESC, allegation_count DESC
3548 LIMIT 3
36- RETURN collect({
37- unit_uid: u.uid,
38- unit_name: u.name,
39- complaint_count: complaint_count,
40- officer_count: officer_count
41- }) AS top_units_by_complaints
49+ RETURN collect(u) AS most_reported_units
4250}
4351"""
4452
@@ -175,9 +183,12 @@ def get_agency(agency_uid: str):
175183 if "allegations" in params .include :
176184 subqueries += ALLEGATION_CYPHER
177185 return_clause += ", collect(type_summary) AS allegation_summary"
178- if "most_complaints " in params .include :
186+ if "reported_units " in params .include :
179187 subqueries += TOP_UNITS_BY_COMPLAINTS_CYPHER
180- return_clause += ", top_units_by_complaints"
188+ return_clause += ", most_reported_units"
189+ if "location" in params .include :
190+ subqueries += LOCATION_CYPHER
191+ return_clause += ", location"
181192 cy = match_clause + subqueries + return_clause
182193
183194 rows , _ = db .cypher_query (cy , {"agency_uid" : agency_uid })
@@ -200,9 +211,28 @@ def get_agency(agency_uid: str):
200211 agency_data ["allegation_summary" ] = format_allegation_summary (
201212 row [idx ])
202213 idx += 1
203- if "most_complaints" in params .include :
204- agency_data ["most_complaints" ] = row [idx ]
214+ if "reported_units" in params .include :
215+ details = fetch_details (
216+ [u .get ("uid" ) for u in row [idx ]], "Unit" )
217+ units = [build_unit_result (
218+ u , details .get (u .get ("uid" ), {})) for u in row [idx ]]
219+ item_dump = [
220+ item .model_dump () for item in units if item
221+ ]
222+ for item in item_dump :
223+ item ["last_updated" ] = item [
224+ "last_updated" ].isoformat () if item .get (
225+ "last_updated" , None ) else None
226+ agency_data ["most_reported_units" ] = item_dump
205227 idx += 1
228+ if "location" in params .include :
229+ loc = row [idx ]
230+ agency_data ["location" ] = {
231+ "latitude" : loc ["coords" ].y ,
232+ "longitude" : loc ["coords" ].x ,
233+ "city" : loc ["city" ],
234+ "state" : loc ["state" ]
235+ } if loc and loc .get ("coords" , None ) else None
206236 return ordered_jsonify (agency_data )
207237
208238
0 commit comments