@pdtf/schemas 3.6.0-18 → 3.6.0-19

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.
@@ -49,7 +49,8 @@
49
49
  "Bash(claude --version)",
50
50
  "Bash(gh pr list --head ta6ed6 --json number,title,url)",
51
51
  "Bash(gh pr:*)",
52
- "Bash(sort -t'.' -k1,1n -k2,2n -k3,3n -k4,4n)"
52
+ "Bash(sort -t'.' -k1,1n -k2,2n -k3,3n -k4,4n)",
53
+ "Bash(wc -l /Users/ed/Code/schemas/src/schemas/v3/combined.json /Users/ed/Code/schemas/src/schemas/v3/overlays/*.json)"
53
54
  ],
54
55
  "deny": []
55
56
  }
@@ -0,0 +1,146 @@
1
+ # SEF25 Extension Overlays — Front-End UI Spec
2
+
3
+ ## Overview
4
+
5
+ Three new extension overlays add follow-up questions to existing form sections. Each overlay is loaded by passing its key to `getTransactionSchema(schemaId, overlays)`.
6
+
7
+ | Overlay Key | Name | Section | Fields Added |
8
+ |-------------|------|---------|-------------|
9
+ | `sc` | Supply Costs | Water & Drainage | 2 cost fields (private water, private sewerage) |
10
+ | `pc` | Parking Permit Cost | Parking | 1 frequency field |
11
+ | `ph` | Property Hazards | Specialist Issues | 4 Yes/No + details fields |
12
+
13
+ All fields use `sef25Ref` for reference codes.
14
+
15
+ ---
16
+
17
+ ## 1. Supply Costs (`sc`)
18
+
19
+ ### 1a. Private Water Cost
20
+
21
+ **Trigger:** Show when `propertyPack.waterAndDrainage.water.mainsWater.yesNo` = `"No"`
22
+
23
+ **Path:** `propertyPack.waterAndDrainage.water.mainsWater.associatedCost`
24
+
25
+ **UI:** Render alongside the existing "How is water supplied?" details field.
26
+
27
+ | Field | Path (relative) | Type | Validation | UI Element |
28
+ |-------|-----------------|------|------------|------------|
29
+ | Cost (£) | `associatedCost.amount` | `number` | Required | Numeric input |
30
+ | Payment frequency | `associatedCost.frequency` | `string` | Required, enum | Dropdown |
31
+
32
+ **Frequency enum values:** `"Per month"`, `"Per year"`
33
+
34
+ **Ref:** `U1.1` (amount: `U1.1.1`, frequency: `U1.1.2`)
35
+
36
+ ### 1b. Private Sewerage Cost
37
+
38
+ **Trigger:** Show when `propertyPack.waterAndDrainage.drainage.mainsFoulDrainage.yesNo` = `"No"` or `"Not known"`
39
+
40
+ **Path:** `propertyPack.waterAndDrainage.drainage.mainsFoulDrainage.associatedCost`
41
+
42
+ **UI:** Render alongside the existing off-mains drainage system questions.
43
+
44
+ | Field | Path (relative) | Type | Validation | UI Element |
45
+ |-------|-----------------|------|------------|------------|
46
+ | Cost (£) | `associatedCost.amount` | `number` | Required | Numeric input |
47
+ | Payment frequency | `associatedCost.frequency` | `string` | Required, enum | Dropdown |
48
+
49
+ **Frequency enum values:** `"Per month"`, `"Per year"`
50
+
51
+ **Ref:** `U1.2` (amount: `U1.2.1`, frequency: `U1.2.2`)
52
+
53
+ ---
54
+
55
+ ## 2. Parking Permit Cost (`pc`)
56
+
57
+ **Trigger:** Show when `propertyPack.parking.controlledParking.yesNo` = `"Yes"`
58
+
59
+ **Path:** `propertyPack.parking.controlledParking.costOfPermitFrequency`
60
+
61
+ **UI:** Render alongside the existing cost of permit field (previously titled "Annual cost of permit (£)", now retitled to "Cost of permit (£)"). The frequency dropdown clarifies whether the cost amount is monthly or annual.
62
+
63
+ | Field | Path (relative) | Type | Validation | UI Element |
64
+ |-------|-----------------|------|------------|------------|
65
+ | Payment frequency | `costOfPermitFrequency` | `string` | Enum | Dropdown |
66
+
67
+ **Frequency enum values:** `"Per month"`, `"Per year"`
68
+
69
+ **Note:** The existing `annualCostOfPermit` numeric field remains unchanged. The new frequency field sits beside it to indicate whether the entered amount is per month or per year.
70
+
71
+ **Ref:** `P1.1`
72
+
73
+ ---
74
+
75
+ ## 3. Property Hazards (`ph`)
76
+
77
+ **Trigger:** Always shown (no conditional trigger — these are standalone questions within Specialist Issues).
78
+
79
+ **Path prefix:** `propertyPack.specialistIssues`
80
+
81
+ All 4 fields follow the same pattern:
82
+
83
+ - **Initial question:** Yes/No radio/toggle
84
+ - **If "Yes":** Show a required free-text "Give details" field
85
+
86
+ ### Fields
87
+
88
+ | Property | Title | sef25Ref |
89
+ |----------|-------|----------|
90
+ | `wellsDitchesShaft` | Are there any wells, ditches, or shafts at the property? | H1.1 |
91
+ | `damagedOrExposedElectrics` | Are there any damaged or exposed electrics at the property? | H1.2 |
92
+ | `damageToFlooringOrStaircases` | Is there any damage to flooring and/or staircases? | H1.3 |
93
+ | `knownAreasInPoorCondition` | Are there any known areas in poor condition (internal or external)? | H1.4 |
94
+
95
+ ### Data shape per field
96
+
97
+ ```json
98
+ // When "No":
99
+ { "yesNo": "No" }
100
+
101
+ // When "Yes":
102
+ { "yesNo": "Yes", "details": "Free text description..." }
103
+ ```
104
+
105
+ ### Validation
106
+
107
+ - `yesNo` is required (enum: `["Yes", "No"]`)
108
+ - When `yesNo` = `"Yes"`, `details` is required (string, minLength: 1)
109
+ - When `yesNo` = `"No"`, `details` should not be shown or submitted
110
+
111
+ ### UI pattern
112
+
113
+ These follow the identical pattern to existing specialist issues (dry rot, asbestos, subsidence, health & safety). Render them the same way — group them under "Hazards and Known Issues" within the Specialist Issues section.
114
+
115
+ ---
116
+
117
+ ## Loading the Extensions
118
+
119
+ ```js
120
+ import { getTransactionSchema, getValidator } from "@pdtf/schemas";
121
+
122
+ const schemaId = "https://trust.propdata.org.uk/schemas/v3/pdtf-transaction.json";
123
+
124
+ // Load with one or more SEF25 extensions
125
+ const schema = getTransactionSchema(schemaId, ["sc", "pc", "ph"]);
126
+
127
+ // Or combine with other overlays
128
+ const schema = getTransactionSchema(schemaId, ["baspiV5", "sc", "pc", "ph"]);
129
+
130
+ // Validate data against the merged schema
131
+ const validator = getValidator(schemaId, ["sc", "pc", "ph"]);
132
+ ```
133
+
134
+ ---
135
+
136
+ ## Summary of Trigger Conditions
137
+
138
+ | Field | Visible when... |
139
+ |-------|----------------|
140
+ | Water cost | `mainsWater.yesNo` = `"No"` |
141
+ | Sewerage cost | `mainsFoulDrainage.yesNo` = `"No"` or `"Not known"` |
142
+ | Parking permit frequency | `controlledParking.yesNo` = `"Yes"` |
143
+ | Wells/ditches/shaft | Always (within Specialist Issues) |
144
+ | Damaged electrics | Always (within Specialist Issues) |
145
+ | Flooring/staircase damage | Always (within Specialist Issues) |
146
+ | Areas in poor condition | Always (within Specialist Issues) |
package/index.js CHANGED
@@ -52,6 +52,11 @@ const extensionOverlays = {
52
52
 
53
53
  // Transaction Extensions
54
54
  oc: require("./src/schemas/v3/overlays/extensions/oc.json"),
55
+
56
+ // SEF25 Extensions
57
+ sc: require("./src/schemas/v3/overlays/extensions/sc.json"),
58
+ pc: require("./src/schemas/v3/overlays/extensions/pc.json"),
59
+ ph: require("./src/schemas/v3/overlays/extensions/ph.json"),
55
60
  };
