@planning-inspectorate/data-model 1.18.0 → 1.19.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.
@@ -9,3 +9,8 @@ updates:
9
9
  directory: '/' # Location of package manifests
10
10
  schedule:
11
11
  interval: 'weekly'
12
+ groups:
13
+ devDeps: # group all dev dependencies
14
+ patterns:
15
+ - '*'
16
+ dependency-type: 'development'
@@ -452,23 +452,16 @@ A list of specialisms for allocation purposes
452
452
  ### caseSpecialisms Examples
453
453
 
454
454
  ```json
455
- "Access"
455
+ [
456
+ "Access",
457
+ "Listed building and enforcement"
458
+ ]
456
459
  ```
457
460
 
458
461
  ```json
459
- "Listed building and enforcement"
460
- ```
461
-
462
- ```json
463
- "Roads and traffics"
464
- ```
465
-
466
- ```json
467
- "Natural heritage"
468
- ```
469
-
470
- ```json
471
- "Schedule 1"
462
+ [
463
+ "Schedule 1"
464
+ ]
472
465
  ```
473
466
 
474
467
  ## caseSubmittedDate
@@ -2229,6 +2222,21 @@ The methods used to notify relevant parties
2229
2222
 
2230
2223
  `string[]`
2231
2224
 
2225
+ ### notificationMethod Examples
2226
+
2227
+ ```json
2228
+ [
2229
+ "notice",
2230
+ "letter"
2231
+ ]
2232
+ ```
2233
+
2234
+ ```json
2235
+ [
2236
+ "advert"
2237
+ ]
2238
+ ```
2239
+
2232
2240
  ## ownersInformed
2233
2241
 
2234
2242
  Indicates if the appellant has informed other owners of the site
@@ -506,23 +506,16 @@ A list of specialisms for allocation purposes
506
506
  ### caseSpecialisms Examples
507
507
 
508
508
  ```json
509
- "Access"
509
+ [
510
+ "Access",
511
+ "Listed building and enforcement"
512
+ ]
510
513
  ```
511
514
 
512
515
  ```json
513
- "Listed building and enforcement"
514
- ```
515
-
516
- ```json
517
- "Roads and traffics"
518
- ```
519
-
520
- ```json
521
- "Natural heritage"
522
- ```
523
-
524
- ```json
525
- "Schedule 1"
516
+ [
517
+ "Schedule 1"
518
+ ]
526
519
  ```
527
520
 
528
521
  ## caseSubmittedDate
@@ -1914,6 +1907,21 @@ The methods used to notify relevant parties
1914
1907
 
1915
1908
  `string[]`
1916
1909
 
1910
+ ### notificationMethod Examples
1911
+
1912
+ ```json
1913
+ [
1914
+ "notice",
1915
+ "letter"
1916
+ ]
1917
+ ```
1918
+
1919
+ ```json
1920
+ [
1921
+ "advert"
1922
+ ]
1923
+ ```
1924
+
1917
1925
  ## ownersInformed
1918
1926
 
1919
1927
  Indicates if the appellant has informed other owners of the site
@@ -301,15 +301,16 @@ A list of case specialisms for allocation purposes
301
301
  ### caseSpecialisms Examples
302
302
 
303
303
  ```json
304
- "General allocation"
304
+ [
305
+ "General allocation",
306
+ "Housing orders"
307
+ ]
305
308
  ```
306
309
 
307
310
  ```json
308
- "Housing orders"
309
- ```
310
-
311
- ```json
312
- "Waste"
311
+ [
312
+ "Waste"
313
+ ]
313
314
  ```
314
315
 
315
316
  ## caseSubmittedDate
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planning-inspectorate/data-model",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "JSON Schemas for the Planning Inspectorate's Data Model",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -30,8 +30,8 @@
30
30
  },
