@pdtf/schemas 3.6.0-dev.13 → 3.6.0-dev.15

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.
@@ -344,7 +344,8 @@
344
344
  "properties": {
345
345
  "isGroundRentPayable": {
346
346
  "enum": [
347
- "No"
347
+ "No",
348
+ "Not applicable"
348
349
  ]
349
350
  }
350
351
  }
@@ -566,7 +566,8 @@
566
566
  "properties": {
567
567
  "isGroundRentPayable": {
568
568
  "enum": [
569
- "No"
569
+ "No",
570
+ "Not applicable"
570
571
  ]
571
572
  }
572
573
  }
@@ -517,6 +517,10 @@
517
517
  "title": "Company number",
518
518
  "type": "string"
519
519
  },
520
+ "directorOrAuthorisedPerson": {
521
+ "title": "Director/authorised person",
522
+ "type": "string"
523
+ },
520
524
  "countryOfIncorporation": {
521
525
  "title": "Country of incorporation",
522
526
  "type": "string"
@@ -5613,7 +5617,8 @@
5613
5617
  "type": "string",
5614
5618
  "enum": [
5615
5619
  "Yes",
5616
- "No"
5620
+ "No",
5621
+ "Not applicable"
5617
5622
  ]
5618
5623
  }
5619
5624
  },
@@ -5622,7 +5627,8 @@
5622
5627
  "properties": {
5623
5628
  "isGroundRentPayable": {
5624
5629
  "enum": [
5625
- "No"
5630
+ "No",
5631
+ "Not applicable"
5626
5632
  ]
5627
5633
  }
5628
5634
  }
@@ -6460,7 +6466,14 @@
6460
6466
  "properties": {
6461
6467
  "year": {
6462
6468
  "title": "Year",
6463
- "type": "integer"
6469
+ "oneOf": [
6470
+ {
6471
+ "type": "integer"
6472
+ },
6473
+ {
6474
+ "const": "Not known"
6475
+ }
6476
+ ]
6464
6477
  },
6465
6478
  "from": {
6466
6479
  "title": "To",
@@ -6480,7 +6493,14 @@
6480
6493
  "properties": {
6481
6494
  "year": {
6482
6495
  "title": "Year",
6483
- "type": "integer"
6496
+ "oneOf": [
6497
+ {
6498
+ "type": "integer"
6499
+ },
6500
+ {
6501
+ "const": "Not known"
6502
+ }
6503
+ ]
6484
6504
  },
6485
6505
  "from": {
6486
6506
  "title": "To",
@@ -8807,7 +8827,8 @@
8807
8827
  "title": "",
8808
8828
  "enum": [
8809
8829
  "Yes",
8810
- "No"
8830
+ "No",
8831
+ "Not known"
8811
8832
  ]
8812
8833
  },
8813
8834
  "detailsAnalysis": {
@@ -8821,7 +8842,8 @@
8821
8842
  "properties": {
8822
8843
  "yesNo": {
8823
8844
  "enum": [
8824
- "No"
8845
+ "No",
8846
+ "Not known"
8825
8847
  ]
8826
8848
  }
8827
8849
  }
@@ -9742,11 +9764,89 @@
9742
9764
  "Yes"
9743
9765
  ]
9744
9766
  },
9767
+ "alterationTypes": {
9768
+ "title": "Which of the following alterations have been made to the property?",
9769
+ "type": "array",
9770
+ "items": {
9771
+ "type": "string",
9772
+ "enum": [
9773
+ "Replacement windows, roof windows, roof lights, glazed doors since 1 April 2002",
9774
+ "Extension",
9775
+ "Conservatory",
9776
+ "Loft conversion",
9777
+ "Garage conversion",
9778
+ "Removal of internal walls",
9779
+ "Removal of chimney breast",
9780
+ "Insulation",
9781
+ "Other building works or changes to the property"
9782
+ ]
9783
+ }
9784
+ },
9745
9785
  "details": {
9746
9786
  "title": "Please give details including dates of all work undertaken",
9747
9787
  "type": "string",
9748
9788
  "minLength": 1
9749
9789
  },
9790
+ "workCompleted": {
9791
+ "title": "Has all this work been completed?",
9792
+ "type": "object",
9793
+ "properties": {
9794
+ "yesNo": {
9795
+ "type": "string",
9796
+ "title": "",
9797
+ "enum": [
9798
+ "Yes",
9799
+ "No"
9800
+ ]
9801
+ }
9802
+ },
9803
+ "oneOf": [
9804
+ {
9805
+ "properties": {
9806
+ "yesNo": {
9807
+ "enum": [
9808
+ "Yes"
9809
+ ]
9810
+ }
9811
+ }
9812
+ },
9813
+ {
9814
+ "properties": {
9815
+ "yesNo": {
9816
+ "enum": [
9817
+ "No"
9818
+ ]
9819
+ },
9820
+ "details": {
9821
+ "title": "Give details of what remains to be completed",
9822
+ "type": "string",
9823
+ "minLength": 1
9824
+ }
9825
+ }
9826
+ }
9827
+ ]
9828
+ },
9829
+ "documents": {
9830
+ "title": "Supply copies of the planning permissions, building regulations approvals, completion certificates or competent person certificates for the work if you have them",
9831
+ "type": "string",
9832
+ "enum": [
9833
+ "Attached",
9834
+ "To follow",
9835
+ "Not available"
9836
+ ]
9837
+ },
9838
+ "approvalsObtained": {
9839
+ "title": "If any of the work was undertaken during your ownership, did you get planning permissions, building regulations approvals, completion certificates or competent person certificates when necessary?",
9840
+ "type": "string",
9841
+ "enum": [
9842
+ "Yes",
9843
+ "No"
9844
+ ]
9845
+ },
9846
+ "approvalsNotRequiredReason": {
9847
+ "title": "If planning permissions, building regulations approvals, completion certificates or competent person certificates were not required, explain why",
9848
+ "type": "string"
9849
+ },
9750
9850
  "buildingRegApproval": {
9751
9851
  "title": "Was Building Regulation approval and a completion certificate obtained or an equivalent Competent Person Scheme Certificate?",
9752
9852
  "type": "object",
@@ -19432,14 +19532,6 @@
19432
19532
  }
19433
19533
  }
19434
19534
  ]