56
61
 
57
62
  const overlaysMap = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pdtf/schemas",
3
- "version": "3.6.0-18",
3
+ "version": "3.6.0-19",
4
4
  "description": "Property Data Trust Framework Schemas and Utilities",
5
5
  "main": "index.js",
6
6
  "directories": {
@@ -10362,8 +10362,14 @@
10362
10362
  },
10363
10363
  "annualCostOfPermit": {
10364
10364
  "baspi5Ref": "A1.6.0.2.2",
10365
- "title": "Annual cost of permit (£)",
10365
+ "title": "Cost of permit (£)",
10366
10366
  "type": "number"
10367
+ },
10368
+ "costOfPermitFrequency": {
10369
+ "sef25Ref": "P1.1",
10370
+ "title": "Payment frequency",
10371
+ "type": "string",
10372
+ "enum": ["Per month", "Per year"]
10367
10373
  }
10368
10374
  },
10369
10375
  "baspi5Required": ["annualCostOfPermit"]
@@ -16008,6 +16014,166 @@
16008
16014
  "ntsl2Required": ["details"]
16009
16015
  }
16010
16016
  ]
16017
+ },
16018
+ "wellsDitchesShaft": {
16019
+ "sef25Ref": "H1.1",
16020
+ "title": "Are there any wells, ditches, or shafts at the property?",
16021
+ "type": "object",
16022
+ "sef25Required": ["yesNo"],
16023
+ "properties": {
16024
+ "yesNo": {
16025
+ "sef25Ref": "H1.1.1",
16026
+ "type": "string",
16027
+ "title": "",
16028
+ "enum": ["Yes", "No"]
16029
+ }
16030
+ },
16031
+ "discriminator": {
16032
+ "propertyName": "yesNo"
16033
+ },
16034
+ "oneOf": [
16035
+ {
16036
+ "properties": {
16037
+ "yesNo": {
16038
+ "enum": ["No"]
16039
+ }
16040
+ }
16041
+ },
16042
+ {
16043
+ "sef25Required": ["details"],
16044
+ "properties": {
16045
+ "yesNo": {
16046
+ "enum": ["Yes"]
16047
+ },
16048
+ "details": {
16049
+ "sef25Ref": "H1.1.2",
16050
+ "title": "Give details",
16051
+ "type": "string",
16052
+ "minLength": 1
16053
+ }
16054
+ }
16055
+ }
16056
+ ]
16057
+ },
16058
+ "damagedOrExposedElectrics": {
16059
+ "sef25Ref": "H1.2",
16060
+ "title": "Are there any damaged or exposed electrics at the property?",
16061
+ "type": "object",
16062
+ "sef25Required": ["yesNo"],
16063
+ "properties": {
16064
+ "yesNo": {
16065
+ "sef25Ref": "H1.2.1",
16066
+ "type": "string",
16067
+ "title": "",
16068
+ "enum": ["Yes", "No"]
16069
+ }
16070
+ },
16071
+ "discriminator": {
16072
+ "propertyName": "yesNo"
16073
+ },
16074
+ "oneOf": [
16075
+ {
16076
+ "properties": {
16077
+ "yesNo": {
16078
+ "enum": ["No"]
16079
+ }
16080
+ }
16081
+ },
16082
+ {
16083
+ "sef25Required": ["details"],
16084
+ "properties": {
16085
+ "yesNo": {
16086
+ "enum": ["Yes"]
16087
+ },
16088
+ "details": {
16089
+ "sef25Ref": "H1.2.2",
16090
+ "title": "Give details",
16091
+ "type": "string",
16092
+ "minLength": 1
16093
+ }
16094
+ }
16095
+ }
16096
+ ]
16097
+ },
16098
+ "damageToFlooringOrStaircases": {
16099
+ "sef25Ref": "H1.3",
16100
+ "title": "Is there any damage to flooring and/or staircases?",
16101
+ "type": "object",
16102
+ "sef25Required": ["yesNo"],
16103
+ "properties": {
16104
+ "yesNo": {
16105
+ "sef25Ref": "H1.3.1",
16106
+ "type": "string",
16107
+ "title": "",
16108
+ "enum": ["Yes", "No"]
16109
+ }
16110
+ },
16111
+ "discriminator": {
16112
+ "propertyName": "yesNo"
16113
+ },
16114
+ "oneOf": [
16115
+ {
16116
+ "properties": {
16117
+ "yesNo": {
16118
+ "enum": ["No"]
16119
+ }
16120
+ }
16121
+ },
16122
+ {
16123
+ "sef25Required": ["details"],
16124
+ "properties": {
16125
+ "yesNo": {
16126
+ "enum": ["Yes"]
16127
+ },
16128
+ "details": {
16129
+ "sef25Ref": "H1.3.2",
16130
+ "title": "Give details",
16131
+ "type": "string",
16132
+ "minLength": 1
16133
+ }
16134
+ }
16135
+ }
16136
+ ]
16137
+ },
16138
+ "knownAreasInPoorCondition": {
16139
+ "sef25Ref": "H1.4",
16140
+ "title": "Are there any known areas in poor condition (internal or external)?",
16141
+ "type": "object",
16142
+ "sef25Required": ["yesNo"],
16143
+ "properties": {
16144
+ "yesNo": {
16145
+ "sef25Ref": "H1.4.1",
16146
+ "type": "string",
16147
+ "title": "",
16148
+ "enum": ["Yes", "No"]
16149
+ }
16150
+ },
16151
+ "discriminator": {
16152
+ "propertyName": "yesNo"
16153
+ },
16154
+ "oneOf": [
16155
+ {
16156
+ "properties": {
16157
+ "yesNo": {
16158
+ "enum": ["No"]
16159
+ }
16160
+ }
16161
+ },
16162
+ {
16163
+ "sef25Required": ["details"],
16164
+ "properties": {
16165
+ "yesNo": {
16166
+ "enum": ["Yes"]
16167
+ },
16168
+ "details": {
16169
+ "sef25Ref": "H1.4.2",
16170
+ "title": "Give details",
16171
+ "type": "string",
16172
+ "minLength": 1
16173
+ }
16174
+ }
16175
+ }
16176
+ ]
16011
16177
  }