31
31
  "devDependencies": {
32
32
  "@adobe/jsonschema2md": "^8.0.3",
33
- "@commitlint/cli": "^19.8.1",
34
- "@commitlint/config-conventional": "^19.8.1",
33
+ "@commitlint/cli": "^20.1.0",
34
+ "@commitlint/config-conventional": "^20.0.0",
35
35
  "ajv": "^8.17.1",
36
36
  "ajv-formats": "^3.0.1",
37
37
  "eslint": "^9.31.0",
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: appeal-has.schema.json
3
- # timestamp: 2025-09-09T11:38:23+00:00
3
+ # timestamp: 2025-09-15T15:35:44+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -175,16 +175,12 @@ class KnowsAllOwners(Enum):
175
175
  NoneType_None = None
176
176
 
177
177
 
178
- class NotificationMethodEnumEnumEnum(Enum):
178
+ class NotificationMethodEnum(Enum):
179
179
  notice = "notice"
180
180
  letter = "letter"
181
181
  advert = "advert"
182
182
 
183
183
 
184
- class NotificationMethodEnum(RootModel[NotificationMethodEnumEnumEnum | None]):
185
- root: NotificationMethodEnumEnumEnum | None = None
186
-
187
-
188
184
  class NeighbouringSiteAddress(BaseModel):
189
185
  model_config = ConfigDict(
190
186
  extra="allow",
@@ -291,14 +287,7 @@ class AppealHasCase1(BaseModel):
291
287
  A band used for allocation purposes
292
288
  """
293
289
  caseSpecialisms: list[str] = Field(
294
- ...,
295
- examples=[
296
- "Access",
297
- "Listed building and enforcement",
298
- "Roads and traffics",
299
- "Natural heritage",
300
- "Schedule 1",
301
- ],
290
+ ..., examples=[["Access", "Listed building and enforcement"], ["Schedule 1"]]
302
291
  )
303
292
  """
304
293
  A list of specialisms for allocation purposes
@@ -643,7 +632,9 @@ class AppealHasCase1(BaseModel):
643
632
  """
644
633
  Indicates if the appellant has advertised the appeal to the LPA decision
645
634
  """
646
- notificationMethod: list[NotificationMethodEnum]
635
+ notificationMethod: list[NotificationMethodEnum] = Field(
636
+ ..., examples=[["notice", "letter"], ["advert"]]
637
+ )
647
638
  """
648
639
  The methods used to notify relevant parties
649
640
  """
@@ -722,16 +713,6 @@ class AppealHasCase1(BaseModel):
722
713
  advertType: str | None = None
723
714
 
724
715
 
725
- class NotificationMethodEnum1EnumEnum(Enum):
726
- notice = "notice"
727
- letter = "letter"
728
- advert = "advert"
729
-
730
-
731
- class NotificationMethodEnum1(RootModel[NotificationMethodEnum1EnumEnum | None]):
732
- root: NotificationMethodEnum1EnumEnum | None = None
733
-
734
-
735
716
  class AppealHasCase2(BaseModel):
736
717
  """
737
718
  Group A - Schema defining the metadata for an appeal
@@ -787,14 +768,7 @@ class AppealHasCase2(BaseModel):
787
768
  A band used for allocation purposes
788
769
  """
789
770
  caseSpecialisms: list[str] = Field(
790
- ...,
791
- examples=[
792
- "Access",
793
- "Listed building and enforcement",
794
- "Roads and traffics",
795
- "Natural heritage",
796
- "Schedule 1",
797
- ],
771
+ ..., examples=[["Access", "Listed building and enforcement"], ["Schedule 1"]]
798
772
  )
799
773
  """
800
774
  A list of specialisms for allocation purposes
@@ -1139,7 +1113,9 @@ class AppealHasCase2(BaseModel):
1139
1113
  """
1140
1114
  Indicates if the appellant has advertised the appeal to the LPA decision
1141
1115
  """
1142
- notificationMethod: list[NotificationMethodEnum1]
1116
+ notificationMethod: list[NotificationMethodEnum] = Field(
1117
+ ..., examples=[["notice", "letter"], ["advert"]]
1118
+ )
1143
1119
  """
1144
1120
  The methods used to notify relevant parties
1145
1121
  """
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: appeal-s78.schema.json
3
- # timestamp: 2025-09-09T11:38:22+00:00
3
+ # timestamp: 2025-09-15T15:35:44+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -169,16 +169,12 @@ class KnowsAllOwners(Enum):
169
169
  NoneType_None = None
170
170
 
171
171
 
172
- class NotificationMethodEnumEnumEnum(Enum):
172
+ class NotificationMethodEnum(Enum):
173
173
  notice = "notice"
174
174
  letter = "letter"
175
175
  advert = "advert"
176
176
 
177
177
 
178
- class NotificationMethodEnum(RootModel[NotificationMethodEnumEnumEnum | None]):
179
- root: NotificationMethodEnumEnumEnum | None = None
180
-
181
-
182
178
  class NeighbouringSiteAddress(BaseModel):
183
179
  model_config = ConfigDict(
184
180
  extra="allow",
@@ -357,14 +353,7 @@ class AppealS78Case1(BaseModel):
357
353
  A band used for allocation purposes
358
354
  """
359
355
  caseSpecialisms: list[str] = Field(
360
- ...,
361
- examples=[
362
- "Access",
363
- "Listed building and enforcement",
364
- "Roads and traffics",
365
- "Natural heritage",
366
- "Schedule 1",
367
- ],
356
+ ..., examples=[["Access", "Listed building and enforcement"], ["Schedule 1"]]
368
357
  )
369
358
  """
370
359
  A list of specialisms for allocation purposes
@@ -611,7 +600,9 @@ class AppealS78Case1(BaseModel):
611
600
  """
612
601
  Indicates if the appellant has advertised the appeal to the LPA decision
613
602
  """
614
- notificationMethod: list[NotificationMethodEnum]
603
+ notificationMethod: list[NotificationMethodEnum] = Field(
604
+ ..., examples=[["notice", "letter"], ["advert"]]
605
+ )
615
606
  """
616
607
  The methods used to notify relevant parties
617
608
  """
@@ -875,16 +866,6 @@ class AppealS78Case1(BaseModel):
875
866
  )
876
867
 
877
868
 
878
- class NotificationMethodEnum1EnumEnum(Enum):
879
- notice = "notice"
880
- letter = "letter"
881
- advert = "advert"
882
-
883
-
884
- class NotificationMethodEnum1(RootModel[NotificationMethodEnum1EnumEnum | None]):
885
- root: NotificationMethodEnum1EnumEnum | None = None
886
-
887
-
888
869
  class AppealS78Case2(BaseModel):
889
870
  """
890
871
  Group B - Schema defining the metadata for an appeal
@@ -940,14 +921,7 @@ class AppealS78Case2(BaseModel):
940
921
  A band used for allocation purposes
941
922
  """
942
923
  caseSpecialisms: list[str] = Field(
943
- ...,
944
- examples=[
945
- "Access",
946
- "Listed building and enforcement",
947
- "Roads and traffics",
948
- "Natural heritage",
949
- "Schedule 1",
950
- ],
924
+ ..., examples=[["Access", "Listed building and enforcement"], ["Schedule 1"]]
951
925
  )
952
926
  """
953
927
  A list of specialisms for allocation purposes
@@ -1194,7 +1168,9 @@ class AppealS78Case2(BaseModel):
1194
1168
  """
1195
1169
  Indicates if the appellant has advertised the appeal to the LPA decision
1196
1170
  """
1197
- notificationMethod: list[NotificationMethodEnum1]
1171
+ notificationMethod: list[NotificationMethodEnum] = Field(
1172
+ ..., examples=[["notice", "letter"], ["advert"]]
1173
+ )
1198
1174
  """
1199
1175
  The methods used to notify relevant parties
1200
1176
  """
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: dart-response.schema.json
3
- # timestamp: 2025-08-29T10:40:44+00:00
3
+ # timestamp: 2025-09-15T15:35:43+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -78,7 +78,7 @@ class DartApiResponse(BaseModel):
78
78
  A band used for allocation purposes
79
79
  """
80
80
  caseSpecialisms: list[str] | None = Field(
81
- None, examples=["General allocation", "Housing orders", "Waste"]
81
+ None, examples=[["General allocation", "Housing orders"], ["Waste"]]
82
82
  )
83
83
  """
84
84
  A list of case specialisms for allocation purposes
@@ -167,9 +167,16 @@
167
167
  "caseSpecialisms": {
168
168
  "type": ["array", "null"],
169
169
  "items": {
170
- "type": "string"
170
+ "type": "string",
171
+ "examples": [
172
+ "Access",
173
+ "Listed building and enforcement",
174
+ "Roads and traffics",
175
+ "Natural heritage",
176
+ "Schedule 1"
177
+ ]
171
178
  },
172
- "examples": ["Access", "Listed building and enforcement", "Roads and traffics", "Natural heritage", "Schedule 1"],
179
+ "examples": [["Access", "Listed building and enforcement"], ["Schedule 1"]],
173
180
  "description": "A list of specialisms for allocation purposes"
174
181
  },
175
182
  "caseSubmittedDate": {
@@ -573,8 +580,9 @@
573
580
  "type": ["array", "null"],
574
581
  "items": {
575
582
  "type": "string",
576
- "enum": ["notice", "letter", "advert", null]
583
+ "enum": ["notice", "letter", "advert"]
577
584
  },
585
+ "examples": [["notice", "letter"], ["advert"]],
578
586
  "description": "The methods used to notify relevant parties"
579
587
  },
580
588
  "ownersInformed": {
@@ -236,9 +236,16 @@
236
236
  "caseSpecialisms": {
237
237
  "type": ["array", "null"],
238
238
  "items": {
239
- "type": "string"
239
+ "type": "string",
240
+ "examples": [
241
+ "Access",
242
+ "Listed building and enforcement",
243
+ "Roads and traffics",
244
+ "Natural heritage",
245
+ "Schedule 1"
246
+ ]
240
247
  },
241
- "examples": ["Access", "Listed building and enforcement", "Roads and traffics", "Natural heritage", "Schedule 1"],
248
+ "examples": [["Access", "Listed building and enforcement"], ["Schedule 1"]],
242
249
  "description": "A list of specialisms for allocation purposes",
243
250
  "$comment": "Also available on HAS cases"
244
251
  },
@@ -584,8 +591,9 @@
584
591
  "type": ["array", "null"],
585
592
  "items": {
586
593
  "type": "string",
587
- "enum": ["notice", "letter", "advert", null]
594
+ "enum": ["notice", "letter", "advert"]
588
595
  },
596
+ "examples": [["notice", "letter"], ["advert"]],
589
597
  "description": "The methods used to notify relevant parties",
590
598
  "$comment": "Also available on HAS cases"
591
599
  },
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "representationType": {
23
23
  "type": "string",
24
- "enum": ["statement", "comment", "final_comment", "proofs_evidence", null],
24
+ "enum": ["statement", "comment", "final_comment", "proofs_evidence"],
25
25
  "description": "The type of representation"
26
26
  },
27
27
  "representation": {
@@ -0,0 +1,95 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "commands/lpa-questionnaire-cas-advert.schema.json",
4
+ "title": "LPAQ cas advert submission properties",
5
+ "description": "Schema defining any cas advert specific properties for LPAQ submissions",
6
+ "type": "object",
7
+ "additionalProperties": true,
8
+ "required": [
9
+ "affectsScheduledMonument",
10
+ "hasProtectedSpecies",
11
+ "isAonbNationalLandscape",
12
+ "designatedSitesNames",
13
+ "hasStatutoryConsultees",
14
+ "consultedBodiesDetails",
15
+ "hasEmergingPlan",
16
+ "lpaProcedurePreference",
17
+ "lpaProcedurePreferenceDetails",
18
+ "lpaProcedurePreferenceDuration",
19
+ "isSiteInAreaOfSpecialControlAdverts",
20
+ "wasApplicationRefusedDueToHighwayOrTraffic",
21
+ "didAppellantSubmitCompletePhotosAndPlans"
22
+ ],
23
+ "allOf": [
24
+ {
25
+ "properties": {
26
+ "affectsScheduledMonument": {
27
+ "type": ["boolean", "null"],
28
+ "description": "Indicates that a scheduled monument is affected",
29
+ "$comment": "Only available in S78 cases"
30
+ },
31
+ "hasProtectedSpecies": {
32
+ "type": ["boolean", "null"],
33
+ "description": "Indicates the existence of protected species",
34
+ "$comment": "Only available in S78 cases"
35
+ },
36
+ "isAonbNationalLandscape": {
37
+ "type": ["boolean", "null"],
38
+ "description": "Indicates an area of outstanding beauty (National Landscape)",
39
+ "$comment": "Only available in S78 cases"
40
+ },
41
+ "designatedSitesNames": {
42
+ "type": ["array", "null"],
43
+ "items": {
44
+ "type": "string",
45
+ "examples": ["SSSI", "cSAC", "SAC", "pSPA", "SPA", "user entered value"]
46
+ },
47
+ "description": "The designated site names",
48
+ "$comment": "Only available in S78 cases"
49
+ },
50
+ "hasStatutoryConsultees": {
51
+ "type": ["boolean", "null"],
52
+ "description": "Indicates statutory consultees",
53
+ "$comment": "Only available in S78 cases"
54
+ },
55
+ "consultedBodiesDetails": {
56
+ "type": ["string", "null"],
57
+ "description": "The details of the bodies consulted"
58
+ },
59
+ "hasEmergingPlan": {
60
+ "type": ["boolean", "null"],
61
+ "description": "Indicates emerging plans",
62
+ "$comment": "Only available in S78 cases"
63
+ },
64
+ "lpaProcedurePreference": {
65
+ "type": ["string", "null"],
66
+ "enum": ["written", "hearing", "inquiry", null],
67
+ "description": "The procedure preference indicated by the LPA",
68
+ "$comment": "Only available in S78 cases"
69
+ },
70
+ "lpaProcedurePreferenceDetails": {
71
+ "type": ["string", "null"],
72
+ "description": "The procedure details preference indicated by the LPA",
73
+ "$comment": "Only available in S78 cases"
74
+ },
75
+ "lpaProcedurePreferenceDuration": {
76
+ "type": ["number", "null"],
77
+ "description": "The duration of enquiry indicated by the LPA",
78
+ "$comment": "Only available in S78 cases"
79
+ },
80
+ "isSiteInAreaOfSpecialControlAdverts": {
81
+ "type": ["boolean", "null"],
82
+ "description": "Indicates if the site is in an area of special control for adverts"
83
+ },
84
+ "wasApplicationRefusedDueToHighwayOrTraffic": {
85
+ "type": ["boolean", "null"],
86
+ "description": "Indicates if the application was refused because of highway or traffic public safety?"
87
+ },
88
+ "didAppellantSubmitCompletePhotosAndPlans": {
89
+ "type": ["boolean", "null"],
90
+ "description": "Indicates if the appellant submitted complete and accurate photographs and plans"
91
+ }
92
+ }
93
+ }
94
+ ]
95
+ }
@@ -33,7 +33,9 @@
33
33
  "$comment": "Adverts + CAS Adverts - TBD - may need separate schemas",
34
34
  "allOf": [
35
35
  { "properties": { "caseType": { "enum": ["H", "ZA"] } } },
36
- { "$ref": "lpa-questionnaire-common.schema.json" }
36
+ { "$ref": "lpa-questionnaire-common.schema.json" },
37
+ { "$ref": "lpa-questionnaire-has.schema.json" },
38
+ { "$ref": "lpa-questionnaire-cas-advert.schema.json" }
37
39
  ]
38
40
  }
39
41
  ]
