@planning-inspectorate/data-model 2.56.0 → 2.57.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.
@@ -1378,6 +1378,7 @@ The final outcome for the decision
1378
1378
  | `"planning_permission_granted"` | |
1379
1379
  | `"quashed_on_legal_grounds"` | |
1380
1380
  | `"notice_varied_and_upheld"` | |
1381
+ | `"notice_quashed"` | |
1381
1382
  | `null` | |
1382
1383
 
1383
1384
  ## caseCompletedDate
@@ -3697,6 +3698,13 @@ The net gain in residences of the proposed development
3697
3698
  | `"lawful-development-certificate"` | |
3698
3699
  | `"discontinuance-notice"` | |
3699
3700
  | `"permission-in-principle"` | |
3701
+ | `"tree-preservation-order"` | |
3702
+ | `"tree-replacement-notice"` | |
3703
+ | `"high-hedge-appeal"` | |
3704
+ | `"hedgerows-appeal"` | |
3705
+ | `"community-infrastructure-levy"` | |
3706
+ | `"planning-obligation"` | |
3707
+ | `"environmental"` | |
3700
3708
  | `null` | |
3701
3709
 
3702
3710
  ## developmentType
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planning-inspectorate/data-model",
3
- "version": "2.56.0",
3
+ "version": "2.57.0",
4
4
  "description": "JSON Schemas for the Planning Inspectorate's Data Model",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -36,7 +36,7 @@
36
36
  "@commitlint/cli": "^21.0.0",
37
37
  "@commitlint/config-conventional": "^21.0.0",
38
38
  "@eslint/js": "^10.0.1",
39
- "@planning-inspectorate/coding-standards": "^1.1.1",
39
+ "@planning-inspectorate/coding-standards": "^2.0.0",
40
40
  "ajv": "^8.17.1",
41
41
  "ajv-formats": "^3.0.1",
42
42
  "conventional-changelog-conventionalcommits": "^10.2.0",
@@ -58,6 +58,7 @@ class DocumentType(Enum):
58
58
  The type of document, used for exchange, migrations and consumption from the appeal back-office system
