@planning-inspectorate/data-model 2.28.1 → 2.30.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 (37) hide show
  1. package/docs/appeal-document.md +3 -0
  2. package/docs/appeal-s78-if.md +35 -0
  3. package/docs/appeal-s78-then.md +31 -0
  4. package/docs/appeal-s78.md +71 -2
  5. package/package.json +1 -1
  6. package/pins_data_model/models/model_appeal_document.py +4 -1
  7. package/pins_data_model/models/model_appeal_event.py +1 -1
  8. package/pins_data_model/models/model_appeal_event_estimate.py +1 -1
  9. package/pins_data_model/models/model_appeal_has.py +1 -1
  10. package/pins_data_model/models/model_appeal_representation.py +1 -1
  11. package/pins_data_model/models/model_appeal_s78.py +27 -5
  12. package/pins_data_model/models/model_dart_response.py +1 -1
  13. package/pins_data_model/models/model_entraid.py +1 -1
  14. package/pins_data_model/models/model_folder.py +1 -1
  15. package/pins_data_model/models/model_gettimesheets_response.py +1 -1
  16. package/pins_data_model/models/model_listed_building.py +1 -1
  17. package/pins_data_model/models/model_listed_buildings.py +1 -1
  18. package/pins_data_model/models/model_nsip_document.py +1 -1
  19. package/pins_data_model/models/model_nsip_exam_timetable.py +1 -1
  20. package/pins_data_model/models/model_nsip_invoice.py +1 -1
  21. package/pins_data_model/models/model_nsip_meeting.py +1 -1
  22. package/pins_data_model/models/model_nsip_project.py +1 -1
  23. package/pins_data_model/models/model_nsip_project_update.py +1 -1
  24. package/pins_data_model/models/model_nsip_representation.py +1 -1
  25. package/pins_data_model/models/model_nsip_subscription.py +1 -1
  26. package/pins_data_model/models/model_pins_inspector.py +1 -1
  27. package/pins_data_model/models/model_pins_lpa.py +1 -1
  28. package/pins_data_model/models/model_s51_advice.py +1 -1
  29. package/pins_data_model/models/model_service_user.py +1 -1
  30. package/schemas/appeal-document.schema.json +3 -0
  31. package/schemas/appeal-s78.schema.json +24 -2
  32. package/src/enums.cjs +25 -0
  33. package/src/enums.d.ts +23 -0
  34. package/src/enums.js +23 -0
  35. package/src/index.cjs +25 -0
  36. package/src/schemas.d.ts +16 -2
  37. package/tests/appeals/appeal-s78.test.js +21 -1
@@ -607,6 +607,7 @@ The type of document, used for exchange, migrations and consumption from the app
607
607
  | `"planningPermission"` | |
608
608
  | `"lpaEnforcementNotice"` | |
609
609
  | `"lpaEnforcementNoticePlan"` | |
610
+ | `"lpaEnforcementNoticeWithdrawal"` | |
610
611
  | `"planningContraventionNotice"` | |
611
612
  | `"priorCorrespondenceWithPINS"` | |
612
613
  | `"enforcementNotice"` | |
@@ -626,6 +627,7 @@ The type of document, used for exchange, migrations and consumption from the app
626
627
  | `"groundISupporting"` | |
627
628
  | `"groundJSupporting"` | |
628
629
  | `"groundKSupporting"` | |
630
+ | `"discontinuanceNotice"` | |
629
631
  | `null` | |
630
632
 
631
633
  ## sourceSystem
@@ -778,6 +780,7 @@ The stage in the appeal process that has created the document
778
780
  | `"appeal-decision"` | |
779
781
  | `"costs"` | |
780
782
  | `"internal"` | |
783
+ | `"cancellation"` | |
781
784
  | `null` | |
782
785
 
783
786
  ## horizonFolderId
