Skip to content

Commit 16aa022

Browse files
committed
Updates the Database Models
Updates the models to account for additional properties required by the source data and the new version of the UI. Also includes a change to add details to the standard error response.
1 parent 737dbc6 commit 16aa022

File tree

14 files changed

+223
-56
lines changed

14 files changed

+223
-56
lines changed

backend/database/models/agency.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ class UnitMembership(StructuredRel, JsonSerializable):
3030

3131

3232
class Unit(StructuredNode, JsonSerializable):
33+
__property_order__ = [
34+
"uid", "name", "website_url", "phone",
35+
"email", "description", "address",
36+
"city", "state", "zip", "agency_url",
37+
"officers_url", "date_etsablished"
38+
]
3339
__hidden_properties__ = ["citations"]
3440

3541
uid = UniqueIdProperty()
@@ -62,6 +68,12 @@ def __repr__(self):
6268

6369

6470
class Agency(StructuredNode, JsonSerializable):
71+
__property_order__ = [
72+
"uid", "name", "website_url", "hq_address",
73+
"hq_city", "hq_state", "hq_zip",
74+
"phone", "email", "description",
75+
"jurisdiction"
76+
]
6577
__hidden_properties__ = ["citations"]
6678

6779
uid = UniqueIdProperty()

backend/database/models/attachment.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,51 @@
22
from neomodel import (
33
StringProperty,
44
UniqueIdProperty,
5-
StructuredNode
5+
StructuredNode,
6+
DateProperty
67
)
78

89

910
class Attachment(JsonSerializable, StructuredNode):
11+
"""
12+
Multimedia attachment.
13+
"""
14+
__property_order__ = [
15+
"uid", "title", "url", "filetype"
16+
]
17+
__hidden_properties__ = ["hash"]
18+
1019
uid = UniqueIdProperty()
1120
title = StringProperty()
1221
hash = StringProperty()
1322
url = StringProperty()
1423
filetype = StringProperty()
24+
25+
26+
class Article(StructuredNode, JsonSerializable):
27+
"""
28+
News article.
29+
"""
30+
31+
uid = UniqueIdProperty()
32+
title = StringProperty()
33+
publisher = StringProperty()
34+
publication_date = DateProperty()
35+
url = StringProperty()
36+
37+
38+
class SocialMediaInfo(StructuredNode, JsonSerializable):
39+
"""
40+
Social media information.
41+
"""
42+
__property_order__ = [
43+
"twitter_url", "linkedin_url", "facebook_url",
44+
"instagram_url", "youtube_url", "tiktok_url"
45+
]
46+
47+
twitter_url = StringProperty()
48+
linkedin_url = StringProperty()
49+
facebook_url = StringProperty()
50+
instagram_url = StringProperty()
51+
youtube_url = StringProperty()
52+
tiktok_url = StringProperty()

backend/database/models/civilian.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"""Define the Classes for Civilians."""
2+
from backend.schemas import JsonSerializable
3+
from backend.database.models.types.enums import Ethnicity, Gender
24
from neomodel import (
35
StructuredNode,
46
StringProperty,
@@ -7,10 +9,11 @@
79
)
810

911

10-
class Civilian(StructuredNode):
12+
class Civilian(StructuredNode, JsonSerializable):
1113
age = IntegerProperty()
12-
race = StringProperty()
13-
gender = StringProperty()
14+
age_range = StringProperty()
15+
ethnicity = StringProperty(choices=Ethnicity.choices())
16+
gender = StringProperty(choices=Gender.choices())
1417

1518
# Relationships
1619
complaints = RelationshipTo(

backend/database/models/complaint.py

Lines changed: 72 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
RelationshipTo,
88
RelationshipFrom,
99
DateProperty,
10-
UniqueIdProperty
10+
UniqueIdProperty,
11+
ZeroOrOne
1112
)
1213

1314

@@ -19,36 +20,58 @@ class RecordType(str, PropertyEnum):
1920

2021

2122
# Neo4j Models
22-
class BaseSourceRel(StructuredRel, JsonSerializable):
23+
class ComplaintSourceRel(StructuredRel, JsonSerializable):
24+
uid = UniqueIdProperty()
2325
record_type = StringProperty(
2426
choices=RecordType.choices(),
2527
required=True
2628
)
29+
date_published = DateProperty()
2730

28-
29-
class LegalSourceRel(BaseSourceRel):
31+
# Legal Source Properties
3032
court = StringProperty()
3133
judge = StringProperty()
3234
docket_number = StringProperty()
33-
date_of_action = DateProperty()
34-
35+
case_event_date = DateProperty()
3536