19435
- },
19436
- "permitDocuments": {
19437
- "title": "Please supply a copy of any permit or other documents relating to the sewerage system.",
19438
- "type": "string",
19439
- "enum": [
19440
- "Attached",
19441
- "To follow"
19442
- ]
19443
19535
  }
19444
19536
  },
19445
19537
  "oneOf": [
@@ -19487,6 +19579,14 @@
19487
19579
  "title": "Date last emptied",
19488
19580
  "type": "string",
19489
19581
  "format": "date"
19582
+ },
19583
+ "permitDocuments": {
19584
+ "title": "Please supply a copy of any permit or other documents relating to the sewerage system.",
19585
+ "type": "string",
19586
+ "enum": [
19587
+ "Attached",
19588
+ "To follow"
19589
+ ]
19490
19590
  }
19491
19591
  }
19492
19592
  },
@@ -19525,6 +19625,14 @@
19525
19625
  "title": "Date last emptied",
19526
19626
  "type": "string",
19527
19627
  "format": "date"
19628
+ },
19629
+ "permitDocuments": {
19630
+ "title": "Please supply a copy of any permit or other documents relating to the sewerage system.",
19631
+ "type": "string",
19632
+ "enum": [
19633
+ "Attached",
19634
+ "To follow"
19635
+ ]
19528
19636
  }
19529
19637
  }
19530
19638
  },
@@ -19584,6 +19692,14 @@
19584
19692
  "To follow",
19585
19693
  "Not applicable"
19586
19694
  ]
19695
+ },
19696
+ "permitDocuments": {
19697
+ "title": "Please supply a copy of any permit or other documents relating to the sewerage system.",
19698
+ "type": "string",
19699
+ "enum": [
19700
+ "Attached",
19701
+ "To follow"
19702
+ ]
19587
19703
  }
19588
19704
  }
19589
19705
  },
@@ -19598,6 +19714,14 @@
19598
19714
  "details": {
19599
19715
  "title": "Details",
19600
19716
  "type": "string"
19717
+ },
19718
+ "permitDocuments": {
19719
+ "title": "Please supply a copy of any permit or other documents relating to the sewerage system.",
19720
+ "type": "string",
19721
+ "enum": [
19722
+ "Attached",
19723
+ "To follow"
19724
+ ]
19601
19725
  }
19602
19726
  }
19603
19727
  }
@@ -20395,6 +20519,110 @@
20395
20519
  }
20396
20520
  ]
20397
20521
  },