@@ -0,0 +1,35 @@
1
+ ## if Type
2
+
3
+ unknown
4
+
5
+ # if Properties
6
+
7
+ | Property | Type | Required | Nullable | Defined by |
8
+ | :-------------------------------------------------------------------- | :------------ | :------- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
9
+ | [discontinuanceNoticeServedReason](#discontinuancenoticeservedreason) | Not specified | Optional | cannot be null | [Appeal S78 Case](appeal-s78-if-properties-discontinuancenoticeservedreason.md "appeal-s78.schema.json#/if/properties/discontinuanceNoticeServedReason") |
10
+
11
+ ## discontinuanceNoticeServedReason
12
+
13
+
14
+
15
+ `discontinuanceNoticeServedReason`
16
+
17
+ * is optional
18
+
19
+ * Type: unknown
20
+
21
+ * cannot be null
22
+
23
+ * defined in: [Appeal S78 Case](appeal-s78-if-properties-discontinuancenoticeservedreason.md "appeal-s78.schema.json#/if/properties/discontinuanceNoticeServedReason")
24
+
25
+ ### discontinuanceNoticeServedReason Type
26
+
27
+ unknown
28
+
29
+ ### discontinuanceNoticeServedReason Constraints
30
+
31
+ **constant**: the value of this property must be equal to:
32
+
33
+ ```json
34
+ "other"
35
+ ```
@@ -0,0 +1,31 @@
1
+ ## then Type
2
+
3
+ unknown
4
+
5
+ # then Properties
6
+
7
+ | Property | Type | Required | Nullable | Defined by |
8
+ | :------------------------------------------------------------------------------ | :------- | :------- | :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
9
+ | [discontinuanceNoticeServedOtherReason](#discontinuancenoticeservedotherreason) | `string` | Optional | cannot be null | [Appeal S78 Case](appeal-s78-then-properties-discontinuancenoticeservedotherreason.md "appeal-s78.schema.json#/then/properties/discontinuanceNoticeServedOtherReason") |
10
+
11
+ ## discontinuanceNoticeServedOtherReason
12
+
13
+
14
+
15
+ `discontinuanceNoticeServedOtherReason`
16
+
17
+ * is optional
18
+
19
+ * Type: `string`
20
+
21
+ * cannot be null
22
+
23
+ * defined in: [Appeal S78 Case](appeal-s78-then-properties-discontinuancenoticeservedotherreason.md "appeal-s78.schema.json#/then/properties/discontinuanceNoticeServedOtherReason")
24
+
25
+ ### discontinuanceNoticeServedOtherReason Type
26
+
27
+ `string`
28
+
29
+ ### discontinuanceNoticeServedOtherReason Constraints
30
+
31
+ **minimum length**: the minimum number of characters for this string is: `1`
@@ -200,6 +200,9 @@ any of
200
200
  | [appealUnderActSection](#appealunderactsection) | `string` | Optional | can be null | [Appeal S78 Case](appeal-s78-properties-appealunderactsection.md "appeal-s78.schema.json#/properties/appealUnderActSection") |
201
201
  | [lpaConsiderAppealInvalid](#lpaconsiderappealinvalid) | `boolean` | Optional | can be null | [Appeal S78 Case](appeal-s78-properties-lpaconsiderappealinvalid.md "appeal-s78.schema.json#/properties/lpaConsiderAppealInvalid") |
202
202
  | [lpaAppealInvalidReasons](#lpaappealinvalidreasons) | `string` | Optional | can be null | [Appeal S78 Case](appeal-s78-properties-lpaappealinvalidreasons.md "appeal-s78.schema.json#/properties/lpaAppealInvalidReasons") |
203
+ | [discontinuanceNoticeServedReason](#discontinuancenoticeservedreason) | `string` | Optional | can be null | [Appeal S78 Case](appeal-s78-properties-discontinuancenoticeservedreason.md "appeal-s78.schema.json#/properties/discontinuanceNoticeServedReason") |
204
+ | [discontinuanceNoticeServedOtherReason](#discontinuancenoticeservedotherreason) | `string` | Optional | can be null | [Appeal S78 Case](appeal-s78-properties-discontinuancenoticeservedotherreason.md "appeal-s78.schema.json#/properties/discontinuanceNoticeServedOtherReason") |
205
+ | [wasRetrospectivePlanningApplicationMade](#wasretrospectiveplanningapplicationmade) | `boolean` | Optional | can be null | [Appeal S78 Case](appeal-s78-properties-wasretrospectiveplanningapplicationmade.md "appeal-s78.schema.json#/properties/wasRetrospectivePlanningApplicationMade") |
203
206
  | Additional Properties | Any | Optional | can be null | |
204
207
 
205
208
  ## caseId
@@ -3664,6 +3667,7 @@ The net gain in residences of the proposed development
3664
3667
  | `"minor-commercial-development"` | |
3665
3668
  | `"advertisement"` | |
3666
3669
  | `"lawful-development-certificate"` | |
3670
+ | `"discontinuance-notice"` | |
3667
3671
  | `null` | |
3668
3672
 
3669
3673
  ## developmentType
@@ -4205,7 +4209,7 @@ Was planning permission granted in relation to a prior application
4205
4209
 
4206
4210
  ## issueDateOfEnforcementNotice
4207
4211
 
4208
- The date on which an enforcement notice was issued
4212
+ The date on which an Enforcement Notice or Discontinuance Notice was issued
4209
4213
 
4210
4214
  `issueDateOfEnforcementNotice`
4211
4215
 
@@ -4233,7 +4237,7 @@ The date on which an enforcement notice was issued
4233
4237
 
4234
4238
  ## effectiveDateOfEnforcementNotice
4235
4239
 
4236
- The effective date of an enforcement notice
4240
+ The effective date of an Enforcement Notice or Discontinuance Notice
4237
4241
 
4238
4242
  `effectiveDateOfEnforcementNotice`
4239
4243
 
@@ -4737,6 +4741,71 @@ Reason(s) why LPA consider the appeal invalid
4737
4741
 
4738
4742
  `string`
4739
4743
 
4744
+ ## discontinuanceNoticeServedReason
4745
+
4746
+
4747
+
4748
+ `discontinuanceNoticeServedReason`
4749
+
4750
+ * is optional
4751
+
4752
+ * Type: `string`
4753
+
4754
+ * can be null
4755
+
4756
+ * defined in: [Appeal S78 Case](appeal-s78-properties-discontinuancenoticeservedreason.md "appeal-s78.schema.json#/properties/discontinuanceNoticeServedReason")
4757
+
4758
+ ### discontinuanceNoticeServedReason Type
4759
+
4760
+ `string`
4761
+
4762
+ ### discontinuanceNoticeServedReason Constraints
4763
+
4764
+ **enum**: the value of this property must be equal to one of the following values:
4765
+
4766
+ | Value | Explanation |
4767
+ | :-------------------------------------------- | :---------- |
4768
+ | `"risk-of-injury-to-the-amenity-of-locality"` | |
4769
+ | `"danger-to-members-of-the-public"` | |
4770
+ | `"other"` | |
4771
+ | `null` | |
4772
+
4773
+ ## discontinuanceNoticeServedOtherReason
4774
+
4775
+ Other reason for serving a discontinuance notice, for discontinuanceNoticeServedReason: other
4776
+
4777
+ `discontinuanceNoticeServedOtherReason`
4778
+
4779
+ * is optional
4780
+
4781
+ * Type: `string`
4782
+
4783
+ * can be null
4784
+
4785
+ * defined in: [Appeal S78 Case](appeal-s78-properties-discontinuancenoticeservedotherreason.md "appeal-s78.schema.json#/properties/discontinuanceNoticeServedOtherReason")
4786
+
4787
+ ### discontinuanceNoticeServedOtherReason Type
4788
+
4789
+ `string`
4790
+
4791
+ ## wasRetrospectivePlanningApplicationMade
4792
+
4793
+
4794
+
4795
+ `wasRetrospectivePlanningApplicationMade`
4796
+
4797
+ * is optional
4798
+
4799
+ * Type: `boolean`
4800
+
4801
+ * can be null
4802
+
4803
+ * defined in: [Appeal S78 Case](appeal-s78-properties-wasretrospectiveplanningapplicationmade.md "appeal-s78.schema.json#/properties/wasRetrospectivePlanningApplicationMade")
4804
+
4805
+ ### wasRetrospectivePlanningApplicationMade Type
4806
+
4807
+ `boolean`
4808
+
4740
4809
  ## Additional Properties
4741
4810
 
4742
4811
  Additional properties are allowed and do not have to follow a specific schema
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planning-inspectorate/data-model",
3
- "version": "2.28.1",
3
+ "version": "2.30.0",
4
4
  "description": "JSON Schemas for the Planning Inspectorate's Data Model",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: appeal-document.schema.json
3
- # timestamp: 2026-03-05T13:03:23+00:00
3
+ # timestamp: 2026-03-17T18:45:49+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -129,6 +129,7 @@ class DocumentType(Enum):
129
129
  planningPermission = "planningPermission"
130
130
  lpaEnforcementNotice = "lpaEnforcementNotice"
131
131
  lpaEnforcementNoticePlan = "lpaEnforcementNoticePlan"
132
+ lpaEnforcementNoticeWithdrawal = "lpaEnforcementNoticeWithdrawal"
132
133
  planningContraventionNotice = "planningContraventionNotice"
133
134
  priorCorrespondenceWithPINS = "priorCorrespondenceWithPINS"
134
135
  enforcementNotice = "enforcementNotice"
@@ -148,6 +149,7 @@ class DocumentType(Enum):
148
149
  groundISupporting = "groundISupporting"
149
150
  groundJSupporting = "groundJSupporting"
150
151
  groundKSupporting = "groundKSupporting"
152
+ discontinuanceNotice = "discontinuanceNotice"
151
153
  NoneType_None = None
152
154
 
153
155
 
@@ -190,6 +192,7 @@ class CaseStage(Enum):
190
192
  appeal_decision = "appeal-decision"
191
193
  costs = "costs"
192
194
  internal = "internal"
195
+ cancellation = "cancellation"
193
196
  NoneType_None = None
194
197
 
195
198
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: appeal-event.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: appeal-event-estimate.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: appeal-has.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: appeal-representation.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: appeal-s78.schema.json
3
- # timestamp: 2026-03-05T13:03:23+00:00
3
+ # timestamp: 2026-03-17T18:45:48+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -284,6 +284,7 @@ class TypeOfPlanningApplication(Enum):
284
284
  minor_commercial_development = "minor-commercial-development"
285
285
  advertisement = "advertisement"
286
286
  lawful_development_certificate = "lawful-development-certificate"
287
+ discontinuance_notice = "discontinuance-notice"
287
288
  NoneType_None = None
288
289
 
289
290
 
@@ -416,6 +417,15 @@ class AppealUnderActSection(Enum):
416
417
  NoneType_None = None
417
418
 
418
419
 
420
+ class DiscontinuanceNoticeServedReason(Enum):
421
+ risk_of_injury_to_the_amenity_of_locality = (
422
+ "risk-of-injury-to-the-amenity-of-locality"
423
+ )
424
+ danger_to_members_of_the_public = "danger-to-members-of-the-public"
425
+ other = "other"
426
+ NoneType_None = None
427
+
428
+
419
429
  class AppealS78Case1(BaseModel):
420
430
  """
421
431
  Group B - Schema defining the metadata for an appeal
@@ -1085,13 +1095,13 @@ class AppealS78Case1(BaseModel):
1085
1095
  None, examples=["2023-07-27T20:30:00.000Z"]
1086
1096
  )
1087
1097
  """
1088
- The date on which an enforcement notice was issued
1098
+ The date on which an Enforcement Notice or Discontinuance Notice was issued
1089
1099
  """
1090
1100
  effectiveDateOfEnforcementNotice: AwareDatetime | None = Field(
1091
1101
  None, examples=["2023-07-27T20:30:00.000Z"]
1092
1102
  )
1093
1103
  """
1094
- The effective date of an enforcement notice
1104
+ The effective date of an Enforcement Notice or Discontinuance Notice
1095
1105
  """
1096
1106
  didAppellantAppealLpaDecision: bool | None = None
1097
1107
  """
@@ -1147,6 +1157,12 @@ class AppealS78Case1(BaseModel):
1147
1157
  """
1148
1158
  Reason(s) why LPA consider the appeal invalid
1149
1159
  """
1160
+ discontinuanceNoticeServedReason: DiscontinuanceNoticeServedReason | None = None
1161
+ discontinuanceNoticeServedOtherReason: str | None = None
1162
+ """
1163
+ Other reason for serving a discontinuance notice, for discontinuanceNoticeServedReason: other
1164
+ """
1165
+ wasRetrospectivePlanningApplicationMade: bool | None = None
1150
1166
 
1151
1167
 
1152
1168
  class AdvertDetail1(BaseModel):
@@ -1887,13 +1903,13 @@ class AppealS78Case2(BaseModel):
1887
1903
  None, examples=["2023-07-27T20:30:00.000Z"]
1888
1904
  )
1889
1905
  """
1890
- The date on which an enforcement notice was issued
1906
+ The date on which an Enforcement Notice or Discontinuance Notice was issued
1891
1907
  """
1892
1908
  effectiveDateOfEnforcementNotice: AwareDatetime | None = Field(
1893
1909
  None, examples=["2023-07-27T20:30:00.000Z"]
1894
1910
  )
1895
1911
  """
1896
- The effective date of an enforcement notice
1912
+ The effective date of an Enforcement Notice or Discontinuance Notice
1897
1913
  """
1898
1914
  didAppellantAppealLpaDecision: bool | None = None
1899
1915
  """
@@ -1949,6 +1965,12 @@ class AppealS78Case2(BaseModel):
1949
1965
  """
1950
1966
  Reason(s) why LPA consider the appeal invalid
1951
1967
  """
1968
+ discontinuanceNoticeServedReason: DiscontinuanceNoticeServedReason | None = None
1969
+ discontinuanceNoticeServedOtherReason: str | None = None
1970
+ """
1971
+ Other reason for serving a discontinuance notice, for discontinuanceNoticeServedReason: other
1972
+ """
1973
+ wasRetrospectivePlanningApplicationMade: bool | None = None
1952
1974
 
1953
1975
 
1954
1976
  class AppealS78Case(RootModel[AppealS78Case1 | AppealS78Case2]):
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: dart-response.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: entraid.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: folder.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: gettimesheets-response.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: listed-building.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: listed-buildings.schema.json
3
- # timestamp: 2026-03-05T13:03:23+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: nsip-document.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: nsip-exam-timetable.schema.json
3
- # timestamp: 2026-03-05T13:03:23+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: nsip-invoice.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: nsip-meeting.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: nsip-project.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: nsip-project-update.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: nsip-representation.schema.json
3
- # timestamp: 2026-03-05T13:03:23+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: nsip-subscription.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: pins-inspector.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: pins-lpa.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: s51-advice.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: service-user.schema.json
3
- # timestamp: 2026-03-05T13:03:22+00:00
3
+ # timestamp: 2026-03-06T13:54:17+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -207,6 +207,7 @@
207
207
  "planningPermission",
208
208
  "lpaEnforcementNotice",
209
209
  "lpaEnforcementNoticePlan",
210
+ "lpaEnforcementNoticeWithdrawal",
210
211
  "planningContraventionNotice",
211
212
  "priorCorrespondenceWithPINS",
212
213
  "enforcementNotice",
@@ -226,6 +227,7 @@
226
227
  "groundISupporting",
227
228
  "groundJSupporting",
228
229
  "groundKSupporting",
230
+ "discontinuanceNotice",
229
231
  null
230
232
  ],
231
233
  "description": "The type of document, used for exchange, migrations and consumption from the appeal back-office system"
@@ -265,6 +267,7 @@
265
267
  "appeal-decision",
266
268
  "costs",
267
269
  "internal",
270
+ "cancellation",
268
271
  null
269
272
  ],
270
273
  "description": "The stage in the appeal process that has created the document",
@@ -151,6 +151,16 @@
151
151
  }
152
152
  }
153
153
  ],
154
+ "if": {
155
+ "properties": {
156
+ "discontinuanceNoticeServedReason": { "const": "other" }
157
+ }
158
+ },
159
+ "then": {
160
+ "properties": {
161
+ "discontinuanceNoticeServedOtherReason": { "type": "string", "minLength": 1 }
162
+ }
163
+ },
154
164
  "properties": {
155
165
  "caseId": {
156
166
  "type": ["integer", "null"],
@@ -1035,6 +1045,7 @@
1035
1045
  "minor-commercial-development",
1036
1046
  "advertisement",
1037
1047
  "lawful-development-certificate",
1048
+ "discontinuance-notice",
1038
1049
  null
1039
1050
  ]
1040
1051
  },
@@ -1234,13 +1245,13 @@
1234
1245
  "issueDateOfEnforcementNotice": {
1235
1246
  "type": ["string", "null"],
1236
1247
  "format": "date-time",
1237
- "description": "The date on which an enforcement notice was issued",
1248
+ "description": "The date on which an Enforcement Notice or Discontinuance Notice was issued",
1238
1249
  "examples": ["2023-07-27T20:30:00.000Z"]
1239
1250
  },
1240
1251
  "effectiveDateOfEnforcementNotice": {
1241
1252
  "type": ["string", "null"],
1242
1253
  "format": "date-time",
1243
- "description": "The effective date of an enforcement notice",
1254
+ "description": "The effective date of an Enforcement Notice or Discontinuance Notice",
1244
1255
  "examples": ["2023-07-27T20:30:00.000Z"]
1245
1256
  },
1246
1257
  "didAppellantAppealLpaDecision": {
@@ -1329,6 +1340,17 @@
1329
1340
  "lpaAppealInvalidReasons": {
1330
1341
  "type": ["string", "null"],
1331
1342
  "description": "Reason(s) why LPA consider the appeal invalid"
1343
+ },
1344
+ "discontinuanceNoticeServedReason": {
1345
+ "type": ["string", "null"],
1346
+ "enum": ["risk-of-injury-to-the-amenity-of-locality", "danger-to-members-of-the-public", "other", null]
1347
+ },
1348
+ "discontinuanceNoticeServedOtherReason": {
1349
+ "type": ["string", "null"],
1350
+ "description": "Other reason for serving a discontinuance notice, for discontinuanceNoticeServedReason: other"
1351
+ },
1352
+ "wasRetrospectivePlanningApplicationMade": {
1353
+ "type": ["boolean", "null"]
1332
1354
  }
1333
1355
  }
1334
1356
  }
package/src/enums.cjs CHANGED
@@ -29,6 +29,19 @@ const APPEAL_HAS_CASE_STATUS = Object.freeze({
29
29
  WITHDRAWN: 'withdrawn',
30
30
  });
31
31
 
32
+ const APPEAL_HAS_TYPE_OF_PLANNING_APPLICATION = Object.freeze({
33
+ ADVERTISEMENT: 'advertisement',
34
+ FULL_APPEAL: 'full-appeal',
35
+ HOUSEHOLDER_PLANNING: 'householder-planning',
36
+ LAWFUL_DEVELOPMENT_CERTIFICATE: 'lawful-development-certificate',
37
+ LISTED_BUILDING: 'listed-building',
38
+ MINOR_COMMERCIAL_DEVELOPMENT: 'minor-commercial-development',
39
+ OUTLINE_PLANNING: 'outline-planning',
40
+ PRIOR_APPROVAL: 'prior-approval',
41
+ REMOVAL_OR_VARIATION_OF_CONDITIONS: 'removal-or-variation-of-conditions',
42
+ RESERVED_MATTERS: 'reserved-matters',
43
+ });
44
+
32
45
  const APPEAL_ALLOCATION_LEVEL = Object.freeze({
33
46
  A: 'A',
34
47
  B: 'B',
@@ -90,6 +103,7 @@ const APPEAL_CASE_PROCEDURE = Object.freeze({
90
103
  const APPEAL_CASE_STAGE = Object.freeze({
91
104
  APPEAL_DECISION: 'appeal-decision',
92
105
  APPELLANT_CASE: 'appellant-case',
106
+ CANCELLATION: 'cancellation',
93
107
  COSTS: 'costs',
94
108
  EVIDENCE: 'evidence',
95
109
  FINAL_COMMENTS: 'final-comments',
@@ -162,6 +176,12 @@ const APPEAL_DEVELOPMENT_TYPE = Object.freeze({
162
176
  OTHER_MINOR: 'other-minor',
163
177
  });
164
178
 
179
+ const APPEAL_DISCONTINUANCE_NOTICE_SERVED_REASON = Object.freeze({
180
+ DANGER_TO_MEMBERS_OF_THE_PUBLIC: 'danger-to-members-of-the-public',
181
+ OTHER: 'other',
182
+ RISK_OF_INJURY_TO_THE_AMENITY_OF_LOCALITY: 'risk-of-injury-to-the-amenity-of-locality',
183
+ });
184
+
165
185
  const APPEAL_DOCUMENT_TYPE = Object.freeze({
166
186
  APPEAL_NOTIFICATION: 'appealNotification',
167
187
  APPELLANT_CASE_CORRESPONDENCE: 'appellantCaseCorrespondence',
@@ -188,6 +208,7 @@ const APPEAL_DOCUMENT_TYPE = Object.freeze({
188
208
  DELEGATED_REPORT: 'delegatedReport',
189
209
  DESIGN_ACCESS_STATEMENT: 'designAccessStatement',
190
210
  DEVELOPMENT_PLAN_POLICIES: 'developmentPlanPolicies',
211
+ DISCONTINUANCE_NOTICE: 'discontinuanceNotice',
191
212
  EIA_ENVIRONMENTAL_STATEMENT: 'eiaEnvironmentalStatement',
192
213
  EIA_SCOPING_OPINION: 'eiaScopingOpinion',
193
214
  EIA_SCREENING_DIRECTION: 'eiaScreeningDirection',
@@ -220,6 +241,7 @@ const APPEAL_DOCUMENT_TYPE = Object.freeze({
220
241
  LPA_COSTS_WITHDRAWAL: 'lpaCostsWithdrawal',
221
242
  LPA_ENFORCEMENT_NOTICE: 'lpaEnforcementNotice',
222
243
  LPA_ENFORCEMENT_NOTICE_PLAN: 'lpaEnforcementNoticePlan',
244
+ LPA_ENFORCEMENT_NOTICE_WITHDRAWAL: 'lpaEnforcementNoticeWithdrawal',
223
245
  LPA_FINAL_COMMENT: 'lpaFinalComment',
224
246
  LPA_PROOF_OF_EVIDENCE: 'lpaProofOfEvidence',
225
247
  LPA_STATEMENT: 'lpaStatement',
@@ -391,6 +413,7 @@ const APPEAL_SOURCE_SYSTEM = Object.freeze({
391
413
 
392
414
  const APPEAL_TYPE_OF_PLANNING_APPLICATION = Object.freeze({
393
415
  ADVERTISEMENT: 'advertisement',
416
+ DISCONTINUANCE_NOTICE: 'discontinuance-notice',
394
417
  FULL_APPEAL: 'full-appeal',
395
418
  HOUSEHOLDER_PLANNING: 'householder-planning',
396
419
  LAWFUL_DEVELOPMENT_CERTIFICATE: 'lawful-development-certificate',
@@ -796,6 +819,7 @@ exports.APPEAL_CASE_STATUS = APPEAL_CASE_STATUS;
796
819
  exports.APPEAL_CASE_TYPE = APPEAL_CASE_TYPE;
797
820
  exports.APPEAL_CASE_VALIDATION_OUTCOME = APPEAL_CASE_VALIDATION_OUTCOME;
798
821
  exports.APPEAL_DEVELOPMENT_TYPE = APPEAL_DEVELOPMENT_TYPE;
822
+ exports.APPEAL_DISCONTINUANCE_NOTICE_SERVED_REASON = APPEAL_DISCONTINUANCE_NOTICE_SERVED_REASON;
799
823
  exports.APPEAL_DOCUMENT_TYPE = APPEAL_DOCUMENT_TYPE;
800
824
  exports.APPEAL_EIA_DEVELOPMENT_DESCRIPTION = APPEAL_EIA_DEVELOPMENT_DESCRIPTION;
801
825
  exports.APPEAL_EIA_ENVIRONMENTAL_IMPACT_SCHEDULE = APPEAL_EIA_ENVIRONMENTAL_IMPACT_SCHEDULE;
@@ -804,6 +828,7 @@ exports.APPEAL_EVENT_TYPE = APPEAL_EVENT_TYPE;
804
828
  exports.APPEAL_HAS_CASE_DECISION_OUTCOME = APPEAL_HAS_CASE_DECISION_OUTCOME;
805
829
  exports.APPEAL_HAS_CASE_PROCEDURE = APPEAL_HAS_CASE_PROCEDURE;
806
830
  exports.APPEAL_HAS_CASE_STATUS = APPEAL_HAS_CASE_STATUS;
831
+ exports.APPEAL_HAS_TYPE_OF_PLANNING_APPLICATION = APPEAL_HAS_TYPE_OF_PLANNING_APPLICATION;
807
832
  exports.APPEAL_INVALID_OR_INCOMPLETE_DETAILS = APPEAL_INVALID_OR_INCOMPLETE_DETAILS;
808
833
  exports.APPEAL_KNOWS_ALL_OWNERS = APPEAL_KNOWS_ALL_OWNERS;
809
834
  exports.APPEAL_KNOWS_OTHER_OWNERS = APPEAL_KNOWS_OTHER_OWNERS;
package/src/enums.d.ts CHANGED
@@ -27,6 +27,19 @@ export const APPEAL_HAS_CASE_STATUS = {
27
27
  WITHDRAWN: 'withdrawn',
28
28
  } as const;
29
29
 
30
+ export const APPEAL_HAS_TYPE_OF_PLANNING_APPLICATION = {
31
+ ADVERTISEMENT: 'advertisement',
32
+ FULL_APPEAL: 'full-appeal',
33
+ HOUSEHOLDER_PLANNING: 'householder-planning',
34
+ LAWFUL_DEVELOPMENT_CERTIFICATE: 'lawful-development-certificate',
35
+ LISTED_BUILDING: 'listed-building',
36
+ MINOR_COMMERCIAL_DEVELOPMENT: 'minor-commercial-development',
37
+ OUTLINE_PLANNING: 'outline-planning',
38
+ PRIOR_APPROVAL: 'prior-approval',
39
+ REMOVAL_OR_VARIATION_OF_CONDITIONS: 'removal-or-variation-of-conditions',
40
+ RESERVED_MATTERS: 'reserved-matters',
41
+ } as const;
42
+
30
43
  export const APPEAL_ALLOCATION_LEVEL = {
31
44
  A: 'A',
32
45
  B: 'B',
@@ -88,6 +101,7 @@ export const APPEAL_CASE_PROCEDURE = {
88
101
  export const APPEAL_CASE_STAGE = {
89
102
  APPEAL_DECISION: 'appeal-decision',
90
103
  APPELLANT_CASE: 'appellant-case',
104
+ CANCELLATION: 'cancellation',
91
105
  COSTS: 'costs',
92
106
  EVIDENCE: 'evidence',
93
107
  FINAL_COMMENTS: 'final-comments',
@@ -160,6 +174,12 @@ export const APPEAL_DEVELOPMENT_TYPE = {
160
174
  OTHER_MINOR: 'other-minor',
161
175
  } as const;
162
176
 
177
+ export const APPEAL_DISCONTINUANCE_NOTICE_SERVED_REASON = {
178
+ DANGER_TO_MEMBERS_OF_THE_PUBLIC: 'danger-to-members-of-the-public',
179
+ OTHER: 'other',
180
+ RISK_OF_INJURY_TO_THE_AMENITY_OF_LOCALITY: 'risk-of-injury-to-the-amenity-of-locality',
181
+ } as const;
182
+
163
183
  export const APPEAL_DOCUMENT_TYPE = {
164
184
  APPEAL_NOTIFICATION: 'appealNotification',
165
185
  APPELLANT_CASE_CORRESPONDENCE: 'appellantCaseCorrespondence',
@@ -186,6 +206,7 @@ export const APPEAL_DOCUMENT_TYPE = {
186
206
  DELEGATED_REPORT: 'delegatedReport',
187
207
  DESIGN_ACCESS_STATEMENT: 'designAccessStatement',
188
208
  DEVELOPMENT_PLAN_POLICIES: 'developmentPlanPolicies',
209
+ DISCONTINUANCE_NOTICE: 'discontinuanceNotice',
189
210
  EIA_ENVIRONMENTAL_STATEMENT: 'eiaEnvironmentalStatement',
190
211
  EIA_SCOPING_OPINION: 'eiaScopingOpinion',
191
212
  EIA_SCREENING_DIRECTION: 'eiaScreeningDirection',
@@ -218,6 +239,7 @@ export const APPEAL_DOCUMENT_TYPE = {
218
239
  LPA_COSTS_WITHDRAWAL: 'lpaCostsWithdrawal',
219
240
  LPA_ENFORCEMENT_NOTICE: 'lpaEnforcementNotice',
220
241
  LPA_ENFORCEMENT_NOTICE_PLAN: 'lpaEnforcementNoticePlan',
242
+ LPA_ENFORCEMENT_NOTICE_WITHDRAWAL: 'lpaEnforcementNoticeWithdrawal',
221
243
  LPA_FINAL_COMMENT: 'lpaFinalComment',
222
244
  LPA_PROOF_OF_EVIDENCE: 'lpaProofOfEvidence',
223
245
  LPA_STATEMENT: 'lpaStatement',
@@ -389,6 +411,7 @@ export const APPEAL_SOURCE_SYSTEM = {
389
411
 
390
412
  export const APPEAL_TYPE_OF_PLANNING_APPLICATION = {
391
413
  ADVERTISEMENT: 'advertisement',
414
+ DISCONTINUANCE_NOTICE: 'discontinuance-notice',
392
415
  FULL_APPEAL: 'full-appeal',
393
416
  HOUSEHOLDER_PLANNING: 'householder-planning',
394
417
  LAWFUL_DEVELOPMENT_CERTIFICATE: 'lawful-development-certificate',
package/src/enums.js CHANGED
@@ -27,6 +27,19 @@ export const APPEAL_HAS_CASE_STATUS = Object.freeze({
27
27
  WITHDRAWN: 'withdrawn',
28
28
  });
29
29
 
30
+ export const APPEAL_HAS_TYPE_OF_PLANNING_APPLICATION = Object.freeze({
31
+ ADVERTISEMENT: 'advertisement',
32
+ FULL_APPEAL: 'full-appeal',
33
+ HOUSEHOLDER_PLANNING: 'householder-planning',
34
+ LAWFUL_DEVELOPMENT_CERTIFICATE: 'lawful-development-certificate',
35
+ LISTED_BUILDING: 'listed-building',
36
+ MINOR_COMMERCIAL_DEVELOPMENT: 'minor-commercial-development',
37
+ OUTLINE_PLANNING: 'outline-planning',
38
+ PRIOR_APPROVAL: 'prior-approval',
39
+ REMOVAL_OR_VARIATION_OF_CONDITIONS: 'removal-or-variation-of-conditions',
40
+ RESERVED_MATTERS: 'reserved-matters',
41
+ });
42
+
30
43
  export const APPEAL_ALLOCATION_LEVEL = Object.freeze({
31
44
  A: 'A',
32
45
  B: 'B',
@@ -88,6 +101,7 @@ export const APPEAL_CASE_PROCEDURE = Object.freeze({
88
101
  export const APPEAL_CASE_STAGE = Object.freeze({
89
102
  APPEAL_DECISION: 'appeal-decision',
90
103
  APPELLANT_CASE: 'appellant-case',
104
+ CANCELLATION: 'cancellation',
91
105
  COSTS: 'costs',
92
106
  EVIDENCE: 'evidence',
93
107
  FINAL_COMMENTS: 'final-comments',
@@ -160,6 +174,12 @@ export const APPEAL_DEVELOPMENT_TYPE = Object.freeze({
160
174
  OTHER_MINOR: 'other-minor',
161
175
  });
162
176
 
177
+ export const APPEAL_DISCONTINUANCE_NOTICE_SERVED_REASON = Object.freeze({
178
+ DANGER_TO_MEMBERS_OF_THE_PUBLIC: 'danger-to-members-of-the-public',
179
+ OTHER: 'other',
180
+ RISK_OF_INJURY_TO_THE_AMENITY_OF_LOCALITY: 'risk-of-injury-to-the-amenity-of-locality',
181
+ });
182
+
163
183
  export const APPEAL_DOCUMENT_TYPE = Object.freeze({
164
184
  APPEAL_NOTIFICATION: 'appealNotification',
165
185
  APPELLANT_CASE_CORRESPONDENCE: 'appellantCaseCorrespondence',
@@ -186,6 +206,7 @@ export const APPEAL_DOCUMENT_TYPE = Object.freeze({
186
206
  DELEGATED_REPORT: 'delegatedReport',
187
207
  DESIGN_ACCESS_STATEMENT: 'designAccessStatement',
188
208
  DEVELOPMENT_PLAN_POLICIES: 'developmentPlanPolicies',
209
+ DISCONTINUANCE_NOTICE: 'discontinuanceNotice',
189
210
  EIA_ENVIRONMENTAL_STATEMENT: 'eiaEnvironmentalStatement',
190
211
  EIA_SCOPING_OPINION: 'eiaScopingOpinion',
191
212
  EIA_SCREENING_DIRECTION: 'eiaScreeningDirection',
@@ -218,6 +239,7 @@ export const APPEAL_DOCUMENT_TYPE = Object.freeze({
218
239
  LPA_COSTS_WITHDRAWAL: 'lpaCostsWithdrawal',
219
240
  LPA_ENFORCEMENT_NOTICE: 'lpaEnforcementNotice',
220
241
  LPA_ENFORCEMENT_NOTICE_PLAN: 'lpaEnforcementNoticePlan',
242
+ LPA_ENFORCEMENT_NOTICE_WITHDRAWAL: 'lpaEnforcementNoticeWithdrawal',
221
243
  LPA_FINAL_COMMENT: 'lpaFinalComment',
222
244
  LPA_PROOF_OF_EVIDENCE: 'lpaProofOfEvidence',
223
245
  LPA_STATEMENT: 'lpaStatement',
@@ -389,6 +411,7 @@ export const APPEAL_SOURCE_SYSTEM = Object.freeze({
389
411
 
390
412
  export const APPEAL_TYPE_OF_PLANNING_APPLICATION = Object.freeze({
391
413
  ADVERTISEMENT: 'advertisement',
414
+ DISCONTINUANCE_NOTICE: 'discontinuance-notice',
392
415
  FULL_APPEAL: 'full-appeal',
393
416
  HOUSEHOLDER_PLANNING: 'householder-planning',
394
417
  LAWFUL_DEVELOPMENT_CERTIFICATE: 'lawful-development-certificate',
package/src/index.cjs CHANGED
@@ -110,6 +110,19 @@ const APPEAL_HAS_CASE_STATUS = Object.freeze({
110
110
  WITHDRAWN: 'withdrawn',
111
111
  });
112
112
 
113
+ const APPEAL_HAS_TYPE_OF_PLANNING_APPLICATION = Object.freeze({
114
+ ADVERTISEMENT: 'advertisement',
115
+ FULL_APPEAL: 'full-appeal',
116
+ HOUSEHOLDER_PLANNING: 'householder-planning',
117
+ LAWFUL_DEVELOPMENT_CERTIFICATE: 'lawful-development-certificate',
118
+ LISTED_BUILDING: 'listed-building',
119
+ MINOR_COMMERCIAL_DEVELOPMENT: 'minor-commercial-development',
120
+ OUTLINE_PLANNING: 'outline-planning',
121
+ PRIOR_APPROVAL: 'prior-approval',
122
+ REMOVAL_OR_VARIATION_OF_CONDITIONS: 'removal-or-variation-of-conditions',
123
+ RESERVED_MATTERS: 'reserved-matters',
124
+ });
125
+
113
126
  const APPEAL_ALLOCATION_LEVEL = Object.freeze({
114
127
  A: 'A',
115
128
  B: 'B',
@@ -171,6 +184,7 @@ const APPEAL_CASE_PROCEDURE = Object.freeze({
171
184
  const APPEAL_CASE_STAGE = Object.freeze({
172
185
  APPEAL_DECISION: 'appeal-decision',
173
186
  APPELLANT_CASE: 'appellant-case',
187
+ CANCELLATION: 'cancellation',
174
188
  COSTS: 'costs',
175
189
  EVIDENCE: 'evidence',
176
190
  FINAL_COMMENTS: 'final-comments',
@@ -243,6 +257,12 @@ const APPEAL_DEVELOPMENT_TYPE = Object.freeze({
243
257
  OTHER_MINOR: 'other-minor',
244
258
  });
245
259
 
260
+ const APPEAL_DISCONTINUANCE_NOTICE_SERVED_REASON = Object.freeze({
261
+ DANGER_TO_MEMBERS_OF_THE_PUBLIC: 'danger-to-members-of-the-public',
262
+ OTHER: 'other',
263
+ RISK_OF_INJURY_TO_THE_AMENITY_OF_LOCALITY: 'risk-of-injury-to-the-amenity-of-locality',
264
+ });
265
+
246
266
  const APPEAL_DOCUMENT_TYPE = Object.freeze({
247
267
  APPEAL_NOTIFICATION: 'appealNotification',
248
268
  APPELLANT_CASE_CORRESPONDENCE: 'appellantCaseCorrespondence',
@@ -269,6 +289,7 @@ const APPEAL_DOCUMENT_TYPE = Object.freeze({
269
289
  DELEGATED_REPORT: 'delegatedReport',
270
290
  DESIGN_ACCESS_STATEMENT: 'designAccessStatement',
271
291
  DEVELOPMENT_PLAN_POLICIES: 'developmentPlanPolicies',
292
+ DISCONTINUANCE_NOTICE: 'discontinuanceNotice',
272
293
  EIA_ENVIRONMENTAL_STATEMENT: 'eiaEnvironmentalStatement',
273
294
  EIA_SCOPING_OPINION: 'eiaScopingOpinion',
274
295
  EIA_SCREENING_DIRECTION: 'eiaScreeningDirection',
@@ -301,6 +322,7 @@ const APPEAL_DOCUMENT_TYPE = Object.freeze({
301
322
  LPA_COSTS_WITHDRAWAL: 'lpaCostsWithdrawal',
302
323
  LPA_ENFORCEMENT_NOTICE: 'lpaEnforcementNotice',
303
324
  LPA_ENFORCEMENT_NOTICE_PLAN: 'lpaEnforcementNoticePlan',
325
+ LPA_ENFORCEMENT_NOTICE_WITHDRAWAL: 'lpaEnforcementNoticeWithdrawal',
304
326
  LPA_FINAL_COMMENT: 'lpaFinalComment',
305
327
  LPA_PROOF_OF_EVIDENCE: 'lpaProofOfEvidence',
306
328
  LPA_STATEMENT: 'lpaStatement',
@@ -472,6 +494,7 @@ const APPEAL_SOURCE_SYSTEM = Object.freeze({
472
494
 
473
495
  const APPEAL_TYPE_OF_PLANNING_APPLICATION = Object.freeze({
474
496
  ADVERTISEMENT: 'advertisement',
497
+ DISCONTINUANCE_NOTICE: 'discontinuance-notice',
475
498
  FULL_APPEAL: 'full-appeal',
476
499
  HOUSEHOLDER_PLANNING: 'householder-planning',
477
500
  LAWFUL_DEVELOPMENT_CERTIFICATE: 'lawful-development-certificate',
@@ -909,6 +932,7 @@ exports.APPEAL_CASE_STATUS = APPEAL_CASE_STATUS;
909
932
  exports.APPEAL_CASE_TYPE = APPEAL_CASE_TYPE;
910
933
  exports.APPEAL_CASE_VALIDATION_OUTCOME = APPEAL_CASE_VALIDATION_OUTCOME;
911
934
  exports.APPEAL_DEVELOPMENT_TYPE = APPEAL_DEVELOPMENT_TYPE;
935
+ exports.APPEAL_DISCONTINUANCE_NOTICE_SERVED_REASON = APPEAL_DISCONTINUANCE_NOTICE_SERVED_REASON;
912
936
  exports.APPEAL_DOCUMENT_TYPE = APPEAL_DOCUMENT_TYPE;
913
937
  exports.APPEAL_EIA_DEVELOPMENT_DESCRIPTION = APPEAL_EIA_DEVELOPMENT_DESCRIPTION;
914
938
  exports.APPEAL_EIA_ENVIRONMENTAL_IMPACT_SCHEDULE = APPEAL_EIA_ENVIRONMENTAL_IMPACT_SCHEDULE;
@@ -917,6 +941,7 @@ exports.APPEAL_EVENT_TYPE = APPEAL_EVENT_TYPE;
917
941
  exports.APPEAL_HAS_CASE_DECISION_OUTCOME = APPEAL_HAS_CASE_DECISION_OUTCOME;
918
942
  exports.APPEAL_HAS_CASE_PROCEDURE = APPEAL_HAS_CASE_PROCEDURE;
919
943
  exports.APPEAL_HAS_CASE_STATUS = APPEAL_HAS_CASE_STATUS;
944
+ exports.APPEAL_HAS_TYPE_OF_PLANNING_APPLICATION = APPEAL_HAS_TYPE_OF_PLANNING_APPLICATION;
920
945
  exports.APPEAL_INVALID_OR_INCOMPLETE_DETAILS = APPEAL_INVALID_OR_INCOMPLETE_DETAILS;
921
946
  exports.APPEAL_KNOWS_ALL_OWNERS = APPEAL_KNOWS_ALL_OWNERS;
922
947
  exports.APPEAL_KNOWS_OTHER_OWNERS = APPEAL_KNOWS_OTHER_OWNERS;
package/src/schemas.d.ts CHANGED
@@ -155,6 +155,7 @@ export interface AppealDocument {
155
155
  | 'planningPermission'
156
156
  | 'lpaEnforcementNotice'
157
157
  | 'lpaEnforcementNoticePlan'
158
+ | 'lpaEnforcementNoticeWithdrawal'
158
159
  | 'planningContraventionNotice'
159
160
  | 'priorCorrespondenceWithPINS'
160
161
  | 'enforcementNotice'
@@ -174,6 +175,7 @@ export interface AppealDocument {
174
175
  | 'groundISupporting'
175
176
  | 'groundJSupporting'
176
177
  | 'groundKSupporting'
178
+ | 'discontinuanceNotice'
177
179
  | null;
178
180
  /**
179
181
  * The system mastering the metadata for the current document
@@ -209,6 +211,7 @@ export interface AppealDocument {
209
211
  | 'appeal-decision'
210
212
  | 'costs'
211
213
  | 'internal'
214
+ | 'cancellation'
212
215
  | null;
213
216
  /**
214
217
  * The folder ID containing the document in Horizon
@@ -1489,6 +1492,7 @@ export type AppealS78Case = (GridReference | SiteAddress) & {
1489
1492
  | 'minor-commercial-development'
1490
1493
  | 'advertisement'
1491
1494
  | 'lawful-development-certificate'
1495
+ | 'discontinuance-notice'
1492
1496
  | null;
1493
1497
  developmentType:
1494
1498
  | 'householder'
@@ -1624,11 +1628,11 @@ export type AppealS78Case = (GridReference | SiteAddress) & {
1624
1628
  */
1625
1629
  previousPlanningPermissionGranted?: boolean | null;
1626
1630
  /**
1627
- * The date on which an enforcement notice was issued
1631
+ * The date on which an Enforcement Notice or Discontinuance Notice was issued
1628
1632
  */
1629
1633
  issueDateOfEnforcementNotice?: string | null;
1630
1634
  /**
1631
- * The effective date of an enforcement notice
1635
+ * The effective date of an Enforcement Notice or Discontinuance Notice
1632
1636
  */
1633
1637
  effectiveDateOfEnforcementNotice?: string | null;
1634
1638
  /**
@@ -1689,6 +1693,16 @@ export type AppealS78Case = (GridReference | SiteAddress) & {
1689
1693
  * Reason(s) why LPA consider the appeal invalid
1690
1694
  */
1691
1695
  lpaAppealInvalidReasons?: string | null;
1696
+ discontinuanceNoticeServedReason?:
1697
+ | 'risk-of-injury-to-the-amenity-of-locality'
1698
+ | 'danger-to-members-of-the-public'
1699
+ | 'other'
1700
+ | null;
1701
+ /**
1702
+ * Other reason for serving a discontinuance notice, for discontinuanceNoticeServedReason: other
1703
+ */
1704
+ discontinuanceNoticeServedOtherReason?: string | null;
1705
+ wasRetrospectivePlanningApplicationMade?: boolean | null;
1692
1706
  [k: string]: unknown;
1693
1707
  };
1694
1708
 
@@ -247,7 +247,27 @@ describe(schema, () => {
247
247
  assert.strictEqual(validationResult, false);
248
248
  });
249
249
 
250
- const groupBAppealTypes = ['C', 'F', 'H', 'W', 'X', 'Y', 'Z'];
250
+ it('should enforce other for discontinuanceNoticeServedReason', () => {
251
+ const test = structuredClone(appealS78);
252
+ test.discontinuanceNoticeServedReason = 'other';
253
+ test.discontinuanceNoticeServedOtherReason = '';
254
+ const validationResult = ajv.validate(schema, test);
255
+ assert.strictEqual(validationResult, false);
256
+
257
+ test.discontinuanceNoticeServedOtherReason = null;
258
+ const validationResult2 = ajv.validate(schema, test);
259
+ assert.strictEqual(validationResult2, false);
260
+ });
261
+
262
+ it('should allow no reason for non other discontinuanceNoticeServedOtherReason', () => {
263
+ const test = structuredClone(appealS78);
264
+ test.discontinuanceNoticeServedReason = 'danger-to-members-of-the-public';
265
+ test.discontinuanceNoticeServedOtherReason = null;
266
+ const validationResult = ajv.validate(schema, test);
267
+ assert.strictEqual(validationResult, true);
268
+ });
269
+
270
+ const groupBAppealTypes = ['C', 'F', 'G', 'H', 'W', 'X', 'Y', 'Z'];
251
271
  groupBAppealTypes.forEach((appealType) => {
252
272
  it(`should support group B appeal type ${appealType}`, () => {
253
273
  const test = structuredClone(appealS78);