36-
class NewsSourceRel(BaseSourceRel):
37+
# News Source Properties
3738
publication_name = StringProperty()
38-
publication_date = DateProperty()
3939
publication_url = StringProperty()
4040
author = StringProperty()
4141
author_url = StringProperty()
4242
author_email = StringProperty()
4343

44-
45-
class GovernmentSourceRel(BaseSourceRel):
44+
# Government Source Properties
4645
reporting_agency = StringProperty()
4746
reporting_agency_url = StringProperty()
4847
reporting_agency_email = StringProperty()
4948

5049

50+
class Location(StructuredNode, JsonSerializable):
51+
__property_order__ = [
52+
"location_type", "location_description",
53+
"address", "city", "state", "zip",
54+
"responsibility", "responsibility_type"
55+
]
56+
57+
location_type = StringProperty()
58+
loocation_description = StringProperty()
59+
address = StringProperty()
60+
city = StringProperty()
61+
state = StringProperty()
62+
zip = StringProperty()
63+
responsibility = StringProperty()
64+
responsibility_type = StringProperty()
65+
66+
5167
class Complaint(StructuredNode, JsonSerializable):
68+
__property_order__ = [
69+
"uid", "record_id", "category",
70+
"incident_date", "recieved_date",
71+
"closed_date", "reason_for_contact",
72+
"outcome_of_contact"
73+
]
74+
5275
uid = UniqueIdProperty()
5376
record_id = StringProperty()
5477
category = StringProperty()
@@ -59,22 +82,33 @@ class Complaint(StructuredNode, JsonSerializable):
5982
outcome_of_contact = StringProperty()
6083

6184
# Relationships
62-
source_org = RelationshipFrom("Source", "REPORTED", model=BaseSourceRel)
85+
source_org = RelationshipFrom(
86+
"Source", "REPORTED", model=ComplaintSourceRel)
6387
location = RelationshipTo("Location", "OCCURRED_AT")
6488
civlian_witnesses = RelationshipFrom("Civilian", "WITNESSED")
6589
police_witnesses = RelationshipFrom("Officer", "WITNESSED")
66-
attachments = RelationshipTo("Attachment", "ATTACHED_TO")
90+
attachments = RelationshipTo(
91+
'backend.database.models.attachment.Attachment', "REFERENCED_IN")
92+
articles = RelationshipTo(
93+
'backend.database.models.attachment.Article', "MENTIONED_IN")
6794
allegations = RelationshipTo("Allegation", "ALLEGED")
6895
investigations = RelationshipTo("Investigation", "EXAMINED_BY")
6996
penalties = RelationshipTo("Penalty", "RESULTS_IN")
70-
civilian_review_board = RelationshipFrom("CivilianReviewBoard", "REVIEWED")
97+
# civilian_review_board = RelationshipFrom(
98+
# "CivilianReviewBoard", "REVIEWED")
7199

72100
def __repr__(self):
73101
"""Represent instance as a unique string."""
74102
return f"<Complaint {self.uid}>"
75103

76104

77-
class Allegation(StructuredNode):
105+
class Allegation(StructuredNode, JsonSerializable):
106+
__property_order__ = [
107+
"uid", "record_id", "allegation",
108+
"type", "subtype", "recommended_finding",
109+
"recommended_outcome", "finding", "outcome"
110+
]
111+
78112
uid = UniqueIdProperty()
79113
record_id = StringProperty()
80114
allegation = StringProperty()
@@ -86,36 +120,53 @@ class Allegation(StructuredNode):
86120
outcome = StringProperty()
87121

88122
# Relationships
89-
complainant = RelationshipFrom("Civilian", "COMPLAINED_OF")
123+
complainant = RelationshipFrom(
124+
"Civilian", "COMPLAINED_OF", Cadinality=ZeroOrOne)
125+
complaint = RelationshipFrom(
126+
"Complaint", "ALLEGED", Cadinality=ZeroOrOne)
90127
accused = RelationshipFrom("Officer", "ACCUSED_OF")
91-
complaint = RelationshipFrom("Complaint", "ALLEGED")
92128

93129
def __repr__(self):
94130
"""Represent instance as a unique string."""
95131
return f"<Allegation {self.uid}>"
96132

97133

98-
class Investigation(StructuredNode):
134+
class Investigation(StructuredNode, JsonSerializable):
135+
__property_order__ = [
136+
"uid", "start_date", "end_date"
137+
]
138+
99139
uid = UniqueIdProperty()
100140
start_date = DateProperty()
101141
end_date = DateProperty()
102142