59
59
  """
60
60
 
61
+ appellantCase = "appellantCase"
61
62
  appellantCaseCorrespondence = "appellantCaseCorrespondence"
62
63
  appellantCaseWithdrawalLetter = "appellantCaseWithdrawalLetter"
63
64
  appellantCostsApplication = "appellantCostsApplication"
@@ -72,6 +73,7 @@ class DocumentType(Enum):
72
73
  whoNotifiedLetterToNeighbours = "whoNotifiedLetterToNeighbours"
73
74
  whoNotifiedPressAdvert = "whoNotifiedPressAdvert"
74
75
  conservationMap = "conservationMap"
76
+ lpaQuestionnaire = "lpaQuestionnaire"
75
77
  lpaCaseCorrespondence = "lpaCaseCorrespondence"
76
78
  lpaCostsApplication = "lpaCostsApplication"
77
79
  lpaCostsCorrespondence = "lpaCostsCorrespondence"
@@ -0,0 +1,453 @@
1
+ # generated by datamodel-codegen:
2
+ # filename: appeal-group-c.schema.json
3
+
4
+ from __future__ import annotations
5
+
6
+ from enum import Enum, StrEnum
7
+
8
+ from pydantic import AwareDatetime, BaseModel, ConfigDict, Field, constr
9
+
10
+
11
+ class CaseType(StrEnum):
12
+ """
13
+ The internal letter code for an appeal type, e.g. W (Environmental)
14
+ """
15
+
16
+ C = "C"
17
+ D = "D"
18
+ F = "F"
19
+ G = "G"
20
+ H = "H"
21
+ L = "L"
22
+ Q = "Q"
23
+ S = "S"
24
+ V = "V"
25
+ W = "W"
26
+ X = "X"
27
+ Y = "Y"
28
+ Z = "Z"
29
+ ZA = "ZA"
30
+ ZP = "ZP"
31
+
32
+
33
+ class CaseStatus(StrEnum):
34
+ """
35
+ The processing status for the appeal
36
+ """
37
+
38
+ assign_case_officer = "assign_case_officer"
39
+ validation = "validation"
40
+ ready_to_start = "ready_to_start"
41
+ lpa_questionnaire = "lpa_questionnaire"
42
+ issue_determination = "issue_determination"
43
+ statements = "statements"
44
+ evidence = "evidence"
45
+ witnesses = "witnesses"
46
+ final_comments = "final_comments"
47
+ complete = "complete"
48
+ invalid = "invalid"
49
+ closed = "closed"
50
+ withdrawn = "withdrawn"
51
+ awaiting_transfer = "awaiting_transfer"
52
+ transferred = "transferred"
53
+ event = "event"
54
+ awaiting_event = "awaiting_event"
55
+ notice_withdrawn = "notice_withdrawn"
56
+ closed_opened_in_error = "closed_opened_in_error"
57
+
58
+
59
+ class CaseProcedure(Enum):
60
+ """
61
+ The type of procedure for the appeal
62
+ """
63
+
64
+ written = "written"
65
+ hearing = "hearing"
66
+ inquiry = "inquiry"
67
+ writtenPart1 = "writtenPart1"
68
+ writtenPart2 = "writtenPart2"
69
+ NoneType_None = None
70
+
71
+
72
+ class CaseValidationOutcome(Enum):
73
+ """
74
+ The outcome of the validation action
75
+ """
76
+
77
+ valid = "valid"
78
+ invalid = "invalid"
79
+ incomplete = "incomplete"
80
+ NoneType_None = None
81
+
82
+
83
+ class LpaQuestionnaireValidationOutcome(Enum):
84
+ """
85
+ The outcome of the LPA questionnaire validation action
86
+ """
87
+
88
+ complete = "complete"
89
+ incomplete = "incomplete"
90
+ NoneType_None = None
91
+
92
+
93
+ class CaseDecisionOutcome(Enum):
94
+ """
95
+ The final outcome for the decision
96
+ """
97
+
98
+ allowed = "allowed"
99
+ split_decision = "split_decision"
100
+ dismissed = "dismissed"
101
+ invalid = "invalid"
102
+ notice_upheld = "notice_upheld"
103
+ planning_permission_granted = "planning_permission_granted"
104
+ quashed_on_legal_grounds = "quashed_on_legal_grounds"
105
+ notice_varied_and_upheld = "notice_varied_and_upheld"
106
+ notice_quashed = "notice_quashed"
107
+ NoneType_None = None
108
+
109
+
110
+ class AllocationLevel(Enum):
111
+ """
112
+ A level used for allocation purposes
113
+ """
114
+
115
+ A = "A"
116
+ B = "B"
117
+ C = "C"
118
+ D = "D"
119
+ E = "E"
120
+ F = "F"
121
+ G = "G"
122
+ H = "H"
123
+ NoneType_None = None
124
+
125
+
126
+ class AllocationBand(Enum):
127
+ """
128
+ A band used for allocation purposes
129
+ """
130
+
131
+ int_1 = 1
132
+ int_2 = 2
133
+ int_3 = 3
134
+ NoneType_None = None
135
+
136
+
137
+ class TypeOfPlanningApplication(Enum):
138
+ """
139
+ The type of application or notice that is the subject of the appeal
140
+ """
141
+
142
+ full_appeal = "full-appeal"
143
+ householder_planning = "householder-planning"
144
+ outline_planning = "outline-planning"
145
+ prior_approval = "prior-approval"
146
+ reserved_matters = "reserved-matters"
147
+ removal_or_variation_of_conditions = "removal-or-variation-of-conditions"
148
+ listed_building = "listed-building"
149
+ minor_commercial_development = "minor-commercial-development"
150
+ advertisement = "advertisement"
151
+ lawful_development_certificate = "lawful-development-certificate"
152
+ discontinuance_notice = "discontinuance-notice"
153
+ permission_in_principle = "permission-in-principle"
154
+ tree_preservation_order = "tree-preservation-order"
155
+ tree_replacement_notice = "tree-replacement-notice"
156
+ high_hedge_appeal = "high-hedge-appeal"
157
+ hedgerows_appeal = "hedgerows-appeal"
158
+ community_infrastructure_levy = "community-infrastructure-levy"
159
+ planning_obligation = "planning-obligation"
160
+ environmental = "environmental"
161
+ NoneType_None = None
162
+
163
+
164
+ class CaseSubType(Enum):
165
+ """
166
+ Sub-type categorization for generic/low-volume appeals
167
+ """
168
+
169
+ anti_pollution_works_notice = "anti_pollution_works_notice"
170
+ contaminated_land = "contaminated_land"
171
+ marine_licensing = "marine_licensing"
172
+ waste_carriers = "waste_carriers"
173
+ water_abstraction = "water_abstraction"
174
+ environmental_liability = "environmental_liability"
175
+ environmental_permitting = "environmental_permitting"
176
+ hazardous_substances = "hazardous_substances"
177
+ silage_and_slurry = "silage_and_slurry"
178
+ sssi = "sssi"
179
+ affordable_housing = "affordable_housing"
180
+ NoneType_None = None
181
+
182
+
183
+ class LinkedCaseStatus(Enum):
184
+ """
185
+ Indicates if the case is linked, and the type of relationship
186
+ """
187
+
188
+ lead = "lead"
189
+ child = "child"
190
+ NoneType_None = None
191
+
192
+
193
+ class EnvironmentalPermitSubtypes(Enum):
194
+ """
195
+ Case sub-division applying to Environmental Permitting caseSubType
196
+ """
197
+
198
+ refusal_of_a_permit = "refusal_of_a_permit"
199
+ deemed_refusal = "deemed_refusal"
200
+ conditions_attached_to_a_permit = "conditions_attached_to_a_permit"
201
+ decision_to_impose_conditions_by_regulator = (
202
+ "decision_to_impose_conditions_by_regulator"
203
+ )
204
+ deemed_withdrawal = "deemed_withdrawal"
205
+ enforcement_notice = "enforcement_notice"
206
+ suspension_notice = "suspension_notice"
207
+ closure_notice = "closure_notice"
208
+ flood_risk_activity = "flood_risk_activity"
209
+ revocation_notice = "revocation_notice"
210
+ prohibition_notice = "prohibition_notice"
211
+ NoneType_None = None
212
+
213
+
214
+ class AppealGroupCCase(BaseModel):
215
+ """
216
+ Group C - Schema defining the metadata for generic and low-volume appeals
217
+ """
218
+
219
+ model_config = ConfigDict(
220
+ extra="allow",
221
+ )
222
+ caseId: int | None = Field(..., examples=[6000001])
223
+ """
224
+ Internal case identifier
225
+ """
226
+ caseReference: constr(pattern=r"^6\d{6}$") = Field(..., examples=["6000001"])
227
+ """
228
+ External case identifier for Group C appeals (7 digit number starting in 6)
229
+ """
230
+ caseType: CaseType
231
+ """
232
+ The internal letter code for an appeal type, e.g. W (Environmental)
233
+ """
234
+ caseStatus: CaseStatus
235
+ """
236
+ The processing status for the appeal
237
+ """
238
+ caseProcedure: CaseProcedure | None
239
+ """
240
+ The type of procedure for the appeal
241
+ """
242
+ caseCreatedDate: AwareDatetime = Field(..., examples=["2026-07-27T20:30:00.000Z"])
243
+ """
244
+ The date the appeal was received
245
+ """
246
+ caseSubmittedDate: AwareDatetime | None = Field(
247
+ ..., examples=["2026-07-27T20:30:00.000Z"]
248
+ )
249
+ """
250
+ The date the appeal was submitted by the appellant
251
+ """
252
+ caseUpdatedDate: AwareDatetime | None = Field(
253
+ ..., examples=["2026-07-27T20:30:00.000Z"]
254
+ )
255
+ """
256
+ The date the appeal was last updated in the back-office
257
+ """
258
+ caseValidDate: AwareDatetime | None = Field(
259
+ ..., examples=["2026-07-27T20:30:00.000Z"]
260
+ )
261
+ """
262
+ The date since when the appeal was considered valid
263
+ """
264
+ caseValidationDate: AwareDatetime | None = Field(
265
+ ..., examples=["2026-07-27T20:30:00.000Z"]
266
+ )
267
+ """
268
+ The date the appeal was validated in the back-office
269
+ """
270
+ caseValidationOutcome: CaseValidationOutcome | None
271
+ """
272
+ The outcome of the validation action
273
+ """
274
+ caseStartedDate: AwareDatetime | None = Field(
275
+ ..., examples=["2026-07-27T20:30:00.000Z"]
276
+ )
277
+ """
278
+ A date indicating when the case was started, resulting in the creation of a timetable
279
+ """
280
+ casePublishedDate: AwareDatetime | None = Field(
281
+ ..., examples=["2026-07-27T20:30:00.000Z"]
282
+ )
283
+ """
284
+ A date indicating when the case was published
285
+ """
286
+ lpaQuestionnaireCreatedDate: AwareDatetime | None = Field(
287
+ ..., examples=["2026-07-27T20:30:00.000Z"]
288
+ )
289
+ """
290
+ The date the LPA response was received
291
+ """
292
+ lpaQuestionnaireSubmittedDate: AwareDatetime | None = Field(
293
+ ..., examples=["2026-07-27T20:30:00.000Z"]
294
+ )
295
+ """
296
+ The date the LPA provided a response to the case
297
+ """
298
+ lpaQuestionnaireValidationOutcome: LpaQuestionnaireValidationOutcome | None
299
+ """
300
+ The outcome of the LPA questionnaire validation action
301
+ """
302
+ lpaQuestionnaireDueDate: AwareDatetime | None = Field(
303
+ ..., examples=["2026-07-27T20:30:00.000Z"]
304
+ )
305
+ """
306
+ If the case is started and has a timetable, a deadline for the LPA to provide a response
307
+ """
308
+ caseDecisionOutcomeDate: AwareDatetime | None = Field(
309
+ ..., examples=["2026-07-27T20:30:00.000Z"]
310
+ )
311
+ """
312
+ The date of the appeal decision
313
+ """
314
+ caseDecisionOutcome: CaseDecisionOutcome | None
315
+ """
316
+ The final outcome for the decision
317
+ """
318
+ caseCompletedDate: AwareDatetime | None = Field(
319
+ ..., examples=["2026-07-27T20:30:00.000Z"]
320
+ )
321
+ """
322
+ The date the appeal decision letter was issued
323
+ """
324
+ lpaCode: str | None = Field(..., examples=["Q9999"])
325
+ """
326
+ A unique identifier for the Local Planning Authority
327
+ """
328
+ caseOfficerId: str | None
329
+ """
330
+ Unique identifier for the case officer assigned to the case
331
+ """
332
+ inspectorId: str | None
333
+ """
334
+ Unique identifier for the inspector assigned to the case
335
+ """
336
+ padsSapId: str | None
337
+ """
338
+ padsSapId for PADS inspectors
339
+ """
340
+ allocationLevel: AllocationLevel | None
341
+ """
342
+ A level used for allocation purposes
343
+ """
344
+ allocationBand: AllocationBand | None
345
+ """
346
+ A band used for allocation purposes
347
+ """
348
+ caseSpecialisms: list[str] | None = Field(..., examples=[["Environmental", "SSSI"]])
349
+ """
350
+ A list of specialisms for allocation purposes
351
+ """
352
+ siteAddressLine1: str | None = Field(..., examples=["96 The Avenue"])
353
+ """
354
+ First line of address for the appeal site
355
+ """
356
+ siteAddressLine2: str | None
357
+ """
358
+ Second line of address for the appeal site
359
+ """
360
+ siteAddressTown: str | None = Field(..., examples=["Maidstone"])
361
+ """
362
+ Town / City of the site address
363
+ """
364
+ siteAddressCounty: str | None = Field(..., examples=["Kent"])
365
+ """
366
+ County of the site address
367
+ """
368
+ siteAddressPostcode: str | None = Field(..., examples=["MD21 5XY"])
369
+ """
370
+ Postal code of the site address
371
+ """
372
+ caseManagementConferenceDate: AwareDatetime | None = Field(
373
+ None, examples=["2026-07-27T20:30:00.000Z"]
374
+ )
375
+ """
376
+ The date of the Case Management Conference (CMC)
377
+ """
378
+ statementDueDate: AwareDatetime | None = Field(
379
+ None, examples=["2026-07-27T20:30:00.000Z"]
380
+ )
381
+ """
382
+ Deadline for statements
383
+ """
384
+ proofsOfEvidenceDueDate: AwareDatetime | None = Field(
385
+ None, examples=["2026-07-27T20:30:00.000Z"]
386
+ )
387
+ """
388
+ Deadline for proofs of evidence
389
+ """
390
+ finalCommentsDueDate: AwareDatetime | None = Field(
391
+ None, examples=["2026-07-27T20:30:00.000Z"]
392
+ )
393
+ """
394
+ Deadline for final comments
395
+ """
396
+ interestedPartyRepsDueDate: AwareDatetime | None = Field(
397
+ None, examples=["2026-07-27T20:30:00.000Z"]
398
+ )
399
+ """
400
+ Deadline for interested party representations
401
+ """
402
+ statementOfCommonGroundDueDate: AwareDatetime | None = Field(
403
+ None, examples=["2026-07-27T20:30:00.000Z"]
404
+ )
405
+ """
406
+ Deadline for statement of common ground
407
+ """
408
+ planningObligationDueDate: AwareDatetime | None = Field(
409
+ None, examples=["2026-07-27T20:30:00.000Z"]
410
+ )
411
+ """
412
+ Deadline for planning obligation
413
+ """
414
+ typeOfPlanningApplication: TypeOfPlanningApplication | None = None
415
+ """
416
+ The type of application or notice that is the subject of the appeal
417
+ """
418
+ caseSubType: CaseSubType | None = None
419
+ """
420
+ Sub-type categorization for generic/low-volume appeals
421
+ """
422
+ caseWithdrawnDate: AwareDatetime | None = Field(
423
+ ..., examples=["2026-07-27T20:30:00.000Z"]
424
+ )
425
+ """
426
+ The date the appeal was withdrawn by the appellant
427
+ """
428
+ caseTransferredDate: AwareDatetime | None = Field(
429
+ ..., examples=["2026-07-27T20:30:00.000Z"]
430
+ )
431
+ """
432
+ The date the appeal was transferred to a new case of a different type
433
+ """
434
+ enforcementNoticeReference: str | None = Field(None, examples=["myC45e-123"])
435
+ """
436
+ The reference number of the enforcement notice
437
+ """
438
+ applicationReference: str | None = Field(None, examples=["43010/APP/1/290572"])
439
+ """
440
+ The unique identifier of the LPA or regulator application
441
+ """
442
+ linkedCaseStatus: LinkedCaseStatus | None = None
443
+ """
444
+ Indicates if the case is linked, and the type of relationship
445
+ """
446
+ leadCaseReference: str | None = Field(None, examples=["6000001"])
447
+ """
448
+ The reference of the lead case, if the case is a child case
449
+ """
450
+ environmentalPermitSubtypes: EnvironmentalPermitSubtypes | None = None
451
+ """
452
+ Case sub-division applying to Environmental Permitting caseSubType
453
+ """
@@ -141,6 +141,7 @@ class CaseDecisionOutcome(Enum):
141
141
  planning_permission_granted = "planning_permission_granted"
142
142
  quashed_on_legal_grounds = "quashed_on_legal_grounds"
143
143
  notice_varied_and_upheld = "notice_varied_and_upheld"
144
+ notice_quashed = "notice_quashed"
144
145
  NoneType_None = None
145
146
 
146
147
 
@@ -288,6 +289,13 @@ class TypeOfPlanningApplication(Enum):
288
289
  lawful_development_certificate = "lawful-development-certificate"
289
290
  discontinuance_notice = "discontinuance-notice"
290
291
  permission_in_principle = "permission-in-principle"
292
+ tree_preservation_order = "tree-preservation-order"
293
+ tree_replacement_notice = "tree-replacement-notice"
294
+ high_hedge_appeal = "high-hedge-appeal"
295
+ hedgerows_appeal = "hedgerows-appeal"
296
+ community_infrastructure_levy = "community-infrastructure-levy"
297
+ planning_obligation = "planning-obligation"
298
+ environmental = "environmental"
291
299
  NoneType_None = None
292
300
 
293
301
 
@@ -137,6 +137,7 @@
137
137
  "documentType": {
138
138
  "type": ["string", "null"],
139
139
  "enum": [
140
+ "appellantCase",
140
141
  "appellantCaseCorrespondence",
141
142
  "appellantCaseWithdrawalLetter",
142
143
  "appellantCostsApplication",
@@ -151,6 +152,7 @@
151
152
  "whoNotifiedLetterToNeighbours",
152
153
  "whoNotifiedPressAdvert",
153
154
  "conservationMap",
155
+ "lpaQuestionnaire",
154
156
  "lpaCaseCorrespondence",
155
157
  "lpaCostsApplication",
156
158
  "lpaCostsCorrespondence",