20522
+ "mainHeatingTypes": {
20523
+ "title": "How is the property heated?",
20524
+ "type": "array",
20525
+ "items": {
20526
+ "type": "string",
20527
+ "enum": [
20528
+ "Mains gas",
20529
+ "Oil",
20530
+ "Heat pumps",
20531
+ "Liquid gas",
20532
+ "Electricity",
20533
+ "Underfloor",
20534
+ "Woodburning / multi-fuel stove",
20535
+ "Other"
20536
+ ]
20537
+ }
20538
+ },
20539
+ "mainHeatingTypesOtherDetails": {
20540
+ "title": "If you selected 'Other', give details",
20541
+ "type": "string"
20542
+ },
20543
+ "heatingInstalledDate": {
20544
+ "title": "When was the heating system installed?",
20545
+ "type": "string",
20546
+ "oneOf": [
20547
+ {
20548
+ "format": "date"
20549
+ },
20550
+ {
20551
+ "enum": [
20552
+ "Not known"
20553
+ ]
20554
+ }
20555
+ ]
20556
+ },
20557
+ "boilerInstalledDate": {
20558
+ "title": "If there is a boiler (of any kind) when was it installed?",
20559
+ "type": "string",
20560
+ "oneOf": [
20561
+ {
20562
+ "format": "date"
20563
+ },
20564
+ {
20565
+ "enum": [
20566
+ "Not known"
20567
+ ]
20568
+ }
20569
+ ]
20570
+ },
20571
+ "heatingSystemReplaced": {
20572
+ "title": "Has there been any replacement to the heating system (other than replacement of a boiler)?",
20573
+ "type": "string",
20574
+ "enum": [
20575
+ "Yes",
20576
+ "No",
20577
+ "Not known"
20578
+ ]
20579
+ },
20580
+ "complianceCertificates": {
20581
+ "title": "Supply compliance certificates or documentation for the installation or alteration of each heating system",
20582
+ "type": "string",
20583
+ "enum": [
20584
+ "Attached",
20585
+ "To follow",
20586
+ "None"
20587
+ ]
20588
+ },
20589
+ "inspectionReport": {
20590
+ "title": "Supply a copy of the latest inspection report",
20591
+ "type": "string",
20592
+ "enum": [
20593
+ "Attached",
20594
+ "To follow",
20595
+ "None"
20596
+ ]
20597
+ },
20598
+ "inGoodWorkingOrder": {
20599
+ "title": "Is the boiler and heating system working?",
20600
+ "type": "string",
20601
+ "enum": [
20602
+ "Yes",
20603
+ "No",
20604
+ "Not known"
20605
+ ]
20606
+ },
20607
+ "lastServicedYear": {
20608
+ "title": "In what year was the boiler and heating system last serviced or maintained?",
20609
+ "oneOf": [
20610
+ {
20611
+ "type": "integer"
20612
+ },
20613
+ {
20614
+ "const": "Not known"
20615
+ }
20616
+ ]
20617
+ },
20618
+ "lastServicedReport": {
20619
+ "title": "Supply a copy of the service report",
20620
+ "type": "string",
20621
+ "enum": [
20622
+ "Attached",
20623
+ "To follow"
20624
+ ]
20625
+ },
20398
20626
  "otherHeatingFeatures": {
20399
20627
  "title": "What other heating features does the property have?",
20400
20628
  "type": "array",
@@ -21981,7 +22209,8 @@
21981
22209
  "type": "string",
21982
22210
  "enum": [
21983
22211
  "Yes",
21984
- "No"
22212
+ "No",
22213
+ "Not known"
21985
22214
  ]
21986
22215
  }
21987
22216
  },
@@ -21990,7 +22219,8 @@
21990
22219
  "properties": {
21991
22220
  "hasFloodDefences": {
21992
22221
  "enum": [
21993
- "No"
22222
+ "No",
22223
+ "Not known"
21994
22224
  ]
21995
22225
  }
21996
22226
  }
@@ -82,6 +82,7 @@
82
82
  "attachments": "string",
83
83
  "companyName": "string",
84
84
  "companyNumber": "string",
85
+ "directorOrAuthorisedPerson": "string",
85
86
  "countryOfIncorporation": "string"
86
87
  },
87
88
  "dateBecameOwnerOrAuthority": "string"
@@ -1004,12 +1005,12 @@
1004
1005
  },