@@ -55,9 +55,10 @@
55
55
  "caseSpecialisms": {
56
56
  "type": ["array", "null"],
57
57
  "items": {
58
- "type": "string"
58
+ "type": "string",
59
+ "examples": ["General allocation", "Housing orders", "Waste"]
59
60
  },
60
- "examples": ["General allocation", "Housing orders", "Waste"],
61
+ "examples": [["General allocation", "Housing orders"], ["Waste"]],
61
62
  "description": "A list of case specialisms for allocation purposes"
62
63
  },
63
64
  "caseSubmittedDate": {
package/src/schemas.d.ts CHANGED
@@ -676,7 +676,7 @@ export type AppealHASCase = (
676
676
  /**
677
677
  * The methods used to notify relevant parties
678
678
  */
679
- notificationMethod: ('notice' | 'letter' | 'advert' | null)[] | null;
679
+ notificationMethod: ('notice' | 'letter' | 'advert')[] | null;
680
680
  /**
681
681
  * Indicates if the appellant has informed other owners of the site
682
682
  */
@@ -1168,7 +1168,7 @@ export type AppealS78Case = (
1168
1168
  /**
1169
1169
  * The methods used to notify relevant parties
1170
1170
  */
1171
- notificationMethod: ('notice' | 'letter' | 'advert' | null)[] | null;
1171
+ notificationMethod: ('notice' | 'letter' | 'advert')[] | null;
1172
1172
  /**
1173
1173
  * Indicates if the appellant has informed other owners of the site
1174
1174
  */
@@ -2968,7 +2968,7 @@ export type AppealRepresentationSubmission = {
2968
2968
  /**
2969
2969
  * The type of representation
2970
2970
  */
2971
- representationType: 'statement' | 'comment' | 'final_comment' | 'proofs_evidence' | null;
2971
+ representationType: 'statement' | 'comment' | 'final_comment' | 'proofs_evidence';
2972
2972
  /**
2973
2973
  * The original representation
2974
2974
  */
@@ -3597,6 +3597,64 @@ export interface Address {
3597
3597
  country?: string;
3598
3598
  }
3599
3599
 
3600
+ /**
3601
+ * Schema defining any cas advert specific properties for LPAQ submissions
3602
+ */
3603
+ export type LPAQCasAdvertSubmissionProperties = {
3604
+ /**
3605
+ * Indicates that a scheduled monument is affected
3606
+ */
3607
+ affectsScheduledMonument?: boolean | null;
3608
+ /**
3609
+ * Indicates the existence of protected species
3610
+ */
3611
+ hasProtectedSpecies?: boolean | null;
3612
+ /**
3613
+ * Indicates an area of outstanding beauty (National Landscape)
3614
+ */
3615
+ isAonbNationalLandscape?: boolean | null;
3616
+ /**
3617
+ * The designated site names
3618
+ */
3619
+ designatedSitesNames?: string[] | null;
3620
+ /**
3621
+ * Indicates statutory consultees
3622
+ */
3623
+ hasStatutoryConsultees?: boolean | null;
3624
+ /**
3625
+ * The details of the bodies consulted
3626
+ */
3627
+ consultedBodiesDetails?: string | null;
3628
+ /**
3629
+ * Indicates emerging plans
3630
+ */
3631
+ hasEmergingPlan?: boolean | null;
3632
+ /**
3633
+ * The procedure preference indicated by the LPA
3634
+ */
3635
+ lpaProcedurePreference?: 'written' | 'hearing' | 'inquiry' | null;
3636
+ /**
3637
+ * The procedure details preference indicated by the LPA
3638
+ */
3639
+ lpaProcedurePreferenceDetails?: string | null;
3640
+ /**
3641
+ * The duration of enquiry indicated by the LPA
3642
+ */
3643
+ lpaProcedurePreferenceDuration?: number | null;
3644
+ /**
3645
+ * Indicates if the site is in an area of special control for adverts
3646
+ */
3647
+ isSiteInAreaOfSpecialControlAdverts?: boolean | null;
3648
+ /**
3649
+ * Indicates if the application was refused because of highway or traffic public safety?
3650
+ */
3651
+ wasApplicationRefusedDueToHighwayOrTraffic?: boolean | null;
3652
+ /**
3653
+ * Indicates if the appellant submitted complete and accurate photographs and plans
3654
+ */
3655
+ didAppellantSubmitCompletePhotosAndPlans?: boolean | null;
3656
+ };
3657
+
3600
3658
  /**
3601
3659
  * Schema defining any properties common across all appeal types for LPAQ submissions
3602
3660
  */
@@ -4010,6 +4068,63 @@ export type LPAQS78SubmissionProperties = {
4010
4068
  */
4011
4069
  lpaProcedurePreferenceDuration?: number | null;
4012
4070
  };
4071
+ /**
4072
+ * Schema defining any cas advert specific properties for LPAQ submissions
4073
+ */
4074
+ export type LPAQCasAdvertSubmissionProperties = {
4075
+ /**
4076
+ * Indicates that a scheduled monument is affected
4077
+ */
4078
+ affectsScheduledMonument?: boolean | null;
4079
+ /**
4080
+ * Indicates the existence of protected species
4081
+ */
4082
+ hasProtectedSpecies?: boolean | null;
4083
+ /**
4084
+ * Indicates an area of outstanding beauty (National Landscape)
4085
+ */
4086
+ isAonbNationalLandscape?: boolean | null;
4087
+ /**
4088
+ * The designated site names
4089
+ */
4090
+ designatedSitesNames?: string[] | null;
4091
+ /**
4092
+ * Indicates statutory consultees
4093
+ */
4094
+ hasStatutoryConsultees?: boolean | null;
4095
+ /**
4096
+ * The details of the bodies consulted
4097
+ */
4098
+ consultedBodiesDetails?: string | null;
4099
+ /**
4100
+ * Indicates emerging plans
4101
+ */
4102
+ hasEmergingPlan?: boolean | null;
4103
+ /**
4104
+ * The procedure preference indicated by the LPA
4105
+ */
4106
+ lpaProcedurePreference?: 'written' | 'hearing' | 'inquiry' | null;
4107
+ /**
4108
+ * The procedure details preference indicated by the LPA
4109
+ */
4110
+ lpaProcedurePreferenceDetails?: string | null;
4111
+ /**
4112
+ * The duration of enquiry indicated by the LPA
4113
+ */
4114
+ lpaProcedurePreferenceDuration?: number | null;
4115
+ /**
4116
+ * Indicates if the site is in an area of special control for adverts
4117
+ */
4118
+ isSiteInAreaOfSpecialControlAdverts?: boolean | null;
4119
+ /**
4120
+ * Indicates if the application was refused because of highway or traffic public safety?
4121
+ */
4122
+ wasApplicationRefusedDueToHighwayOrTraffic?: boolean | null;
4123
+ /**
4124
+ * Indicates if the appellant submitted complete and accurate photographs and plans
4125
+ */
4126
+ didAppellantSubmitCompletePhotosAndPlans?: boolean | null;
4127
+ };
4013
4128
 
4014
4129
  /**
4015
4130
  * Schema defining the data produced by the Front-Office when an LPA Questionnaire is submitted
@@ -4027,7 +4142,9 @@ export interface LPAQuestionnaireCommand {
4027
4142
  LPAQS78SubmissionProperties)
4028
4143
  | ({
4029
4144
  caseType?: 'H' | 'ZA';
4030
- } & LPAQCommonSubmissionProperties);
4145
+ } & LPAQCommonSubmissionProperties &
4146
+ LPAQHASSubmissionProperties &
4147
+ LPAQCasAdvertSubmissionProperties);
4031
4148
  documents: {
4032
4149
  /**
4033
4150
  * The unique identifier for the document
@@ -49,12 +49,25 @@ const exampleAdvertQuestionnaireSchema = {
49
49
  'ullamco quis',
50
50
  'voluptate quis'
51
51
  ],
52
- lpaCostsAppliedFor: null
52
+ lpaCostsAppliedFor: null,
53
+ affectsScheduledMonument: null,
54
+ hasProtectedSpecies: null,
55
+ isAonbNationalLandscape: null,
56
+ designatedSitesNames: null,
57
+ hasStatutoryConsultees: null,
58
+ consultedBodiesDetails: null,
59
+ hasEmergingPlan: null,
60
+ lpaProcedurePreference: null,
61
+ lpaProcedurePreferenceDetails: null,
62
+ lpaProcedurePreferenceDuration: null,
63
+ isSiteInAreaOfSpecialControlAdverts: null,
64
+ wasApplicationRefusedDueToHighwayOrTraffic: null,
65
+ didAppellantSubmitCompletePhotosAndPlans: null
53
66
  },
54
67
  documents: [document]
55
68
  };
56
69
 
57
- describe('HAS questionnaire command schema', () => {
70
+ describe('Adverts questionnaire command schema', () => {
58
71
  const schemas = loadAllSchemasSync();
59
72
  const flatSchemas = Object.values(schemas).reduce((a, c) => ({ ...a, ...c }), {});
60
73
  const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
@@ -65,13 +78,6 @@ describe('HAS questionnaire command schema', () => {
65
78
  assert.strictEqual(validationResult, true);
66
79
  });
67
80
 
68
- it('should allow valid schema for CAS Advert', () => {
69
- const test = structuredClone(exampleAdvertQuestionnaireSchema);
70
- test.casedata.caseType = 'ZA';
71
- const validationResult = ajv.validate(schema, test);
72
- assert.strictEqual(validationResult, true);
73
- });
74
-
75
81
  it('should reject missing caseReference', () => {
76
82
  const test = structuredClone(exampleAdvertQuestionnaireSchema);
77
83
  delete test.casedata.caseReference;
@@ -0,0 +1,98 @@
1
+ import { describe, it } from 'node:test';
2
+ import assert from 'node:assert';
3
+ import Ajv from 'ajv';
4
+ import addFormats from 'ajv-formats';
5
+ import { loadAllSchemasSync } from '../../../src/index.js';
6
+
7
+ const schema = 'lpa-questionnaire.schema.json';
8
+
9
+ const document = {
10
+ documentId: 'deserunt sint aliqua adipisicing dolore',
11
+ filename: 'ut dolore',
12
+ originalFilename: 'Lorem amet fugiat adipisicing Excepteur',
13
+ size: -90476934,
14
+ mime: 'magna labore exercitation ut',
15
+ documentURI: 'ut reprehenderit',
16
+ dateCreated: '1933-04-03T03:24:38.0Z',
17
+ documentType: 'plansDrawings'
18
+ };
19
+
20
+ const exampleCasAdvertQuestionnaireSchema = {
21
+ casedata: {
22
+ caseType: 'ZA',
23
+ caseReference: 'nisi incididunt cillum',
24
+ lpaQuestionnaireSubmittedDate: null,
25
+ lpaStatement: 'consequat ex',
26
+ siteAccessDetails: null,
27
+ siteSafetyDetails: null,
28
+ isCorrectAppealType: null,
29
+ isGreenBelt: null,
30
+ inConservationArea: null,
31
+ newConditionDetails: 'anim sint ut aute',
32
+ notificationMethod: null,
33
+ nearbyCaseReferences: null,
34
+ neighbouringSiteAddresses: [
35
+ {
36
+ neighbouringSiteAddressLine1: 'commodo dolore incididunt',
37
+ neighbouringSiteAddressLine2: 'est voluptate irure aliqua elit',
38
+ neighbouringSiteAddressTown: 'labore aliquip ex incididunt nulla',
39
+ neighbouringSiteAddressCounty: 'enim ut Duis ut ex',
40
+ neighbouringSiteAddressPostcode: 'pariatur',
41
+ neighbouringSiteAccessDetails: 'aliqua irure mollit consequat nisi',
42
+ neighbouringSiteSafetyDetails: null
43
+ }
44
+ ],
45
+ affectedListedBuildingNumbers: [
46
+ 'occaecat id aliquip dolore',
47
+ 'magna',
48
+ 'minim laboris fugiat id aliqua',
49
+ 'ullamco quis',
50
+ 'voluptate quis'
51
+ ],
52
+ lpaCostsAppliedFor: null,
53
+ affectsScheduledMonument: null,
54
+ hasProtectedSpecies: null,
55
+ isAonbNationalLandscape: null,
56
+ designatedSitesNames: null,
57
+ hasStatutoryConsultees: null,
58
+ consultedBodiesDetails: null,
59
+ hasEmergingPlan: null,
60
+ lpaProcedurePreference: null,
61
+ lpaProcedurePreferenceDetails: null,
62
+ lpaProcedurePreferenceDuration: null,
63
+ isSiteInAreaOfSpecialControlAdverts: null,
64
+ wasApplicationRefusedDueToHighwayOrTraffic: null,
65
+ didAppellantSubmitCompletePhotosAndPlans: null
66
+ },
67
+ documents: [document]
68
+ };
69
+
70
+ describe('CAS Advert questionnaire command schema', () => {
71
+ const schemas = loadAllSchemasSync();
72
+ const flatSchemas = Object.values(schemas).reduce((a, c) => ({ ...a, ...c }), {});
73
+ const ajv = new Ajv({ schemas: flatSchemas, allErrors: true });
74
+ addFormats(ajv);
75
+
76
+ it('should allow valid schema for CAS Advert', () => {
77
+ const validationResult = ajv.validate(schema, exampleCasAdvertQuestionnaireSchema);
78
+ assert.strictEqual(validationResult, true);
79
+ });
80
+
81
+ it('should reject missing caseReference', () => {
82
+ const test = structuredClone(exampleCasAdvertQuestionnaireSchema);
83
+ delete test.casedata.caseReference;
84
+ const validationResult = ajv.validate(schema, test);
85
+ assert.strictEqual(validationResult, false);
86
+ assert.strictEqual(
87
+ ajv.errors.some((x) => x.message === "must have required property 'caseReference'"),
88
+ true
89
+ );
90
+ });
91
+
92
+ it('should allow additional props', () => {
93
+ const test = structuredClone(exampleCasAdvertQuestionnaireSchema);
94
+ test.test = 1;
95
+ const validationResult = ajv.validate(schema, test);
96
+ assert.strictEqual(validationResult, true);
97
+ });
98
+ });