@pdtf/schemas 3.6.0-35 → 3.6.0-36

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/README.md +33 -52
  2. package/docs/sef25-extensions-ui-spec.md +49 -258
  3. package/index.js +0 -9
  4. package/package.json +1 -1
  5. package/src/examples/v3/exampleTransaction.json +3 -3
  6. package/src/schemas/v3/combined.json +32 -279
  7. package/src/schemas/v3/compactSkeleton.txt +2 -16
  8. package/src/schemas/v3/overlays/extensions/as.json +2 -4
  9. package/src/schemas/v3/overlays/extensions/dr.json +2 -4
  10. package/src/schemas/v3/overlays/extensions/er.json +2 -4
  11. package/src/schemas/v3/overlays/extensions/fd.json +3 -6
  12. package/src/schemas/v3/overlays/extensions/hi.json +3 -6
  13. package/src/schemas/v3/overlays/extensions/hs.json +2 -4
  14. package/src/schemas/v3/overlays/extensions/jk.json +2 -4
  15. package/src/schemas/v3/overlays/extensions/la.json +2 -4
  16. package/src/schemas/v3/overlays/extensions/ma.json +3 -6
  17. package/src/schemas/v3/overlays/extensions/mc.json +2 -4
  18. package/src/schemas/v3/overlays/extensions/oa.json +2 -4
  19. package/src/schemas/v3/overlays/extensions/oc.json +2 -4
  20. package/src/schemas/v3/overlays/extensions/pc.json +1 -2
  21. package/src/schemas/v3/overlays/extensions/ph.json +14 -11
  22. package/src/schemas/v3/overlays/extensions/sb.json +2 -4
  23. package/src/schemas/v3/overlays/extensions/sc.json +14 -82
  24. package/src/schemas/v3/overlays/extensions/sf.json +2 -4
  25. package/src/schemas/v3/overlays/extensions/sl.json +2 -4
  26. package/src/schemas/v3/overlays/extensions/tf.json +3 -6
  27. package/src/schemas/v3/overlays/sef25.json +10 -727
  28. package/src/schemas/v3/pdtf-transaction.json +15 -227
  29. package/src/schemas/v3/skeleton.json +5 -24
  30. package/src/tests/v3/extensionOverlays.test.js +5 -411
  31. package/src/utils/extractExtensionOverlays.js +4 -116
  32. package/src/schemas/v3/overlays/extensions/dk.json +0 -32
  33. package/src/schemas/v3/overlays/extensions/ic.json +0 -59
  34. package/src/schemas/v3/overlays/extensions/lc.json +0 -86
  35. package/src/schemas/v3/overlays/extensions/mi.json +0 -55
  36. package/src/schemas/v3/overlays/extensions/nd.json +0 -43
  37. package/src/schemas/v3/overlays/extensions/rw.json +0 -68
  38. package/src/schemas/v3/overlays/extensions/sd.json +0 -63
  39. package/src/schemas/v3/overlays/extensions/tr.json +0 -73
  40. package/src/schemas/v3/overlays/extensions/wg.json +0 -250
