Merged PR 2242: Refactor: New Appeal flow structural cleanup (Slices 1–8, no behaviour change)

## Summary

This PR merges the completed new-appeal refactor stream (Slices 1–8) into SIPS-Development.

This refactor was executed in controlled slices with regression validation at each step.

## Scope

Structural and readability improvements only:
- XML/form derivation extraction
- payload and file helper extraction
- side-effect facade introduction
- BuildSection and BuildCheckSection decomposition
- BuildCheckRow formatter map refactor
- nested prop boundary cleanup
- start-flow cleanup (CreateCase / AboutYou)

## Behaviour

No intended behavioural changes.

The following were explicitly preserved:
- S78 journey behaviour
- payload shapes and field names/ids
- HASCAS mapping logic
- appellant/agent branching
- validation rules and messages
- redirect/query parameters (`lpa`, `apt`, `id`)
- navigation and side-effect sequencing
- EN/CY output parity

## Validation

Full regression has been performed on:
- start flow (CreateCase / AboutYou)
- save and resume flows
- file upload handling
- check answers rendering
- submit/finalisation sequence
- confirmation flow
- CRM insertion path
- EN/CY parity

Additional checks:
- docsOffline branch behaviour
- completion and partial-save email paths
- negative-path validation scenarios
- lint (warnings baseline unchanged)

## Risk

Low:
- changes are structural only
- no business logic changes
- no contract changes

## Rollback

Safe rollback via reverting this merge commit.

## Notes

This refactor reduces coupling and prepares the new-appeal flow for future appeal-type expansion.

Related work items: #22570, #22576, #22577, #22583, #22586, #22587, #22588, #22590
This commit is contained in:
Robert Bond
2026-04-13 13:09:12 +00:00
parent bd3d311cfb
commit 0de9268255
47 changed files with 2010 additions and 945 deletions
+45 -43
View File
@@ -1,11 +1,30 @@
import _ from "lodash";
import useTranslation from "next-translate/useTranslation";
import { useRouter } from "next/router";
import xpath from "xpath";
import BuildField from "./buildfield";
import {
parseRowOuterHTML,
selectRowDataFieldContent,
selectRowDataFieldName,
selectRowDateEnd,
selectRowDateStart,
selectRowDocumentTypeCode,
selectRowFieldType,
selectRowHint,
selectRowLabelDescriptions,
selectRowMaxFieldLength,
selectRowMaxSubField,
selectRowParentField,
selectRowParentFieldShowOnValue,
selectRowRequiredDocumentLabel,
selectRowRequiredDocumentValue,
selectRowValidation
} from "../../lib/newappeal/formDerivation";
export default function BuildRow(props) {
let { t } = useTranslation();
const legacyProps = props.props;
const legacyPageProps = legacyProps.props;
const router = useRouter();
const { locale } = router;
@@ -20,56 +39,39 @@ export default function BuildRow(props) {
uploadCount,
setFileCount,
completedUploadFilesCount,
setCompletedUploadFilesCount,
setCompletedUploadFilesCount
} = props;
const parser = new DOMParser();
return (
<div className="govuk-grid-column-full">
{Object.keys(rowXML).map((key, index) => {
var doc = parser.parseFromString(
rowXML[key].outerHTML,
"text/xml"
);
var doc = parseRowOuterHTML(rowXML[key].outerHTML);
if (_.isEmpty(rowXML[key].innerHTML)) {
("");
} else {
var rows = xpath.select("//label/@description", doc);
var fieldtype = xpath.select("//@classid", doc);
var validation = xpath.select("//@validation", doc);
var maxFieldLength = xpath.select("//@maxFieldLength", doc);
var maxSubField = xpath.select("//@maxsubfield", doc);
var datafieldname = xpath.select("//@datafieldname", doc);
var datafieldcontent = xpath.select(
"//@datafieldcontent",
doc
);
var parentField = xpath.select("//@parentField", doc);
var rows = selectRowLabelDescriptions(doc);
var fieldtype = selectRowFieldType(doc);
var validation = selectRowValidation(doc);
var maxFieldLength = selectRowMaxFieldLength(doc);
var maxSubField = selectRowMaxSubField(doc);
var datafieldname = selectRowDataFieldName(doc);
var datafieldcontent = selectRowDataFieldContent(doc);
var parentField = selectRowParentField(doc);
var parentFieldShowOnValue = xpath.select(
"//@parentFieldShowOnValue",
doc
);
var parentFieldShowOnValue =
selectRowParentFieldShowOnValue(doc);
var requiredDocumentValue = xpath.select(
"//@requiredDocumentValue",
doc
);
var requiredDocumentValue =
selectRowRequiredDocumentValue(doc);
var requiredDocumentLabel = xpath.select(
"//@requiredDocumentLabel",
doc
);
var requiredDocumentLabel =
selectRowRequiredDocumentLabel(doc);
var documentTypeCode = xpath.select(
"//@ishareDocumentCode",
doc
);
var documentTypeCode = selectRowDocumentTypeCode(doc);
var hint = xpath.select("//label/@hint", doc);
var dateStart = xpath.select("//@dateStart", doc);
var dateEnd = xpath.select("//@dateEnd", doc);
var hint = selectRowHint(doc);
var dateStart = selectRowDateStart(doc);
var dateEnd = selectRowDateEnd(doc);
hint = !_.isEmpty(hint) && hint[0].value;
@@ -128,7 +130,7 @@ export default function BuildRow(props) {
key={key}
props={props}
picklistData={
props.props.props.formData.pickListData
legacyPageProps.formData.pickListData
}
mandatoryFieldsData={mandatoryFieldsData}
documentTypeCode={documentTypeCode}
@@ -158,7 +160,7 @@ export default function BuildRow(props) {
key={key}
props={props}
picklistData={
props.props.props.formData.pickListData
legacyPageProps.formData.pickListData
}
mandatoryFieldsData={mandatoryFieldsData}
hint={hint}
@@ -168,13 +170,13 @@ export default function BuildRow(props) {
maxFieldLength={maxFieldLength}
dateStart={dateStart}
dateEnd={dateEnd}
setDocumentsList={props.props.setDocumentsList}
setDocumentsList={legacyProps.setDocumentsList}
documentList={
props.props.appealType.documentList
legacyProps.appealType.documentList
}
documentTypeCode={documentTypeCode}
setFilesForAppeal={
props.props.setFilesForAppeal
legacyProps.setFilesForAppeal
}
maxSubField={maxSubField}
setFileCount={setFileCount}