103143
# Relationships
104-
investigator = RelationshipFrom("Officer", "LED_BY")
144+
investigator = RelationshipFrom(
145+
"Officer", "LED_BY", Cadinality=ZeroOrOne)
105146
complaint = RelationshipFrom("Complaint", "EXAMINED_BY")
106147

107148
def __repr__(self):
108149
"""Represent instance as a unique string."""
109150
return f"<Investigation {self.uid}>"
110151

111152

112-
class Penalty(StructuredNode):
153+
class Penalty(StructuredNode, JsonSerializable):
154+
__property_order__ = [
155+
"uid", "penalty", "date_assessed",
156+
"crb_plea", "crb_case_status",
157+
"crb_disposition", "agency_disposition"
158+
]
159+
113160
uid = UniqueIdProperty()
114-
description = StringProperty()
161+
penalty = StringProperty()
115162
date_assessed = DateProperty()
163+
crb_plea = StringProperty()
164+
crb_case_status = StringProperty()
165+
crb_disposition = StringProperty()
166+
agency_disposition = StringProperty()
116167

117168
# Relationships
118-
officer = RelationshipFrom("Officer", "RECEIVED")
169+
officer = RelationshipFrom("models.officer.Officer", "RECEIVED")
119170
complaint = RelationshipFrom("Complaint", "RESULTS_IN")
120171

121172
def __repr__(self):

backend/database/models/litigation.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,34 @@ class LegalCaseType(str, PropertyEnum):
1414
CRIMINAL = "CRIMINAL"
1515

1616

17+
class CourtLevel(str, PropertyEnum):
18+
MUNICIPAL_OR_COUNTY = "Municipal or County"
19+
STATE_TRIAL = "State Trial Court"
20+
STATE_INTERMEDIATE_APPELLATE = "State Intermediate Appellate"
21+
STATE_HIGHEST = "State Highest"
22+
FEDERAL_DISTRICT = "Federal District"
23+
FEDERAL_APPELLATE = "Federal Appellate"
24+
US_SUPREME_COURT = "U.S. Supreme"
25+
26+
1727
class Litigation(StructuredNode, JsonSerializable):
28+
"""
29+
Represents a legal case or litigation.
30+
"""
31+
__property_order__ = [
32+
"uid", "case_type", "case_title", "state",
33+
"court_name", "court_level", "jurisdiction",
34+
"docket_number", "description", "start_date",
35+
"settlement_date", "settlement_amount",
36+
"url"
37+
]
1838
__hidden_properties__ = ["citations"]
1939

2040
uid = UniqueIdProperty()
2141
case_title = StringProperty()
2242
docket_number = StringProperty()
23-
court_level = StringProperty()
43+
court_name = StringProperty()
44+
court_level = StringProperty(choices=CourtLevel.choices())
2445
jurisdiction = StringProperty()
2546
state = StringProperty()
2647
description = StringProperty()
@@ -42,6 +63,10 @@ def __repr__(self):
4263

4364

4465
class Document(StructuredNode, JsonSerializable):
66+
__property_order__ = [
67+
"uid", "title", "description", "url"
68+
]
69+
4570
uid = UniqueIdProperty()
4671
title = StringProperty()
4772
description = StringProperty()

backend/database/models/officer.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ class StateID(StructuredNode, JsonSerializable):
1616
law enforcement agencies. For example, in New York, this would be
1717
the Tax ID Number.
1818
"""
19+
__property_order__ = [
20+
"uid", "state", "id_name", "value"
21+
]
22+
1923
id_name = StringProperty() # e.g. "Tax ID Number"
2024
state = StringProperty(choices=State.choices()) # e.g. "NY"
2125
value = StringProperty() # e.g. "958938"
@@ -41,6 +45,7 @@ class Officer(StructuredNode, JsonSerializable):
4145
ethnicity = StringProperty(choices=Ethnicity.choices())
4246
gender = StringProperty(choices=Gender.choices())
4347
date_of_birth = DateProperty()
48+
year_of_birth = StringProperty()
4449

4550
# Relationships
4651
state_ids = RelationshipTo('StateID', "HAS_STATE_ID")
@@ -54,6 +59,10 @@ class Officer(StructuredNode, JsonSerializable):
5459
'backend.database.models.complaint.Investigation', "LEAD_BY")
5560
commands = Relationship(
5661
'backend.database.models.agency.Unit', "COMMANDS")
62+
articles = RelationshipTo(
63+
'backend.database.models.attachment.Article', "MENTIONED_IN")
64+
attachments = RelationshipTo(
65+
'backend.database.models.attachment.Attachment', "REFERENCED_IN")
5766
citations = RelationshipTo(
5867
'backend.database.models.source.Source', "UPDATED_BY", model=Citation)
5968

0 commit comments

Comments
 (0)