@@ -165,15 +165,6 @@ describe("Extension Overlays", () => {
165
165
  "sc",
166
166
  "pc",
167
167
  "ph", // SEF25
168
- "dk",
169
- "rw",
170
- "sd",
171
- "lc",
172
- "wg",
173
- "ic",
174
- "nd",
175
- "mi",
176
- "tr", // SEF25 (new)
177
168
  ];
178
169
 
179
170
  expect(Object.keys(extensionOverlays).sort()).toEqual(
@@ -495,14 +486,9 @@ describe("Extension Overlays", () => {
495
486
  const cost = noBranch?.properties?.associatedCost;
496
487
  expect(cost).toBeDefined();
497
488
  expect(cost.ntsRef).toBe("U1.1");
498
- expect(cost.required).toEqual(["hasCost"]);
499
- expect(cost.properties.hasCost.type).toBe("string");
500
- expect(cost.oneOf).toHaveLength(2);
501
- // Yes branch should have amount and frequency
502
- const yesBranch = cost.oneOf[1];
503
- expect(yesBranch.properties.amount.type).toBe("number");
504
- expect(yesBranch.properties.frequency.type).toBe("string");
505
- expect(yesBranch.required).toEqual(["amount", "frequency"]);
489
+ expect(cost.required).toEqual(["amount", "frequency"]);
490
+ expect(cost.properties.amount.type).toBe("number");
491
+ expect(cost.properties.frequency.type).toBe("string");
506
492
  });
507
493
 
508
494
  test("should merge supply costs extension into mainsFoulDrainage No/Not known branch", () => {
@@ -518,7 +504,7 @@ describe("Extension Overlays", () => {
518
504
  const cost = noBranch?.properties?.associatedCost;
519
505
  expect(cost).toBeDefined();
520
506
  expect(cost.ntsRef).toBe("U1.2");
521
- expect(cost.required).toEqual(["hasCost"]);
507
+ expect(cost.required).toEqual(["amount", "frequency"]);
522
508
  });
523
509
 
524
510
  test("should merge parking permit cost and frequency into controlledParking Yes branch", () => {
@@ -648,7 +634,6 @@ describe("Extension Overlays", () => {
648
634
  yesNo: "No",
649
635
  details: "Private borehole",
650
636
  associatedCost: {
651
- hasCost: "Yes",
652
637
  amount: 50,
653
638
  frequency: "Per month",
654
639
  },
@@ -657,24 +642,6 @@ describe("Extension Overlays", () => {
657
642
  expect(result).toBe(true);
658
643
  });
659
644
 
660
- test("should validate private water with no associated costs", () => {
661
- const validator = getSubschemaValidator(
662
- "/propertyPack/waterAndDrainage/water/mainsWater",
663
- schemaId,
664
- overlays
665
- );
666
-
667
- const result = validator({
668
- yesNo: "No",
669
- details: "Private borehole",
670
- associatedCost: {
671
- hasCost: "No",
672
- },
673
- });
674
-
675
- expect(result).toBe(true);
676
- });
677
-
678
645
  test("should require associated cost for private water supply", () => {
679
646
  const validator = getSubschemaValidator(
680
647
  "/propertyPack/waterAndDrainage/water/mainsWater",
@@ -702,7 +669,6 @@ describe("Extension Overlays", () => {
702
669
  yesNo: "No",
703
670
  details: "Borehole",
704
671
  associatedCost: {
705
- hasCost: "Yes",
706
672
  amount: 100,
707
673
  frequency: "Weekly",
708
674
  },
@@ -722,7 +688,6 @@ describe("Extension Overlays", () => {
722
688
  yesNo: "No",
723
689
  details: "Borehole",
724
690
  associatedCost: {
725
- hasCost: "Yes",
726
691
  amount: "fifty pounds",
727
692
  frequency: "Per month",
728
693
  },
@@ -742,7 +707,6 @@ describe("Extension Overlays", () => {
742
707
  const result = validator({
743
708
  yesNo: "No",
744
709
  associatedCost: {
745
- hasCost: "Yes",
746
710
  amount: 200,
747
711
  frequency: "Per year",
748
712
  },
@@ -761,7 +725,6 @@ describe("Extension Overlays", () => {
761
725
  const result = validator({
762
726
  yesNo: "No",
763
727
  associatedCost: {
764
- hasCost: "Yes",
765
728
  amount: 200,
766
729
  frequency: "Quarterly",
767
730
  },
@@ -987,381 +950,12 @@ describe("Extension Overlays", () => {
987
950
  expect(si?.required).toContain("japaneseKnotweed");
988
951
  expect(si?.required).toContain("ongoingHealthOrSafetyIssue");
989
952
 
990
- // SEF25 hazards also present
953
+ // SEF25 hazards also present (remapped to ntsRef in extension overlays)
991
954
  expect(si?.properties?.wellsDitchesShaft?.ntsRef).toBe("H1.1");
992
955
  expect(si?.properties?.knownAreasInPoorCondition?.ntsRef).toBe(
993
956
  "H1.4"
994
957
  );
995
958
  });
996
959
  });
997
-
998
- describe("Dropped kerb (dk)", () => {
999
- test("should validate Yes answer", () => {
1000
- const validator = getSubschemaValidator(
1001
- "/propertyPack/parking/droppedKerbAccess",
1002
- schemaId,
1003
- ["dk"]
1004
- );
1005
- expect(validator({ yesNo: "Yes" })).toBe(true);
1006
- });
1007
-
1008
- test("should validate No answer", () => {
1009
- const validator = getSubschemaValidator(
1010
- "/propertyPack/parking/droppedKerbAccess",
1011
- schemaId,
1012
- ["dk"]
1013
- );
1014
- expect(validator({ yesNo: "No" })).toBe(true);
1015
- });
1016
-
1017
- test("should reject invalid value", () => {
1018
- const validator = getSubschemaValidator(
1019
- "/propertyPack/parking/droppedKerbAccess",
1020
- schemaId,
1021
- ["dk"]
1022
- );
1023
- expect(validator({ yesNo: "Maybe" })).toBe(false);
1024
- });
1025
-
1026
- test("should not be required without dk overlay", () => {
1027
- const schema = getTransactionSchema(schemaId, ["baspiV5"]);
1028
- const parking = schema.properties?.propertyPack?.properties?.parking;
1029
- expect(parking?.required || []).not.toContain("droppedKerbAccess");
1030
- });
1031
-
1032
- test("should be required with dk overlay", () => {
1033
- const schema = getTransactionSchema(schemaId, ["dk"]);
1034
- const parking = schema.properties?.propertyPack?.properties?.parking;
1035
- expect(parking?.required).toContain("droppedKerbAccess");
1036
- });
1037
- });
1038
-
1039
- describe("Private right of way (rw)", () => {
1040
- test("should validate No answer", () => {
1041
- const validator = getSubschemaValidator(
1042
- "/propertyPack/rightsAndInformalArrangements/rightsOrArrangements/privateRightOfWay",
1043
- schemaId,
1044
- ["rw"]
1045
- );
1046
- expect(validator({ yesNo: "No" })).toBe(true);
1047
- });
1048
-
1049
- test("should validate Yes with details", () => {
1050
- const validator = getSubschemaValidator(
1051
- "/propertyPack/rightsAndInformalArrangements/rightsOrArrangements/privateRightOfWay",
1052
- schemaId,
1053
- ["rw"]
1054
- );
1055
- expect(validator({ yesNo: "Yes", details: "Neighbour has access through garden" })).toBe(true);
1056
- });
1057
-
1058
- test("should reject Yes without details", () => {
1059
- const validator = getSubschemaValidator(
1060
- "/propertyPack/rightsAndInformalArrangements/rightsOrArrangements/privateRightOfWay",
1061
- schemaId,
1062
- ["rw"]
1063
- );
1064
- expect(validator({ yesNo: "Yes" })).toBe(false);
1065
- });
1066
-
1067
- test("should reject Yes with empty details", () => {
1068
- const validator = getSubschemaValidator(
1069
- "/propertyPack/rightsAndInformalArrangements/rightsOrArrangements/privateRightOfWay",
1070
- schemaId,
1071
- ["rw"]
1072
- );
1073
- expect(validator({ yesNo: "Yes", details: "" })).toBe(false);
1074
- });
1075
-
1076
- test("should not be required without rw overlay", () => {
1077
- const schema = getTransactionSchema(schemaId, ["baspiV5"]);
1078
- const rights = schema.properties?.propertyPack?.properties?.rightsAndInformalArrangements
1079
- ?.properties?.rightsOrArrangements;
1080
- expect(rights?.required || []).not.toContain("privateRightOfWay");
1081
- });
1082
-
1083
- test("should be required with rw overlay", () => {
1084
- const schema = getTransactionSchema(schemaId, ["rw"]);
1085
- const rights = schema.properties?.propertyPack?.properties?.rightsAndInformalArrangements
1086
- ?.properties?.rightsOrArrangements;
1087
- expect(rights?.required).toContain("privateRightOfWay");
1088
- });
1089
- });
1090
-
1091
- describe("Storm/fire/flood damage (sd)", () => {
1092
- test("should validate No answer", () => {
1093
- const validator = getSubschemaValidator(
1094
- "/propertyPack/environmentalIssues/stormFireFloodDamage",
1095
- schemaId,
1096
- ["sd"]
1097
- );
1098
- expect(validator({ yesNo: "No" })).toBe(true);
1099
- });
1100
-
1101
- test("should validate Yes with details", () => {
1102
- const validator = getSubschemaValidator(
1103
- "/propertyPack/environmentalIssues/stormFireFloodDamage",
1104
- schemaId,
1105
- ["sd"]
1106
- );
1107
- expect(validator({ yesNo: "Yes", details: "Flood damage in 2020" })).toBe(true);
1108
- });
1109
-
1110
- test("should reject Yes without details", () => {
1111
- const validator = getSubschemaValidator(
1112
- "/propertyPack/environmentalIssues/stormFireFloodDamage",
1113
- schemaId,
1114
- ["sd"]
1115
- );
1116
- expect(validator({ yesNo: "Yes" })).toBe(false);
1117
- });
1118
-
1119
- test("should not be required without sd overlay", () => {
1120
- const schema = getTransactionSchema(schemaId, ["baspiV5"]);
1121
- const env = schema.properties?.propertyPack?.properties?.environmentalIssues;
1122
- expect(env?.required || []).not.toContain("stormFireFloodDamage");
1123
- });
1124
-
1125
- test("should be required with sd overlay", () => {
1126
- const schema = getTransactionSchema(schemaId, ["sd"]);
1127
- const env = schema.properties?.propertyPack?.properties?.environmentalIssues;
1128
- expect(env?.required).toContain("stormFireFloodDamage");
1129
- });
1130
- });
1131
-
1132
- describe("Solar lease costs (lc)", () => {
1133
- test("should validate No costs", () => {
1134
- const validator = getSubschemaValidator(
1135
- "/propertyPack/electricity/solarPanels/panelsOwnedOutright/associatedCost",
1136
- schemaId,
1137
- ["lc"]
1138
- );
1139
- expect(validator({ hasCost: "No" })).toBe(true);
1140
- });
1141
-
1142
- test("should validate Yes with amount and frequency", () => {
1143
- const validator = getSubschemaValidator(
1144
- "/propertyPack/electricity/solarPanels/panelsOwnedOutright/associatedCost",
1145
- schemaId,
1146
- ["lc"]
1147
- );
1148
- expect(validator({ hasCost: "Yes", amount: 75, frequency: "Per month" })).toBe(true);
1149
- });
1150
-
1151
- test("should reject Yes without amount", () => {
1152
- const validator = getSubschemaValidator(
1153
- "/propertyPack/electricity/solarPanels/panelsOwnedOutright/associatedCost",
1154
- schemaId,
1155
- ["lc"]
1156
- );
1157
- expect(validator({ hasCost: "Yes", frequency: "Per month" })).toBe(false);
1158
- });
1159
-
1160
- test("should reject Yes without frequency", () => {
1161
- const validator = getSubschemaValidator(
1162
- "/propertyPack/electricity/solarPanels/panelsOwnedOutright/associatedCost",
1163
- schemaId,
1164
- ["lc"]
1165
- );
1166
- expect(validator({ hasCost: "Yes", amount: 75 })).toBe(false);
1167
- });
1168
-
1169
- test("should reject invalid frequency", () => {
1170
- const validator = getSubschemaValidator(
1171
- "/propertyPack/electricity/solarPanels/panelsOwnedOutright/associatedCost",
1172
- schemaId,
1173
- ["lc"]
1174
- );
1175
- expect(validator({ hasCost: "Yes", amount: 75, frequency: "Weekly" })).toBe(false);
1176
- });
1177
- });
1178
-
1179
- describe("Warranties and guarantees (wg)", () => {
1180
- const warrantyCategoryPaths = [
1181
- { path: "newHomeWarranty", ref: "W1.1" },
1182
- { path: "roofingWork", ref: "W1.2" },
1183
- { path: "dampProofingTreatment", ref: "W1.3" },
1184
- { path: "centralHeatingAndorPlumbing", ref: "W1.4" },
1185
- { path: "electricalRepairOrInstallation", ref: "W1.5" },
1186
- { path: "subsidenceWork", ref: "W1.6" },
1187
- { path: "otherGuarantees", ref: "W1.7" },
1188
- ];
1189
-
1190
- test("should have ntsRef on all warranty categories when wg overlay loaded", () => {
1191
- const schema = getTransactionSchema(schemaId, ["baspiV5", "wg"]);
1192
- const warranties =
1193
- schema.properties?.propertyPack?.properties?.guaranteesWarrantiesAndIndemnityInsurances;
1194
-
1195
- // Warranty fields are in oneOf[1] (hasValidGuaranteesOrWarranties = Yes)
1196
- const yesBranch = warranties.oneOf[1];
1197
-
1198
- warrantyCategoryPaths.forEach(({ path, ref }) => {
1199
- expect(yesBranch.properties[path]?.ntsRef).toBe(ref);
1200
- });
1201
- });
1202
-
1203
- test("should mark warranty categories as required when wg overlay loaded", () => {
1204
- const schema = getTransactionSchema(schemaId, ["baspiV5", "wg"]);
1205
- const warranties =
1206
- schema.properties?.propertyPack?.properties?.guaranteesWarrantiesAndIndemnityInsurances;
1207
-
1208
- const yesBranch = warranties.oneOf[1];
1209
- warrantyCategoryPaths.forEach(({ path }) => {
1210
- expect(yesBranch.required).toContain(path);
1211
- });
1212
- });
1213
-
1214
- test("should not require warranty categories without any overlay", () => {
1215
- const schema = getTransactionSchema(schemaId, []);
1216
- const warranties =
1217
- schema.properties?.propertyPack?.properties?.guaranteesWarrantiesAndIndemnityInsurances;
1218
-
1219
- const yesBranch = warranties.oneOf[1];
1220
- // Without any overlay, warranty categories should not be in required
1221
- expect(yesBranch.required || []).not.toContain("newHomeWarranty");
1222
- expect(yesBranch.required || []).not.toContain("electricalRepairOrInstallation");
1223
- });
1224
- });
1225
-
1226
- describe("Insurance claims (ic)", () => {
1227
- test("should mark insuranceClaims as required in isInsured=Yes branch", () => {
1228
- const schema = getTransactionSchema(schemaId, ["ic"]);
1229
- const insurance = schema.properties?.propertyPack?.properties?.insurance;
1230
- // oneOf[1] is isInsured=Yes
1231
- const yesBranch = insurance.oneOf[1];
1232
- expect(yesBranch?.required).toContain("insuranceClaims");
1233
- });
1234
-
1235
- test("should validate insuranceClaims No answer", () => {
1236
- const validator = getSubschemaValidator(
1237
- "/propertyPack/insurance/insuranceClaims",
1238
- schemaId,
1239
- ["baspiV5", "ic"]
1240
- );
1241
- expect(validator({ yesNo: "No" })).toBe(true);
1242
- });
1243
-
1244
- test("should validate insuranceClaims Yes with details", () => {
1245
- const validator = getSubschemaValidator(
1246
- "/propertyPack/insurance/insuranceClaims",
1247
- schemaId,
1248
- ["baspiV5", "ic"]
1249
- );
1250
- expect(validator({ yesNo: "Yes", details: "Storm damage claim in 2019" })).toBe(true);
1251
- });
1252
- });
1253
-
1254
- describe("Neighbour development (nd)", () => {
1255
- test("should add ntsRef to neighbourDevelopment", () => {
1256
- const schema = getTransactionSchema(schemaId, ["nd"]);
1257
- const nd = schema.properties?.propertyPack?.properties?.notices
1258
- ?.properties?.neighbourDevelopment;
1259
- expect(nd?.ntsRef).toBe("N1.1");
1260
- });
1261
-
1262
- test("should add ntsRef via nd overlay", () => {
1263
- const schema = getTransactionSchema(schemaId, ["nd"]);
1264
- const notices = schema.properties?.propertyPack?.properties?.notices;
1265
- expect(notices?.ntsRef).toBe("N1");
1266
- });
1267
-
1268
- test("should validate No answer", () => {
1269
- const validator = getSubschemaValidator(
1270
- "/propertyPack/notices/neighbourDevelopment",
1271
- schemaId,
1272
- ["baspiV5", "nd"]
1273
- );
1274
- expect(validator({ yesNo: "No" })).toBe(true);
1275
- });
1276
- });
1277
-
1278
- describe("Other material issue (mi)", () => {
1279
- test("should mark otherMaterialIssue as required", () => {
1280
- const schema = getTransactionSchema(schemaId, ["mi"]);
1281
- const additional = schema.properties?.propertyPack?.properties?.additionalInformation;
1282
- expect(additional?.required).toContain("otherMaterialIssue");
1283
- });
1284
-
1285
- test("should not require otherMaterialIssue without mi overlay", () => {
1286
- const schema = getTransactionSchema(schemaId, []);
1287
- const additional = schema.properties?.propertyPack?.properties?.additionalInformation;
1288
- expect(additional?.required || []).not.toContain("otherMaterialIssue");
1289
- });
1290
-
1291
- test("should validate No answer", () => {
1292
- const validator = getSubschemaValidator(
1293
- "/propertyPack/additionalInformation/otherMaterialIssue",
1294
- schemaId,
1295
- ["baspiV5", "mi"]
1296
- );
1297
- expect(validator({ yesNo: "No" })).toBe(true);
1298
- });
1299
-
1300
- test("should validate Yes with details", () => {
1301
- const validator = getSubschemaValidator(
1302
- "/propertyPack/additionalInformation/otherMaterialIssue",
1303
- schemaId,
1304
- ["baspiV5", "mi"]
1305
- );
1306
- expect(validator({ yesNo: "Yes", details: "Previous subsidence issues" })).toBe(true);
1307
- });
1308
- });
1309
-
1310
- describe("Title restrictions (tr)", () => {
1311
- test("should require titleRestrictions in freehold branch with tr overlay", () => {
1312
- const schema = getTransactionSchema(schemaId, ["tr"]);
1313
- const items = schema.properties?.propertyPack?.properties?.ownership
1314
- ?.properties?.ownershipsToBeTransferred?.items;
1315
- // oneOf[0] is Freehold
1316
- const freeholdBranch = items.oneOf[0];
1317
- expect(freeholdBranch?.properties?.titleRestrictions).toBeDefined();
1318
- expect(freeholdBranch?.required).toContain("titleRestrictions");
1319
- });
1320
-
1321
- test("should not require titleRestrictions without tr overlay", () => {
1322
- const schema = getTransactionSchema(schemaId, ["baspiV5"]);
1323
- const items = schema.properties?.propertyPack?.properties?.ownership
1324
- ?.properties?.ownershipsToBeTransferred?.items;
1325
- const freeholdBranch = items.oneOf[0];
1326
- expect(freeholdBranch?.required || []).not.toContain("titleRestrictions");
1327
- });
1328
-
1329
- test("should have correct ntsRef", () => {
1330
- const schema = getTransactionSchema(schemaId, ["tr"]);
1331
- const items = schema.properties?.propertyPack?.properties?.ownership
1332
- ?.properties?.ownershipsToBeTransferred?.items;
1333
- const freeholdBranch = items.oneOf[0];
1334
- expect(freeholdBranch?.properties?.titleRestrictions?.ntsRef).toBe("T1.1");
1335
- });
1336
- });
1337
-
1338
- describe("All SEF25 extensions combined", () => {
1339
- const allSef25 = ["sc", "pc", "ph", "dk", "rw", "sd", "lc", "wg", "ic", "nd", "mi", "tr"];
1340
-
1341
- test("should load all SEF25 extensions together without error", () => {
1342
- const schema = getTransactionSchema(schemaId, ["baspiV5", ...allSef25]);
1343
- expect(schema).toBeDefined();
1344
- expect(schema.properties?.propertyPack).toBeDefined();
1345
- });
1346
-
1347
- test("should not interfere with existing NTS2 extensions when combined", () => {
1348
- const schema = getTransactionSchema(schemaId, ["nts2025", ...allSef25]);
1349
-
1350
- // NTS2 fields still work
1351
- const si = schema.properties?.propertyPack?.properties?.specialistIssues;
1352
- expect(si?.properties?.wellsDitchesShaft?.ntsRef).toBe("H1.1");
1353
-
1354
- // New SEF25 fields present
1355
- const parking = schema.properties?.propertyPack?.properties?.parking?.properties;
1356
- expect(parking?.droppedKerbAccess).toBeDefined();
1357
-
1358
- const env = schema.properties?.propertyPack?.properties?.environmentalIssues?.properties;
1359
- expect(env?.stormFireFloodDamage).toBeDefined();
1360
-
1361
- const rights = schema.properties?.propertyPack?.properties?.rightsAndInformalArrangements
1362
- ?.properties?.rightsOrArrangements?.properties;
1363
- expect(rights?.privateRightOfWay).toBeDefined();
1364
- });
1365
- });
1366
960
  });
1367
961
  });
@@ -214,97 +214,10 @@ const extensionMappings = {
214
214
  description: "Property hazards and known issues",
215
215
  refType: "sef25Ref",
216
216
  paths: [
217
- "/properties/propertyPack/properties/specialistIssues",
218
- ],
219
- },
220
-
221
- // Dropped kerb access to parking
222
- dk: {
223
- name: "droppedKerbAccess",
224
- description: "Dropped kerb access to parking",
225
- refType: "sef25Ref",
226
- paths: [
227
- "/properties/propertyPack/properties/parking/properties/droppedKerbAccess",
228
- ],
229
- },
230
-
231
- // Private right of way
232
- rw: {
233
- name: "privateRightOfWay",
234
- description: "Private right of way",
235
- refType: "sef25Ref",
236
- paths: [
237
- "/properties/propertyPack/properties/rightsAndInformalArrangements/properties/rightsOrArrangements/properties/privateRightOfWay",
238
- ],
239
- },
240
-
241
- // Storm, fire or flood damage
242
- sd: {
243
- name: "stormFireFloodDamage",
244
- description: "Storm, fire or flood damage",
245
- refType: "sef25Ref",
246
- paths: [
247
- "/properties/propertyPack/properties/environmentalIssues/properties/stormFireFloodDamage",
248
- ],
249
- },
250
-
251
- // Solar panel lease costs
252
- lc: {
253
- name: "solarLeaseCosts",
254
- description: "Solar panel lease costs",
255
- refType: "sef25Ref",
256
- paths: [
257
- "/properties/propertyPack/properties/electricity/properties/solarPanels/oneOf/1/properties/panelsOwnedOutright/oneOf/1/properties/associatedCost",
258
- ],
259
- },
260
-
261
- // Warranties and guarantees upfront
262
- wg: {
263
- name: "warrantiesGuarantees",
264
- description: "Warranties and guarantees upfront Y/N for SEF25",
265
- refType: "sef25Ref",
266
- paths: [
267
- "/properties/propertyPack/properties/guaranteesWarrantiesAndIndemnityInsurances",
268
- ],
269
- },
270
-
271
- // Insurance claims upfront
272
- ic: {
273
- name: "insuranceClaims",
274
- description: "Insurance claims upfront for SEF25",
275
- refType: "sef25Ref",
276
- paths: [
277
- "/properties/propertyPack/properties/insurance/oneOf/1/properties/insuranceClaims",
278
- ],
279
- },
280
-
281
- // Neighbour development upfront
282
- nd: {
283
- name: "neighbourDevelopment",
284
- description: "Neighbour development upfront for SEF25",
285
- refType: "sef25Ref",
286
- paths: [
287
- "/properties/propertyPack/properties/notices/properties/neighbourDevelopment",
288
- ],
289
- },
290
-
291
- // Other material issue upfront
292
- mi: {
293
- name: "otherMaterialIssue",
294
- description: "Other material issue upfront for SEF25",
295
- refType: "sef25Ref",
296
- paths: [
297
- "/properties/propertyPack/properties/additionalInformation/properties/otherMaterialIssue",
298
- ],
299
- },
300
-
301
- // Title restrictions for freehold
302
- tr: {
303
- name: "titleRestrictions",
304
- description: "Title restrictions for freehold properties",
305
- refType: "sef25Ref",
306
- paths: [
307
- "/properties/propertyPack/properties/ownership/properties/ownershipsToBeTransferred/items/oneOf/0/properties/titleRestrictions",
217
+ "/properties/propertyPack/properties/specialistIssues/properties/wellsDitchesShaft",
218
+ "/properties/propertyPack/properties/specialistIssues/properties/damagedOrExposedElectrics",
219
+ "/properties/propertyPack/properties/specialistIssues/properties/damageToFlooringOrStaircases",
220
+ "/properties/propertyPack/properties/specialistIssues/properties/knownAreasInPoorCondition",
308
221
  ],
309
222
  },
310
223
  };
@@ -492,28 +405,6 @@ function addRequiredArrays(overlay, schema, refConfig) {
492
405
  return overlay;
493
406
  }
494
407
 
495
- // Annotate intermediate nodes with refs from the source schema
496
- // This ensures every level of the overlay tree carries an ntsRef
497
- function addIntermediateRefs(overlay, schema, refConfig) {
498
- traverse(overlay).forEach(function (node) {
499
- if (node && typeof node === "object" && !Array.isArray(node) && node.properties) {
500
- // Skip if this node already has a ref
501
- if (node[refConfig.outputRef]) return;
502
-
503
- const schemaPath = "/" + this.path.join("/");
504
- try {
505
- const schemaNode = jp.get(schema, schemaPath);
506
- if (schemaNode && schemaNode[refConfig.ref]) {
507
- node[refConfig.outputRef] = schemaNode[refConfig.ref];
508
- }
509
- } catch (err) {
510
- // Path doesn't exist in schema, skip
511
- }
512
- }
513
- });
514
- return overlay;
515
- }
516
-
517
408
  // Generate extension overlays
518
409
  Object.entries(extensionMappings).forEach(([code, config]) => {
519
410
  const refType = config.refType || "nts2Ref";
@@ -527,9 +418,6 @@ Object.entries(extensionMappings).forEach(([code, config]) => {
527
418
  // Add required arrays where needed
528
419
  overlay = addRequiredArrays(overlay, combinedSchema, refConfig);
529
420
 
530
- // Add refs to intermediate nodes in the path hierarchy
531
- overlay = addIntermediateRefs(overlay, combinedSchema, refConfig);
532
-
533
421
  // Add schema metadata
534
422
  overlay.$schema = "http://json-schema.org/draft-07/schema#";
535
423
  overlay.$id = `https://trust.propdata.org.uk/schemas/v3/overlays/extensions/${code}.json`;
@@ -1,32 +0,0 @@
1
- {
2
- "properties": {
3
- "propertyPack": {
4
- "properties": {
5
- "parking": {
6
- "properties": {
7
- "droppedKerbAccess": {
8
- "ntsRef": "K1.1",
9
- "required": [
10
- "yesNo"
11
- ],
12
- "properties": {
13
- "yesNo": {
14
- "ntsRef": "K1.1.1",
15
- "type": "string"
16
- }
17
- },
18
- "type": "object"
19
- }
20
- },
21
- "required": [
22
- "droppedKerbAccess"
23
- ],
24
- "ntsRef": "K1"
25
- }
26
- }
27
- }
28
- },
29
- "$schema": "http://json-schema.org/draft-07/schema#",
30
- "$id": "https://trust.propdata.org.uk/schemas/v3/overlays/extensions/dk.json",
31
- "$comment": "Dropped kerb access to parking"
32
- }