1005
1006
  "lastDecoratedPeriod": {
1006
1007
  "externally": {
1007
- "year": "integer",
1008
+ "year": {},
1008
1009
  "from": "string",
1009
1010
  "to": "string"
1010
1011
  },
1011
1012
  "internally": {
1012
- "year": "integer",
1013
+ "year": {},
1013
1014
  "from": "string",
1014
1015
  "to": "string"
1015
1016
  }
@@ -1460,7 +1461,17 @@
1460
1461
  "hasStructuralAlterations": {
1461
1462
  "yesNo": "variant",
1462
1463
  "detailsAnalysis": {},
1464
+ "alterationTypes": [
1465
+ "string"
1466
+ ],
1463
1467
  "details": "string",
1468
+ "workCompleted": {
1469
+ "yesNo": "variant",
1470
+ "details": "string"
1471
+ },
1472
+ "documents": "string",
1473
+ "approvalsObtained": "string",
1474
+ "approvalsNotRequiredReason": "string",
1464
1475
  "buildingRegApproval": {
1465
1476
  "yesNo": "variant",
1466
1477
  "detailsAnalysis": {},
@@ -2559,11 +2570,11 @@
2559
2570
  },
2560
2571
  "dischargeCompliesWithGBR": "string"
2561
2572
  },
2562
- "permitDocuments": "string",
2563
2573
  "dateDischargeCommenced": {},
2564
2574
  "dateInstalled": "string",
2565
2575
  "dateReplaced": "string",
2566
2576
  "dateLastEmptied": "string",
2577
+ "permitDocuments": "string",
2567
2578
  "supplier": "string",
2568
2579
  "makeModel": "string",
2569
2580
  "serviceProviderName": "string",
@@ -2658,6 +2669,18 @@
2658
2669
  },
2659
2670
  "details": "string"
2660
2671
  },
2672
+ "mainHeatingTypes": [
2673
+ "string"
2674
+ ],
2675
+ "mainHeatingTypesOtherDetails": "string",
2676
+ "heatingInstalledDate": {},
2677
+ "boilerInstalledDate": {},
2678
+ "heatingSystemReplaced": "string",
2679
+ "complianceCertificates": "string",
2680
+ "inspectionReport": "string",
2681
+ "inGoodWorkingOrder": "string",
2682
+ "lastServicedYear": {},
2683
+ "lastServicedReport": "string",
2661
2684
  "otherHeatingFeatures": [
2662
2685
  "string"
2663
2686
  ],
