@planning-inspectorate/data-model 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/.azure/ci.yml +60 -0
  2. package/.azure/release.yml +57 -0
  3. package/.github/dependabot.yml +11 -0
  4. package/.husky/install.mjs +7 -0
  5. package/.husky/pre-commit +1 -0
  6. package/.prettierignore +11 -0
  7. package/.prettierrc +19 -0
  8. package/LICENSE +21 -0
  9. package/README.md +237 -0
  10. package/commitlint.config.js +8 -0
  11. package/docs/README.md +85 -0
  12. package/docs/appeal-document.md +776 -0
  13. package/docs/appeal-event-estimate.md +108 -0
  14. package/docs/appeal-event.md +404 -0
  15. package/docs/appeal-has.md +1960 -0
  16. package/docs/appeal-representation.md +375 -0
  17. package/docs/appeal-s78.md +3607 -0
  18. package/docs/appeal.md +1879 -0
  19. package/docs/case-schedule.md +8 -0
  20. package/docs/dart-response.md +1413 -0
  21. package/docs/employee.md +70 -0
  22. package/docs/entraid.md +108 -0
  23. package/docs/folder.md +147 -0
  24. package/docs/gettimesheets-response.md +188 -0
  25. package/docs/interested-party.md +284 -0
  26. package/docs/listed-building.md +113 -0
  27. package/docs/listed-buildings.md +113 -0
  28. package/docs/nsip-document.md +966 -0
  29. package/docs/nsip-exam-timetable-defs-event.md +223 -0
  30. package/docs/nsip-exam-timetable-defs-line-item.md +51 -0
  31. package/docs/nsip-exam-timetable-defs.md +3 -0
  32. package/docs/nsip-exam-timetable-submission.md +113 -0
  33. package/docs/nsip-exam-timetable.md +352 -0
  34. package/docs/nsip-project-update.md +163 -0
  35. package/docs/nsip-project.md +2098 -0
  36. package/docs/nsip-representation-defs-attachment.md +133 -0
  37. package/docs/nsip-representation-defs.md +3 -0
  38. package/docs/nsip-representation.md +448 -0
  39. package/docs/nsip-subscription.md +193 -0
  40. package/docs/pins-inspector.md +184 -0
  41. package/docs/pins-lpa.md +260 -0
  42. package/docs/s51-advice.md +460 -0
  43. package/docs/service-user.md +575 -0
  44. package/eslint.config.js +21 -0
  45. package/jsconfig.json +12 -0
  46. package/package.json +55 -0
  47. package/pins_data_model/__init__.py +0 -0
  48. package/pins_data_model/gen_models.py +51 -0
  49. package/pins_data_model/load_schemas.py +51 -0
  50. package/pins_data_model/models/__init__.py +0 -0
  51. package/pins_data_model/models/model_appeal_document.py +294 -0
  52. package/pins_data_model/models/model_appeal_event.py +117 -0
  53. package/pins_data_model/models/model_appeal_event_estimate.py +37 -0
  54. package/pins_data_model/models/model_appeal_has.py +585 -0
  55. package/pins_data_model/models/model_appeal_representation.py +132 -0
  56. package/pins_data_model/models/model_appeal_s78.py +864 -0
  57. package/pins_data_model/models/model_case_schedule.py +11 -0
  58. package/pins_data_model/models/model_dart_response.py +292 -0
  59. package/pins_data_model/models/model_entraid.py +37 -0
  60. package/pins_data_model/models/model_folder.py +56 -0
  61. package/pins_data_model/models/model_gettimesheets_response.py +45 -0
  62. package/pins_data_model/models/model_listed_building.py +33 -0
  63. package/pins_data_model/models/model_listed_buildings.py +33 -0
  64. package/pins_data_model/models/model_nsip_document.py +199 -0
  65. package/pins_data_model/models/model_nsip_exam_timetable.py +90 -0
  66. package/pins_data_model/models/model_nsip_project.py +488 -0
  67. package/pins_data_model/models/model_nsip_project_update.py +60 -0
  68. package/pins_data_model/models/model_nsip_representation.py +83 -0
  69. package/pins_data_model/models/model_nsip_subscription.py +60 -0
  70. package/pins_data_model/models/model_pins_inspector.py +53 -0
  71. package/pins_data_model/models/model_pins_lpa.py +69 -0
  72. package/pins_data_model/models/model_s51_advice.py +109 -0
  73. package/pins_data_model/models/model_service_user.py +121 -0
  74. package/requirements.txt +2 -0
  75. package/schemas/__init__.py +0 -0
  76. package/schemas/appeal-document.schema.json +250 -0
  77. package/schemas/appeal-event-estimate.schema.json +31 -0
  78. package/schemas/appeal-event.schema.json +123 -0
  79. package/schemas/appeal-has.schema.json +576 -0
  80. package/schemas/appeal-representation.schema.json +131 -0
  81. package/schemas/appeal-s78.schema.json +1060 -0
  82. package/schemas/commands/__init__.py +0 -0
  83. package/schemas/commands/appeal-common-submission.schema.json +202 -0
  84. package/schemas/commands/appeal-has-submission.schema.json +82 -0
  85. package/schemas/commands/appeal-representation-submission.schema.json +192 -0
  86. package/schemas/commands/appeal-s78-submission.schema.json +100 -0
  87. package/schemas/commands/appellant-submission.schema.json +164 -0
  88. package/schemas/commands/interested-party.schema.json +80 -0
  89. package/schemas/commands/lpa-questionnaire-common.schema.json +110 -0
  90. package/schemas/commands/lpa-questionnaire-has.schema.json +69 -0
  91. package/schemas/commands/lpa-questionnaire-s78.schema.json +218 -0
  92. package/schemas/commands/lpa-questionnaire.schema.json +125 -0
  93. package/schemas/commands/new-deadline-submission.schema.json +59 -0
  94. package/schemas/commands/nsip-exam-timetable-submission.schema.json +27 -0
  95. package/schemas/commands/register-nsip-subscription.schema.json +32 -0
  96. package/schemas/commands/register-representation.schema.json +51 -0
  97. package/schemas/dart-response.schema.json +350 -0
  98. package/schemas/entraid.schema.json +31 -0
  99. package/schemas/folder.schema.json +49 -0
  100. package/schemas/gettimesheets-response.schema.json +46 -0
  101. package/schemas/listed-building.schema.json +31 -0
  102. package/schemas/listed-buildings.schema.json +31 -0
  103. package/schemas/nsip-document.schema.json +235 -0
  104. package/schemas/nsip-exam-timetable.schema.json +101 -0
  105. package/schemas/nsip-project-update.schema.json +49 -0
  106. package/schemas/nsip-project.schema.json +539 -0
  107. package/schemas/nsip-representation.schema.json +110 -0
  108. package/schemas/nsip-subscription.schema.json +52 -0
  109. package/schemas/pins-inspector.schema.json +47 -0
  110. package/schemas/pins-lpa.schema.json +63 -0
  111. package/schemas/s51-advice.schema.json +113 -0
  112. package/schemas/service-user.schema.json +152 -0
  113. package/setup.py +15 -0
  114. package/src/enums.cjs +632 -0
  115. package/src/enums.d.ts +573 -0
  116. package/src/enums.js +573 -0
  117. package/src/gen-docs.js +34 -0
  118. package/src/gen-enums.js +119 -0
  119. package/src/gen-types.js +70 -0
  120. package/src/index.cjs +746 -0
  121. package/src/index.d.ts +18 -0
  122. package/src/index.js +34 -0
  123. package/src/lib/load.js +78 -0
  124. package/src/schemas.d.ts +4570 -0
  125. package/tests/appeals/appeal-event.test.js +62 -0
  126. package/tests/appeals/commands/appeal-representation-submission.test.js +107 -0
  127. package/tests/appeals/commands/has-questionnaire.test.js +92 -0
  128. package/tests/appeals/commands/has-submission.test.js +113 -0
  129. package/tests/appeals/commands/s78-questionnaire.test.js +96 -0
  130. package/tests/appeals/commands/s78-submission.test.js +119 -0
  131. package/tests/schemas.test.js +97 -0
