@planning-inspectorate/data-model 1.18.1 → 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.
- package/.github/dependabot.yml +5 -0
- package/package.json +3 -3
- package/schemas/commands/lpa-questionnaire-cas-advert.schema.json +95 -0
- package/schemas/commands/lpa-questionnaire.schema.json +3 -1
- package/src/schemas.d.ts +118 -1
- package/tests/appeals/commands/adverts-questionnaire.test.js +15 -9
- package/tests/appeals/commands/cas-adverts-questionnaire.test.js +98 -0
package/.github/dependabot.yml
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planning-inspectorate/data-model",
|
|
3
|
-
"version": "1.
|
|
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": "^
|
|
34
|
-
"@commitlint/config-conventional": "^
|
|
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",
|
|
@@ -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
|
]
|
package/src/schemas.d.ts
CHANGED
|
@@ -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('
|
|
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
|
+
});
|