@@ -30,6 +30,7 @@ const extractFields = [
30
30
  "ntsl2",
31
31
  "ta6",
32
32
  "ta6ed6",
33
+ "ta6ed6v2",
33
34
  "ta7",
34
35
  "ta7ed5",
35
36
  "ta10",
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Sync ta6ed6v2 markers from ta6ed6 across combined.json.
4
+ *
5
+ * ta6ed6v2 is a "full marker set" twin of ta6ed6: every shared field carries its
6
+ * own `ta6ed6v2*` markers so that inclusion is presence and suppression is the
7
+ * ABSENCE of a v2 ref (see src/tests/v3/ta6ed6v2.test.js — the drift-lint).
8
+ *
9
+ * Two subtrees intentionally diverge (their v2 shape is hand-authored) and are
10
+ * excluded from sync: propertyPack.heating and propertyPack.alterationsAndChanges.
11
+ *
12
+ * For every OTHER node, this tool guarantees each `ta6ed6<Suffix>` marker has a
13
+ * matching `ta6ed6v2<Suffix>` marker of equal value — adding missing twins and
14
+ * repairing drifted values. Edits are minimal text splices that preserve the
15
+ * file's existing formatting.
16
+ *
17
+ * node src/utils/syncTa6ed6v2Markers.js # apply (write)
18
+ * node src/utils/syncTa6ed6v2Markers.js --check # exit 1 if out of sync (CI)
19
+ *
20
+ * After running, regenerate overlays: node src/utils/extractOverlay.js
21
+ */
22
+ const fs = require("fs");
23
+ const path = require("path");
24
+
25
+ const FILE = process.env.COMBINED_PATH || path.resolve(__dirname, "../schemas/v3/combined.json");
26
+ const CHECK = process.argv.includes("--check");
27
+
28
+ const MARKER_RE = /^ta6ed6(Ref|Required|Title|Description|Enum|EnumNames)$/;
29
+ const v2Of = (k) => k.replace(/^ta6ed6/, "ta6ed6v2");
30
+ // NOTE: array indices are numbers in the tokenizer path (strict-equal), so use 2 not "2".
31
+ const COMPANY = ["properties", "participants", "items", "oneOf", 2, "properties", "sellersCapacity", "oneOf", 2, "properties"];
32
+ const EXCLUDED_PREFIXES = [
33
+ ["properties", "propertyPack", "properties", "heating"],
34
+ ["properties", "propertyPack", "properties", "alterationsAndChanges"],
35
+ // §1.6 company seller fields: v2 realigns refs to the form (companyNumber→1.6.1,
36
+ // directorOrAuthorisedPerson→1.6.2) while ed6 keeps its existing refs — hand-authored.
37
+ [...COMPANY, "companyName"],
38
+ [...COMPANY, "companyNumber"],
39
+ [...COMPANY, "directorOrAuthorisedPerson"],
40
+ ];
41
+ const isExcluded = (p) => EXCLUDED_PREFIXES.some((pre) => pre.every((seg, i) => p[i] === seg));
42
+
43
+ // minimal position-tracking JSON tokenizer
44
+ function tokenize(text) {
45
+ let i = 0; const n = text.length; const members = [];
46
+ const ws = () => { while (i < n && /\s/.test(text[i])) i++; };
47
+ const str = () => { i++; while (i < n) { const c = text[i]; if (c === "\\") { i += 2; continue; } if (c === '"') { i++; break; } i++; } };
48
+ const val = (p) => { ws(); const c = text[i]; if (c === "{") obj(p); else if (c === "[") arr(p); else if (c === '"') str(); else { while (i < n && !/[,}\]\s]/.test(text[i])) i++; } };
49
+ function obj(p) { i++; ws(); if (text[i] === "}") { i++; return; } while (i < n) { ws(); const ks = i; str(); const key = JSON.parse(text.slice(ks, i)); ws(); i++; ws(); const vs = i; val(p.concat(key)); members.push({ path: p.concat(key), key, keyStart: ks, valueStart: vs, valueEnd: i }); ws(); if (text[i] === ",") { i++; continue; } if (text[i] === "}") { i++; break; } break; } }
50
+ function arr(p) { i++; ws(); if (text[i] === "]") { i++; return; } let k = 0; while (i < n) { ws(); val(p.concat(k)); k++; ws(); if (text[i] === ",") { i++; continue; } if (text[i] === "]") { i++; break; } break; } }
51
+ ws(); val([]); return members;
52
+ }
53
+
54
+ let text = fs.readFileSync(FILE, "utf8");
55
+ const members = tokenize(text);
56
+ const owner = (m) => m.path.slice(0, -1).join("/");
57
+ const keysByOwner = new Map();
58
+ for (const m of members) { const o = owner(m); if (!keysByOwner.has(o)) keysByOwner.set(o, new Map()); keysByOwner.get(o).set(m.key, m); }
59
+ const indentAt = (off) => text.slice(text.lastIndexOf("\n", off - 1) + 1, off);
60
+
61
+ const edits = []; // {at, end, text} (end omitted => pure insert)
62
+ const adds = [], fixes = [];
63
+ for (const m of members) {
64
+ if (!MARKER_RE.test(m.key)) continue;
65
+ if (isExcluded(m.path)) continue;
66
+ const v2 = v2Of(m.key);
67
+ const siblings = keysByOwner.get(owner(m));
68
+ const ed6Val = text.slice(m.valueStart, m.valueEnd);
69
+ if (!siblings.has(v2)) {
70
+ const indent = indentAt(m.keyStart);
71
+ edits.push({ at: m.valueEnd, text: `,\n${indent}"${v2}": ${ed6Val}` });
72
+ adds.push("/" + m.path.join("/"));
73
+ } else {
74
+ const tw = siblings.get(v2);
75
+ const v2Val = text.slice(tw.valueStart, tw.valueEnd);
76
+ if (JSON.stringify(JSON.parse(v2Val)) !== JSON.stringify(JSON.parse(ed6Val))) {
77
+ edits.push({ at: tw.valueStart, end: tw.valueEnd, text: ed6Val });
78
+ fixes.push("/" + tw.path.join("/"));
79
+ }
80
+ }
81
+ }
82
+
83
+ if (!edits.length) { console.log("ta6ed6v2 markers in sync — nothing to do."); process.exit(0); }
84
+ console.log(`Out of sync: ${adds.length} missing twin(s), ${fixes.length} drifted value(s).`);
85
+ [...adds, ...fixes].slice(0, 20).forEach((p) => console.log(" " + p));
86
+ if (CHECK) process.exit(1);
87
+
88
+ edits.sort((a, b) => b.at - a.at);
89
+ for (const e of edits) text = text.slice(0, e.at) + e.text + text.slice(e.end ?? e.at);
90
+ JSON.parse(text); // guard
91
+ fs.writeFileSync(FILE, text);
92
+ console.log(`Applied ${edits.length} edit(s) to ${FILE}. Now run: node src/utils/extractOverlay.js`);