@@ -0,0 +1,51 @@
1
+ """
2
+ Module with two functions:
3
+
4
+ load_all_schemas
5
+ load_schemas
6
+
7
+ They are used to generate a dictionary of schemas and commands
8
+ """
9
+
10
+ from typing import TypedDict
11
+ from jsonc_parser.parser import JsoncParser
12
+ from os import path, listdir
13
+
14
+ schemasDir = path.join(path.dirname(path.realpath(__file__)), "..", "schemas")
15
+ commandsDir = path.join(schemasDir, "commands")
16
+
17
+ LoadedSchemas = TypedDict(
18
+ "LoadedSchemas", {"schemas": dict[str, dict], "commands": dict[str, dict]}
19
+ )
20
+
21
+
22
+ def load_all_schemas() -> LoadedSchemas:
23
+ """
24
+ Load all schemas
25
+
26
+ Returns:
27
+ LoadedSchemas: schemas & commands dictionaries
28
+ """
29
+ return {"schemas": load_schemas(schemasDir), "commands": load_schemas(commandsDir)}
30
+
31
+
32
+ def load_schemas(dir_path: str) -> dict[str, dict]:
33
+ """
34
+ Load schemas
35
+
36
+ Args:
37
+ dir_path (str): The directory to load schemas from
38
+
39
+ Returns:
40
+ dict[str, dict]: a dictionary of schema name to schema
41
+ """
42
+
43
+ schemas_by_name = {}
44
+
45
+ for filename in listdir(dir_path):
46
+ if filename.endswith(".schema.json") or filename.endswith(".schema.jsonc"):
47
+ schema = JsoncParser.parse_file(path.join(dir_path, filename))
48
+ name = path.basename(filename)
49
+ schemas_by_name[name] = schema
50
+
51
+ return schemas_by_name
File without changes
@@ -0,0 +1,294 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: appeal-document.schema.json
3
+ # timestamp: 2025-07-16T14:06:10+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from enum import Enum
8
+
9
+ from pydantic import AwareDatetime, BaseModel, ConfigDict, Field
10
+
11
+
12
+ class VirusCheckStatus(Enum):
13
+ """
14
+ Indicates the virus check status for the current document
15
+ """
16
+
17
+ not_scanned = "not_scanned"
18
+ scanned = "scanned"
19
+ affected = "affected"
20
+ NoneType_None = None
21
+
22
+
23
+ class CaseType(Enum):
24
+ """
25
+ The internal code for an appeal type, e.g. Householder (D)
26
+ """
27
+
28
+ C = "C"
29
+ D = "D"
30
+ F = "F"
31
+ G = "G"
32
+ H = "H"
33
+ L = "L"
34
+ Q = "Q"
35
+ S = "S"
36
+ V = "V"
37
+ W = "W"
38
+ X = "X"
39
+ Y = "Y"
40
+ Z = "Z"
41
+ ZA = "ZA"
42
+ ZP = "ZP"
43
+ NoneType_None = None
44
+
45
+
46
+ class RedactedStatus(Enum):
47
+ """
48
+ Indicates the redaction status for the document
49
+ """
50
+
51
+ not_redacted = "not_redacted"
52
+ redacted = "redacted"
53
+ no_redaction_required = "no_redaction_required"
54
+ NoneType_None = None
55
+
56
+
57
+ class DocumentType(Enum):
58
+ """
59
+ The type of document, used for exchange, migrations and consumption from the appeal back-office system
60
+ """
61
+
62
+ appellantCaseCorrespondence = "appellantCaseCorrespondence"
63
+ appellantCaseWithdrawalLetter = "appellantCaseWithdrawalLetter"
64
+ appellantCostsApplication = "appellantCostsApplication"
65
+ appellantCostsCorrespondence = "appellantCostsCorrespondence"
66
+ appellantCostsWithdrawal = "appellantCostsWithdrawal"
67
+ appellantStatement = "appellantStatement"
68
+ applicationDecisionLetter = "applicationDecisionLetter"
69
+ changedDescription = "changedDescription"
70
+ originalApplicationForm = "originalApplicationForm"
71
+ whoNotified = "whoNotified"
72
+ whoNotifiedSiteNotice = "whoNotifiedSiteNotice"
73
+ whoNotifiedLetterToNeighbours = "whoNotifiedLetterToNeighbours"
74
+ whoNotifiedPressAdvert = "whoNotifiedPressAdvert"
75
+ conservationMap = "conservationMap"
76
+ lpaCaseCorrespondence = "lpaCaseCorrespondence"
77
+ lpaCostsApplication = "lpaCostsApplication"
78
+ lpaCostsCorrespondence = "lpaCostsCorrespondence"
79
+ lpaCostsWithdrawal = "lpaCostsWithdrawal"
80
+ otherPartyRepresentations = "otherPartyRepresentations"
81
+ planningOfficerReport = "planningOfficerReport"
82
+ appellantCostsDecisionLetter = "appellantCostsDecisionLetter"
83
+ lpaCostsDecisionLetter = "lpaCostsDecisionLetter"
84
+ caseDecisionLetter = "caseDecisionLetter"
85
+ crossTeamCorrespondence = "crossTeamCorrespondence"
86
+ inspectorCorrespondence = "inspectorCorrespondence"
87
+ mainPartyCorrespondence = "mainPartyCorrespondence"
88
+ uncategorised = "uncategorised"
89
+ designAccessStatement = "designAccessStatement"
90
+ plansDrawings = "plansDrawings"
91
+ newPlansDrawings = "newPlansDrawings"
92
+ planningObligation = "planningObligation"
93
+ ownershipCertificate = "ownershipCertificate"
94
+ otherNewDocuments = "otherNewDocuments"
95
+ statementCommonGround = "statementCommonGround"
96
+ communityInfrastructureLevy = "communityInfrastructureLevy"
97
+ supplementaryPlanning = "supplementaryPlanning"
98
+ otherRelevantPolicies = "otherRelevantPolicies"
99
+ emergingPlan = "emergingPlan"
100
+ developmentPlanPolicies = "developmentPlanPolicies"
101
+ consultationResponses = "consultationResponses"
102
+ eiaEnvironmentalStatement = "eiaEnvironmentalStatement"
103
+ eiaScreeningDirection = "eiaScreeningDirection"
104
+ eiaScreeningOpinion = "eiaScreeningOpinion"
105
+ eiaScopingOpinion = "eiaScopingOpinion"
106
+ definitiveMapStatement = "definitiveMapStatement"
107
+ treePreservationPlan = "treePreservationPlan"
108
+ interestedPartyComment = "interestedPartyComment"
109
+ lpaStatement = "lpaStatement"
110
+ rule6Statement = "rule6Statement"
111
+ appellantFinalComment = "appellantFinalComment"
112
+ lpaFinalComment = "lpaFinalComment"
113
+ appellantProofOfEvidence = "appellantProofOfEvidence"
114
+ appellantWitnessesEvidence = "appellantWitnessesEvidence"
115
+ lpaProofOfEvidence = "lpaProofOfEvidence"
116
+ lpaWitnessesEvidence = "lpaWitnessesEvidence"
117
+ rule6ProofOfEvidence = "rule6ProofOfEvidence"
118
+ rule6WitnessesEvidence = "rule6WitnessesEvidence"
119
+ environmentalAssessment = "environmentalAssessment"
120
+ appealNotification = "appealNotification"
121
+ historicEnglandConsultation = "historicEnglandConsultation"
122
+ NoneType_None = None
123
+
124
+
125
+ class SourceSystem(Enum):
126
+ """
127
+ The system mastering the metadata for the current document
128
+ """
129
+
130
+ back_office_appeals = "back-office-appeals"
131
+ horizon = "horizon"
132
+ acp = "acp"
133
+ sharepoint = "sharepoint"
134
+ NoneType_None = None
135
+
136
+
137
+ class Origin(Enum):
138
+ """
139
+ Indicates where the documents originates from
140
+ """
141
+
142
+ pins = "pins"
143
+ citizen = "citizen"
144
+ lpa = "lpa"
145
+ ogd = "ogd"
146
+ NoneType_None = None
147
+
148
+
149
+ class CaseStage(Enum):
150
+ """
151
+ The stage in the appeal process that has created the document
152
+ """
153
+
154
+ appellant_case = "appellant-case"
155
+ lpa_questionnaire = "lpa-questionnaire"
156
+ statements = "statements"
157
+ third_party_comments = "third-party-comments"
158
+ evidence = "evidence"
159
+ witnesses = "witnesses"
160
+ final_comments = "final-comments"
161
+ appeal_decision = "appeal-decision"
162
+ costs = "costs"
163
+ internal = "internal"
164
+ NoneType_None = None
165
+
166
+
167
+ class AppealDocument(BaseModel):
168
+ """
169
+ Schema defining the metadata for appeal documents
170
+ """
171
+
172
+ model_config = ConfigDict(
173
+ extra="allow",
174
+ )
175
+ documentId: str = Field(..., examples=["4547fec8-16b2-47bb-836d-4d0baac04079"])
176
+ """
177
+ The unique identifier for the document
178
+ """
179
+ caseId: int | None = Field(..., examples=[1200])
180
+ """
181
+ Internal case identifier
182
+ """
183
+ caseReference: str = Field(..., examples=["7002471"])
184
+ """
185
+ External case identifier
186
+ """
187
+ version: int = Field(..., examples=[1])
188
+ """
189
+ A document can have multiple versions, and this indicates the latest version
190
+ """
191
+ filename: str = Field(..., examples=["filename.pdf"])
192
+ """
193
+ Current stored name of the document
194
+ """
195
+ originalFilename: str = Field(..., examples=["original_filename.pdf"])
196
+ """
197
+ Original name of document
198
+ """
199
+ size: int = Field(..., examples=[23452])
200
+ """
201
+ The file size, in bytes
202
+ """
203
+ mime: str = Field(..., examples=["application/pdf"])
204
+ """
205
+ The mime type for the current version of the file
206
+ """
207
+ documentURI: str = Field(
208
+ ...,
209
+ examples=[
210
+ "https://custom-domain.gov.uk/container-name/appeal/7002471/4547fec8-16b2-47bb-836d-4d0baac04079/v1/filename.pdf"
211
+ ],
212
+ )
213
+ """
214
+ The internal location of the document
215
+ """
216
+ publishedDocumentURI: str | None = Field(
217
+ ...,
218
+ examples=[
219
+ "https://custom-domain.gov.uk/container-name/appeal/7002471/4547fec8-16b2-47bb-836d-4d0baac04079/v1/filename.pdf"
220
+ ],
221
+ )
222
+ """
223
+ The location of the published document, will be null if the datePublished is not set
224
+ """
225
+ virusCheckStatus: VirusCheckStatus
226
+ """
227
+ Indicates the virus check status for the current document
228
+ """
229
+ fileMD5: str | None = Field(..., examples=["b1946ac92492d2347c6235b4d2611184"])
230
+ """
231
+ A MD5 hash to check the validity of the file
232
+ """
233
+ dateCreated: AwareDatetime = Field(..., examples=["2023-07-27T20:30:00.000Z"])
234
+ """
235
+ The creation date for the document
236
+ """
237
+ dateReceived: AwareDatetime | None = Field(
238
+ ..., examples=["2023-07-27T20:30:00.000Z"]
239
+ )
240
+ """
241
+ The date the document was received
242
+ """
243
+ datePublished: AwareDatetime | None = Field(
244
+ ..., examples=["2023-07-27T20:30:00.000Z"]
245
+ )
246
+ """
247
+ The date the document was published
248
+ """
249
+ lastModified: AwareDatetime | None = Field(
250
+ ..., examples=["2023-07-27T20:30:00.000Z"]
251
+ )
252
+ """
253
+ The last update date for the document
254
+ """
255
+ caseType: CaseType
256
+ """
257
+ The internal code for an appeal type, e.g. Householder (D)
258
+ """
259
+ redactedStatus: RedactedStatus
260
+ """
261
+ Indicates the redaction status for the document
262
+ """
263
+ documentType: DocumentType
264
+ """
265
+ The type of document, used for exchange, migrations and consumption from the appeal back-office system
266
+ """
267
+ sourceSystem: SourceSystem
268
+ """
269
+ The system mastering the metadata for the current document
270
+ """
271
+ origin: Origin
272
+ """
273
+ Indicates where the documents originates from
274
+ """
275
+ owner: str | None = None
276
+ """
277
+ Owner of the current document
278
+ """
279
+ author: str | None = None
280
+ """
281
+ Name of person who authored document
282
+ """
283
+ description: str | None = None
284
+ """
285
+ A custom description for the document
286
+ """
287
+ caseStage: CaseStage
288
+ """
289
+ The stage in the appeal process that has created the document
290
+ """
291
+ horizonFolderId: str | None = None
292
+ """
293
+ The folder ID containing the document in Horizon
294
+ """
@@ -0,0 +1,117 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: appeal-event.schema.json
3
+ # timestamp: 2025-07-16T14:06:09+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from enum import Enum
8
+
9
+ from pydantic import AwareDatetime, BaseModel, ConfigDict, Field
10
+
11
+
12
+ class EventType(Enum):
13
+ """
14
+ The type of event
15
+ """
16
+
17
+ site_visit_access_required = "site_visit_access_required"
18
+ site_visit_accompanied = "site_visit_accompanied"
19
+ site_visit_unaccompanied = "site_visit_unaccompanied"
20
+ hearing = "hearing"
21
+ hearing_virtual = "hearing_virtual"
22
+ inquiry = "inquiry"
23
+ inquiry_virtual = "inquiry_virtual"
24
+ in_house = "in_house"
25
+ pre_inquiry = "pre_inquiry"
26
+ pre_inquiry_virtual = "pre_inquiry_virtual"
27
+
28
+
29
+ class EventStatus(Enum):
30
+ """
31
+ Status of the event
32
+ """
33
+
34
+ withdrawn = "withdrawn"
35
+ in_abeyance = "in_abeyance"
36
+ change_of_procedure = "change_of_procedure"
37
+ new_rescheduled = "new_rescheduled"
38
+ confirmed = "confirmed"
39
+ link_to_enforcement = "link_to_enforcement"
40
+ offered = "offered"
41
+ postponed = "postponed"
42
+
43
+
44
+ class AppealEvent(BaseModel):
45
+ """
46
+ Schema defining the metadata for appeal events, such as site visits, inquiries, hearings
47
+ """
48
+
49
+ model_config = ConfigDict(
50
+ extra="allow",
51
+ )
52
+ eventId: str = Field(..., examples=["7000000-1"])
53
+ """
54
+ The unique identifier for the event
55
+ """
56
+ caseReference: str = Field(..., examples=["7002471"])
57
+ """
58
+ External case identifier
59
+ """
60
+ eventType: EventType
61
+ """
62
+ The type of event
63
+ """
64
+ eventName: str | None = Field(..., examples=["A site visit"])
65
+ """
66
+ An optional description / name for the event
67
+ """
68
+ eventStatus: EventStatus
69
+ """
70
+ Status of the event
71
+ """
72
+ isUrgent: bool
73
+ """
74
+ Indicates if the event is urgent
75
+ """
76
+ eventPublished: bool | None = None
77
+ """
78
+ Indicates if the event has been published
79
+ """
80
+ eventStartDateTime: AwareDatetime = Field(
81
+ ..., examples=["2023-07-27T20:30:00.000Z"]
82
+ )
83
+ """
84
+ Event start date and time
85
+ """
86
+ eventEndDateTime: AwareDatetime | None = Field(
87
+ ..., examples=["2023-07-27T20:30:00.000Z"]
88
+ )
89
+ """
90
+ Event end date and time
91
+ """
92
+ notificationOfSiteVisit: AwareDatetime | None = Field(
93
+ ..., examples=["2023-07-27T20:30:00.000Z"]
94
+ )
95
+ """
96
+ The date third-parties were informed of the site visit event
97
+ """
98
+ addressLine1: str | None = Field(..., examples=["96 The Avenue"])
99
+ """
100
+ First line of address for the event site
101
+ """
102
+ addressLine2: str | None = None
103
+ """
104
+ Second line of address for the event site
105
+ """
106
+ addressTown: str | None = Field(..., examples=["Maidstone"])
107
+ """
108
+ Town / City of the event address
109
+ """
110
+ addressCounty: str | None = Field(..., examples=["Kent"])
111
+ """
112
+ County of the event address
113
+ """
114
+ addressPostcode: str | None = Field(..., examples=["MD21 5XY"])
115
+ """
116
+ Postal code of the event address
117
+ """
@@ -0,0 +1,37 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: appeal-event-estimate.schema.json
3
+ # timestamp: 2025-07-16T14:06:09+00:00
4
+
5
+ from __future__ import annotations
6
+
7
+ from pydantic import BaseModel, ConfigDict
8
+
9
+
10
+ class AppealEventEstimate(BaseModel):
11
+ """
12
+ All event estimates belong to a case. A case has only one event estimate.
13
+ """
14
+
15
+ model_config = ConfigDict(
16
+ extra="allow",
17
+ )
18
+ id: int
19
+ """
20
+ The unique identifier within the Back Office.
21
+ """
22
+ caseReference: str
23
+ """
24
+ The case reference the event estimate belongs to.
25
+ """
26
+ preparationTime: float | None = None
27
+ """
28
+ Estimated inspector time (days) to prepare for event.
29
+ """
30
+ sittingTime: float | None = None
31
+ """
32
+ Estimated inspector time (days) for event.
33
+ """
34
+ reportingTime: float | None = None
35
+ """
36
+ Estimated inspector time (days) for event reporting.
37
+ """