16012
16178
  }
16013
16179
  },
@@ -22143,6 +22309,25 @@
22143
22309
  "description": "e.g. Private well, borehole, springs etc.",
22144
22310
  "type": "string",
22145
22311
  "minLength": 1
22312
+ },
22313
+ "associatedCost": {
22314
+ "sef25Ref": "U1.1",
22315
+ "title": "Associated costs for water",
22316
+ "type": "object",
22317
+ "sef25Required": ["amount", "frequency"],
22318
+ "properties": {
22319
+ "amount": {
22320
+ "sef25Ref": "U1.1.1",
22321
+ "title": "Cost (£)",
22322
+ "type": "number"
22323
+ },
22324
+ "frequency": {
22325
+ "sef25Ref": "U1.1.2",
22326
+ "title": "Payment frequency",
22327
+ "type": "string",
22328
+ "enum": ["Per month", "Per year"]
22329
+ }
22330
+ }
22146
22331
  }
22147
22332
  },
22148
22333
  "ntsRequired": ["details"],
@@ -23156,6 +23341,25 @@
23156
23341
  "ntsl2Required": ["details"]
23157
23342
  }
23158
23343
  ]
23344
+ },
23345
+ "associatedCost": {
23346
+ "sef25Ref": "U1.2",
23347
+ "title": "Associated costs for sewerage",
23348
+ "type": "object",
23349
+ "sef25Required": ["amount", "frequency"],
23350
+ "properties": {
23351
+ "amount": {
23352
+ "sef25Ref": "U1.2.1",
23353
+ "title": "Cost (£)",
23354
+ "type": "number"
23355
+ },
23356
+ "frequency": {
23357
+ "sef25Ref": "U1.2.2",
23358
+ "title": "Payment frequency",
23359
+ "type": "string",
23360
+ "enum": ["Per month", "Per year"]
23361
+ }
23362
+ }
23159
23363
  }
