@planning-inspectorate/data-model 2.18.0 → 2.20.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 (40) hide show
  1. package/docs/README.md +2 -0
  2. package/docs/appeal-document.md +4 -0
  3. package/docs/appeal-s78.md +46 -0
  4. package/package.json +1 -1
  5. package/pins_data_model/models/model_appeal_document.py +5 -1
  6. package/pins_data_model/models/model_appeal_event.py +1 -1
  7. package/pins_data_model/models/model_appeal_event_estimate.py +1 -1
  8. package/pins_data_model/models/model_appeal_has.py +1 -1
  9. package/pins_data_model/models/model_appeal_representation.py +1 -1
  10. package/pins_data_model/models/model_appeal_s78.py +97 -2
  11. package/pins_data_model/models/model_dart_response.py +1 -1
  12. package/pins_data_model/models/model_entraid.py +1 -1
  13. package/pins_data_model/models/model_folder.py +1 -1
  14. package/pins_data_model/models/model_gettimesheets_response.py +1 -1
  15. package/pins_data_model/models/model_listed_building.py +1 -1
  16. package/pins_data_model/models/model_listed_buildings.py +1 -1
  17. package/pins_data_model/models/model_nsip_document.py +1 -1
  18. package/pins_data_model/models/model_nsip_exam_timetable.py +1 -1
  19. package/pins_data_model/models/model_nsip_invoice.py +1 -1
  20. package/pins_data_model/models/model_nsip_meeting.py +1 -1
  21. package/pins_data_model/models/model_nsip_project.py +1 -1
  22. package/pins_data_model/models/model_nsip_project_update.py +1 -1
  23. package/pins_data_model/models/model_nsip_representation.py +1 -1
  24. package/pins_data_model/models/model_nsip_subscription.py +1 -1
  25. package/pins_data_model/models/model_pins_inspector.py +1 -1
  26. package/pins_data_model/models/model_pins_lpa.py +1 -1
  27. package/pins_data_model/models/model_s51_advice.py +1 -1
  28. package/pins_data_model/models/model_service_user.py +1 -1
  29. package/schemas/appeal-document.schema.json +4 -0
  30. package/schemas/appeal-s78.schema.json +29 -0
  31. package/schemas/commands/appeals-components/appeal-enforcement-common-submission.schema.json +137 -0
  32. package/schemas/commands/appeals-components/appeal-enforcement-listed-submission.schema.json +103 -0
  33. package/schemas/commands/appeals-components/appeal-enforcement-submission.schema.json +19 -145
  34. package/schemas/commands/appellant-submission.schema.json +3 -1
  35. package/src/enums.cjs +4 -0
  36. package/src/enums.d.ts +4 -0
  37. package/src/enums.js +4 -0
  38. package/src/index.cjs +4 -0
  39. package/src/schemas.d.ts +208 -96
  40. package/tests/appeals/commands/enforcement-listed-submission.test.js +1 -60