23160
23364
  },
23161
23365
  "ntsRequired": ["offMainsDrainageSystem"],
@@ -951,6 +951,7 @@
951
951
  controlledParking
952
952
  yesNo
953
953
  annualCostOfPermit
954
+ costOfPermitFrequency
954
955
  vehicleTypeRestriction
955
956
  yesNo
956
957
  details
@@ -1390,6 +1391,18 @@
1390
1391
  yesNo
1391
1392
  details
1392
1393
  attachments
1394
+ wellsDitchesShaft
1395
+ yesNo
1396
+ details
1397
+ damagedOrExposedElectrics
1398
+ yesNo
1399
+ details
1400
+ damageToFlooringOrStaircases
1401
+ yesNo
1402
+ details
1403
+ knownAreasInPoorCondition
1404
+ yesNo
1405
+ details
1393
1406
  fixturesAndFittings
1394
1407
  itemsToRemove
1395
1408
  yesNo
@@ -1910,6 +1923,9 @@
1910
1923
  mainsWater
1911
1924
  yesNo
1912
1925
  details
1926
+ associatedCost
1927
+ amount
1928
+ frequency
1913
1929
  supplier
1914
1930
  stopcock
1915
1931
  location
@@ -1965,6 +1981,9 @@
1965
1981
  dateLastServiced
1966
1982
  attachments
1967
1983
  details
1984
+ associatedCost
1985
+ amount
1986
+ frequency
1968
1987
  surfaceDrainageCharge
1969
1988
  yesNo
1970
1989
  details
@@ -33,6 +33,9 @@
33
33
  "required": [
34
34
  "managementPlanInPlace"
35
35
  ],
36
+ "discriminator": {
37
+ "propertyName": "managementPlanInPlace"
38
+ },
36
39
  "properties": {
37
40
  "managementPlanInPlace": {
38
41
  "ntsRef": "A5.3.2",
@@ -47,14 +50,29 @@
47
50
  "enum": [
48
51
  "Yes"
49
52
  ]
53
+ }
54
+ },
55
+ "oneOf": [
56
+ {
57
+ "properties": {
58
+ "managementPlanInPlace": {
59
+ "enum": [
60
+ "No",
61
+ "Not known"
62
+ ]
63
+ }
64
+ }
50
65
  },
51
- "attachments": {
52
- "enum": [
53
- "Attached",
54
- "To follow"
55
- ]
66
+ {
67
+ "properties": {
68
+ "managementPlanInPlace": {
69
+ "enum": [
70
+ "Yes"
71
+ ]
72
+ }
73
+ }
56
74
  }
57
- }
75
+ ]
58
76
  }
59
77
  ],
60
78
  "type": "object"
@@ -0,0 +1,28 @@
1
+ {
2
+ "properties": {
3
+ "propertyPack": {
4
+ "properties": {
5
+ "parking": {
6
+ "properties": {
7
+ "controlledParking": {
8
+ "oneOf": [
9
+ null,
10
+ {
11
+ "properties": {
12
+ "costOfPermitFrequency": {
13
+ "sef25Ref": "P1.1",
14
+ "type": "string"
15
+ }
16
+ }
17
+ }
18
+ ]
19
+ }
20
+ }
21
+ }
22
+ }
23
+ }
24
+ },
25
+ "$schema": "http://json-schema.org/draft-07/schema#",
26
+ "$id": "https://trust.propdata.org.uk/schemas/v3/overlays/extensions/pc.json",
27
+ "$comment": "Parking permit cost and frequency"
28
+ }