package/src/schemas.d.ts CHANGED
@@ -170,6 +170,10 @@ export interface AppealDocument {
170
170
  | 'delegatedReport'
171
171
  | 'relatedApplications'
172
172
  | 'otherRelevantMatters'
173
+ | 'groundHSupporting'
174
+ | 'groundISupporting'
175
+ | 'groundJSupporting'
176
+ | 'groundKSupporting'
173
177
  | null;
174
178
  /**
175
179
  * The system mastering the metadata for the current document
@@ -1230,6 +1234,10 @@ export type AppealS78Case = (
1230
1234
  * New conditions details provided by the LPA
1231
1235
  */
1232
1236
  newConditionDetails: string | null;
1237
+ /**
1238
+ * extra conditions details provided by the LPA
1239
+ */
1240
+ extraConditionsDetails?: string | null;
1233
1241
  /**
1234
1242
  * A list of related case references known to the appellant and the LPA
1235
1243
  */
@@ -1584,6 +1592,20 @@ export type AppealS78Case = (
1584
1592
  [k: string]: unknown;
1585
1593
  }[]
1586
1594
  | null;
1595
+ /**
1596
+ * A list of grounds for the appeal, supporting facts & start dates. Enforcement cases (C) can have grounds (a) to (g)
1597
+ */
1598
+ applicationElbAppealGroundsDetails?:
1599
+ | {
1600
+ appealGroundLetter?: 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | null;
1601
+ groundForAppealStartDate?: string | null;
1602
+ /**
1603
+ * Facts supporting the appeal ground
1604
+ */
1605
+ groundFacts?: string | null;
1606
+ [k: string]: unknown;
1607
+ }[]
1608
+ | null;
1587
1609
  /**
1588
1610
  * Was an application made and paid for
1589
1611
  */
@@ -3745,66 +3767,10 @@ export type AppellantEnforcementSubmissionProperties = (
3745
3767
  siteAddressPostcode: string;
3746
3768
  }
3747
3769
  ) & {
3748
- /**
3749
- * Case submission id - link to draft submission created by appellant
3750
- */
3751
- submissionId: string;
3752
- /**
3753
- * The type of procedure for the appeal
3754
- */
3755
- caseProcedure: 'written' | 'hearing' | 'inquiry';
3756
- /**
3757
- * A unique identifier for the Local Planning Authority
3758
- */
3759
- lpaCode: string;
3760
- /**
3761
- * The date the appeal was submitted by the appellant
3762
- */
3763
- caseSubmittedDate: string;
3764
- /**
3765
- * Indicates if an enforcement notice is the reason for the appeal
3766
- */
3767
- enforcementNotice: boolean | null;
3768
- /**
3769
- * The unique identifier of the enforcement notice
3770
- */
3771
- enforcementReference: string;
3772
- /**
3773
- * The date the enforcement notice was issued
3774
- */
3775
- enforcementIssueDate: string;
3776
- /**
3777
- * The date the enforcement notice took effect
3778
- */
3779
- enforcementEffectiveDate: string;
3780
- /**
3781
- * The date the enforcement notice took effect
3782
- */
3783
- contactPlanningInspectorateDate?: string | null;
3784
- /**
3785
- * The individual's interest in the appeal land
3786
- */
3787
- interestInLand?: string | null;
3788
- /**
3789
- * If required, whether the individual has permission to use the appeal land
3790
- */
3791
- writtenOrVerbalPermission?: string | null;
3792
- /**
3793
- * A description of the alleged breach
3794
- */
3795
- descriptionOfAllegedBreach?: string | null;
3796
3770
  /**
3797
3771
  * Whether a planning application was made
3798
3772
  */
3799
3773
  applicationMadeAndFeePaid?: boolean | null;
3800
- /**
3801
- * Whether a retrospective planning application was made
3802
- */
3803
- retrospectiveApplication?: boolean | null;
3804
- /**
3805
- * Whether a ground (a) fee has been paid
3806
- */
3807
- groundAFeePaid?: boolean | null;
3808
3774
  /**
3809
3775
  * Did the application relate to all or part of the development
3810
3776
  */
@@ -3841,10 +3807,6 @@ export type AppellantEnforcementSubmissionProperties = (
3841
3807
  * The date of the appeal against the original LPA decision
3842
3808
  */
3843
3809
  appealDecisionDate?: string | null;
3844
- /**
3845
- * The statutory deadline for submitting an appeal from the original LPA decision date
3846
- */
3847
- caseSubmissionDueDate: string | null;
3848
3810
  /**
3849
3811
  * First line of address for the appeal site
3850
3812
  */
@@ -3865,8 +3827,6 @@ export type AppellantEnforcementSubmissionProperties = (
3865
3827
  * Postal code of the site address
3866
3828
  */
3867
3829
  siteAddressPostcode?: string | null;
3868
- siteGridReferenceEasting?: string | null;
3869
- siteGridReferenceNorthing?: string | null;
3870
3830
  /**
3871
3831
  * First line of address for the appeal site
3872
3832
  */
@@ -3887,44 +3847,22 @@ export type AppellantEnforcementSubmissionProperties = (
3887
3847
  * Postal code of the site address
3888
3848
  */
3889
3849
  contactAddressPostcode?: string | null;
3890
- contactGridReferenceEasting?: string | null;
3891
- contactGridReferenceNorthing?: string | null;
3892
- /**
3893
- * Provided information on site accessibility
3894
- */
3895
- siteAccessDetails?: string[] | null;
3896
- /**
3897
- * Provided information on site health and safety
3898
- */
3899
- siteSafetyDetails?: string[] | null;
3900
- /**
3901
- * Indicates if the appellant has applied for costs
3902
- */
3903
- appellantCostsAppliedFor?: boolean | null;
3904
- /**
3905
- * The procedure preference indicated by the appellant
3906
- */
3907
- appellantProcedurePreference?: 'written' | 'hearing' | 'inquiry' | null;
3908
- /**
3909
- * The procedure details preference indicated by the appellant
3910
- */
3911
- appellantProcedurePreferenceDetails?: string | null;
3912
- /**
3913
- * The duration of the procedure indicated by the appellant
3914
- */
3915
- appellantProcedurePreferenceDuration?: number | null;
3850
+ siteGridReferenceEasting?: string | null;
3851
+ siteGridReferenceNorthing?: string | null;
3916
3852
  /**
3917
- * The number of witnesses appellant has suggested for inquiries preference
3853
+ * Whether a retrospective planning application was made
3918
3854
  */
3919
- appellantProcedurePreferenceWitnessCount?: number | null;
3855
+ retrospectiveApplication?: boolean | null;
3856
+ contactGridReferenceEasting?: string | null;
3857
+ contactGridReferenceNorthing?: string | null;
3920
3858
  /**
3921
- * The planning obligation information, if available
3859
+ * Whether a ground (a) fee has been paid
3922
3860
  */
3923
- statusPlanningObligation?: string | null;
3861
+ groundAFeePaid?: boolean | null;
3924
3862
  /**
3925
- * A list of related case references known to the appellant and the LPA
3863
+ * If required, whether the individual has permission to use the appeal land
3926
3864
  */
3927
- nearbyCaseReferences?: string[] | null;
3865
+ writtenOrVerbalPermission?: string | null;
3928
3866
  /**
3929
3867
  * A list of individuals named on the enforcement notice
3930
3868
  */
@@ -3943,7 +3881,7 @@ export type AppellantEnforcementSubmissionProperties = (
3943
3881
  */
3944
3882
  interestInLand: string;
3945
3883
  /**
3946
- * Whether the individual has permission to use the land
3884
+ * If required, whether the individual has permission to use the appeal land
3947
3885
  */
3948
3886
  writtenOrVerbalPermission: string | null;
3949
3887
  [k: string]: unknown;
@@ -4003,6 +3941,7 @@ export interface AppellantSubmissionCommand {
4003
3941
  | ({
4004
3942
  caseType?: 'C';
4005
3943
  } & AppellantEnforcementSubmissionProperties &
3944
+ AppellantEnforcementCommonSubmissionProperties &
4006
3945
  AppellantProcedurePreferenceProperties)
4007
3946
  | ({
4008
3947
  caseType?: 'X';
@@ -4012,7 +3951,8 @@ export interface AppellantSubmissionCommand {
4012
3951
  LDCSpecificProperties)
4013
3952
  | ({
4014
3953
  caseType?: 'F';
4015
- } & AppellantEnforcementSubmissionProperties &
3954
+ } & AppellantEnforcementCommonSubmissionProperties &
3955
+ AppellantEnforcementListedBuildingSubmissionProperties &
4016
3956
  AppellantProcedurePreferenceProperties);
4017
3957
  documents: {
4018
3958
  /**
@@ -4240,6 +4180,96 @@ export interface AdvertSpecificProperties {
4240
4180
  | null;
4241
4181
  [k: string]: unknown;
4242
4182
  }
4183
+ /**
4184
+ * Schema defining any common properties for enforcement appeals
4185
+ */
4186
+ export interface AppellantEnforcementCommonSubmissionProperties {
4187
+ /**
4188
+ * Case submission id - link to draft submission created by appellant
4189
+ */
4190
+ submissionId: string;
4191
+ /**
4192
+ * A description of the alleged breach
4193
+ */
4194
+ descriptionOfAllegedBreach?: string | null;
4195
+ /**
4196
+ * The type of procedure for the appeal
4197
+ */
4198
+ caseProcedure: 'written' | 'hearing' | 'inquiry';
4199
+ /**
4200
+ * A unique identifier for the Local Planning Authority
4201
+ */
4202
+ lpaCode: string;
4203
+ /**
4204
+ * The date the appeal was submitted by the appellant
4205
+ */
4206
+ caseSubmittedDate: string;
4207
+ /**
4208
+ * Indicates if an enforcement notice is the reason for the appeal
4209
+ */
4210
+ enforcementNotice: boolean | null;
4211
+ /**
4212
+ * The unique identifier of the enforcement notice
4213
+ */
4214
+ enforcementReference: string;
4215
+ /**
4216
+ * The date the enforcement notice was issued
4217
+ */
4218
+ enforcementIssueDate: string;
4219
+ /**
4220
+ * The date the enforcement notice took effect
4221
+ */
4222
+ enforcementEffectiveDate: string;
4223
+ /**
4224
+ * The date the enforcement notice took effect
4225
+ */
4226
+ contactPlanningInspectorateDate?: string | null;
4227
+ /**
4228
+ * The individual's interest in the appeal land
4229
+ */
4230
+ interestInLand?: string | null;
4231
+ /**
4232
+ * The statutory deadline for submitting an appeal from the original LPA decision date
4233
+ */
4234
+ caseSubmissionDueDate: string | null;
4235
+ /**
4236
+ * Provided information on site accessibility
4237
+ */
4238
+ siteAccessDetails?: string[] | null;
4239
+ /**
4240
+ * Provided information on site health and safety
4241
+ */
4242
+ siteSafetyDetails?: string[] | null;
4243
+ /**
4244
+ * Indicates if the appellant has applied for costs
4245
+ */
4246
+ appellantCostsAppliedFor?: boolean | null;
4247
+ /**
4248
+ * The procedure preference indicated by the appellant
4249
+ */
4250
+ appellantProcedurePreference?: 'written' | 'hearing' | 'inquiry' | null;
4251
+ /**
4252
+ * The procedure details preference indicated by the appellant
4253
+ */
4254
+ appellantProcedurePreferenceDetails?: string | null;
4255
+ /**
4256
+ * The duration of the procedure indicated by the appellant
4257
+ */
4258
+ appellantProcedurePreferenceDuration?: number | null;
4259
+ /**
4260
+ * The number of witnesses appellant has suggested for inquiries preference
4261
+ */
4262
+ appellantProcedurePreferenceWitnessCount?: number | null;
4263
+ /**
4264
+ * The planning obligation information, if available
4265
+ */
4266
+ statusPlanningObligation?: string | null;
4267
+ /**
4268
+ * A list of related case references known to the appellant and the LPA
4269
+ */
4270
+ nearbyCaseReferences?: string[] | null;
4271
+ [k: string]: unknown;
4272
+ }
4243
4273
  /**
4244
4274
  * Schema defining any properties for ldc appeals
4245
4275
  */
@@ -4255,6 +4285,88 @@ export interface LDCSpecificProperties {
4255
4285
  | null;
4256
4286
  [k: string]: unknown;
4257
4287
  }
4288
+ /**
4289
+ * Schema defining any properties for enforcement listed building appeals
4290
+ */
4291
+ export interface AppellantEnforcementListedBuildingSubmissionProperties {
4292
+ /**
4293
+ * A list of individuals named on the enforcement notice
4294
+ */
4295
+ namedIndividuals?:
4296
+ | {
4297
+ /**
4298
+ * First name of the individual
4299
+ */
4300
+ firstName: string;
4301
+ /**
4302
+ * Last name of the individual
4303
+ */
4304
+ lastName: string;
4305
+ /**
4306
+ * Individual's interest in the appeal land
4307
+ */
4308
+ interestInLand: string;
4309
+ [k: string]: unknown;
4310
+ }[]
4311
+ | null;
4312
+ /**
4313
+ * First line of address for the appeal site
4314
+ */
4315
+ siteAddressLine1?: string | null;
4316
+ /**
4317
+ * Second line of address for the appeal site
4318
+ */
4319
+ siteAddressLine2?: string | null;
4320
+ /**
4321
+ * Town / City of the site address
4322
+ */
4323
+ siteAddressTown?: string | null;
4324
+ /**
4325
+ * County of the site address
4326
+ */
4327
+ siteAddressCounty?: string | null;
4328
+ /**
4329
+ * Postal code of the site address
4330
+ */
4331
+ siteAddressPostcode?: string | null;
4332
+ /**
4333
+ * First line of address for the appeal site
4334
+ */
4335
+ contactAddressLine1?: string | null;
4336
+ /**
4337
+ * Second line of address for the appeal site
4338
+ */
4339
+ contactAddressLine2?: string | null;
4340
+ /**
4341
+ * Town / City of the site address
4342
+ */
4343
+ contactAddressTown?: string | null;
4344
+ /**
4345
+ * County of the site address
4346
+ */
4347
+ contactAddressCounty?: string | null;
4348
+ /**
4349
+ * Postal code of the site address
4350
+ */
4351
+ contactAddressPostcode?: string | null;
4352
+ /**
4353
+ * A list of appeal grounds being pleaded
4354
+ */
4355
+ appealGrounds?:
4356
+ | {
4357
+ /**
4358
+ * Name of the appeal ground
4359
+ */
4360
+ groundRef: 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k';
4361
+ /**
4362
+ * Facts supporting the appeal ground
4363
+ */
4364
+ factsForGround: string;
4365
+ [k: string]: unknown;
4366
+ }[]
4367
+ | null;
4368
+ [k: string]: unknown;
4369
+ }
4258
4370
 
4259
4371
  export type Name = string;
4260
4372
 
@@ -40,18 +40,6 @@ const exampleEnforcementListedSubmissionSchema = {
40
40
  enforcementEffectiveDate: '1890-12-28T22:49:47.0Z',
41
41
  contactPlanningInspectorateDate: null,
42
42
  interestInLand: 'owner',
43
- writtenOrVerbalPermission: null,
44
- descriptionOfAllegedBreach: 'a new chimney',
45
- applicationMadeAndFeePaid: true,
46
- applicationDevelopmentAllOrPart: 'all-of-the-development',
47
- originalDevelopmentDescription: 'in amet',
48
- changedDevelopmentDescription: true,
49
- applicationReference: '43010/APP/1/290572',
50
- applicationDate: '1890-12-28T22:49:47.0Z',
51
- applicationDecision: 'granted',
52
- applicationDecisionAppealed: false,
53
- applicationDecisionDate: '1890-12-28T22:49:47.0Z',
54
- appealDecisionDate: null,
55
43
  caseSubmissionDueDate: null,
56
44
  siteAddressLine1: 'occaecat aliquip non pariatur consequat',
57
45
  siteAddressLine2: null,
@@ -65,8 +53,6 @@ const exampleEnforcementListedSubmissionSchema = {
65
53
  contactAddressTown: null,
66
54
  contactAddressCounty: null,
67
55
  contactAddressPostcode: null,
68
- contactGridReferenceEasting: null,
69
- contactGridReferenceNorthing: null,
70
56
  siteAccessDetails: ['laborum', 'aute velit quis', 'dolor'],
71
57
  siteSafetyDetails: ['velit aliqua', 'qui', 'tempor Duis ut dolore', 'anim Ut in ea', 'eiusmod laborum'],
72
58
  appellantCostsAppliedFor: false,
@@ -80,8 +66,7 @@ const exampleEnforcementListedSubmissionSchema = {
80
66
  {
81
67
  firstName: 'Bob',
82
68
  lastName: 'Bobberson',
83
- interestInLand: 'owner',
84
- writtenOrVerbalPermission: 'yes'
69
+ interestInLand: 'owner'
85
70
  }
86
71
  ],
87
72
  appealGrounds: [
@@ -106,56 +91,12 @@ describe(' listed building submission command schema', () => {
106
91
  assert.strictEqual(validationResult, true);
107
92
  });
108
93
 
109
- it('should enforce eastings-northings pattern', () => {
110
- const invalidPatterns = [
111
- { easting: 'abc123', northing: '400534', description: 'easting with letters' },
112
- { easting: '1234567*', northing: '400534', description: 'easting too long' },
113
- { easting: '12345', northing: '400534', description: 'easting too short' },
114
- { easting: '357144', northing: 'xyz123', description: 'northing with letters' },
115
- { easting: '357144', northing: '12345678', description: 'northing too long' },
116
- { easting: '357144', northing: '12345', description: 'northing too short' },
117
- { easting: '', northing: '400534', description: 'empty easting' },
118
- { easting: '357144', northing: '', description: 'empty northing' }
119
- ];
120
-
121
- for (const pattern of invalidPatterns) {
122
- const test = structuredClone(exampleEnforcementListedSubmissionSchema);
123
- test.casedata.siteGridReferenceEasting = pattern.easting;
124
- test.casedata.siteGridReferenceNorthing = pattern.northing;
125
-
126
- const validationResult = ajv.validate(schema, test);
127
- assert.strictEqual(validationResult, false, `Expected validation to fail for ${pattern.description}`);
128
- }
129
- });
130
-
131
- it('should allow only eastings-northings', () => {
132
- const test = structuredClone(exampleEnforcementListedSubmissionSchema);
133
- test.casedata.siteAddressPostcode = undefined;
134
- test.casedata.siteAddressLine1 = null;
135
- test.casedata.siteAddressTown = null;
136
- const validationResult = ajv.validate(schema, test);
137
- assert.strictEqual(validationResult, true);
138
- });
139
-
140
94
  it('should allow only site address', () => {
141
95
  const test = structuredClone(exampleEnforcementListedSubmissionSchema);
142
- test.casedata.siteGridReferenceEasting = undefined;
143
- test.casedata.siteGridReferenceNorthing = null;
144
96
  const validationResult = ajv.validate(schema, test);
145
97
  assert.strictEqual(validationResult, true);
146
98
  });
147
99
 
148
- it('should enforce either site address or easting-northing', () => {
149
- const test = structuredClone(exampleEnforcementListedSubmissionSchema);
150
- test.casedata.siteAddressPostcode = undefined;
151
- test.casedata.siteAddressLine1 = null;
152
- test.casedata.siteAddressTown = null;
153
- test.casedata.siteGridReferenceEasting = undefined;
154
- test.casedata.siteGridReferenceNorthing = null;
155
- const validationResult = ajv.validate(schema, test);
156
- assert.strictEqual(validationResult, false);
157
- });
158
-
159
100
  it('should reject missing root property', () => {
160
101
  const test = structuredClone(exampleEnforcementListedSubmissionSchema);
161
102
  delete test.casedata.caseType;