Skip to content

Feature/771 Add Magistrates Standard List style guide and PDF - #788

Merged
junaidiqbalmoj merged 7 commits into
masterfrom
feature/771-Magistartes-Standard-List-style-guide
Jul 3, 2026
Merged

Feature/771 Add Magistrates Standard List style guide and PDF#788
junaidiqbalmoj merged 7 commits into
masterfrom
feature/771-Magistartes-Standard-List-style-guide

Conversation

@KianKwa

@KianKwa KianKwa commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Jira link

#771

Change description

Add Magistrates Standard List style guide and PDF

Testing done

Security Vulnerability Assessment

CVE Suppression: Are there any CVEs present in the codebase (either newly introduced or pre-existing) that are being intentionally suppressed or ignored by this commit?

  • Yes
  • No

Checklist

  • commit messages are meaningful and follow good commit message guidelines
  • README and other documentation has been updated / added (if needed)
  • tests have been updated / new tests has been added (if needed)
  • Does this PR introduce a breaking change

Summary by CodeRabbit

  • New Features
    • Added Magistrates Standard List support, including the new web view (accordion layout, search, restriction guidance), PDF generation, and enhanced email summaries.
    • Introduced full English and Welsh (cy/en) UI copy, plus schema validation and provenance labelling.
    • Registered the new list type for publication, notifications, and location support, with dedicated styles.
  • Bug Fixes
    • Improved handling for missing, invalid, not-found, access-denied, and unexpected errors with appropriate status pages/messages.
  • Tests
    • Added comprehensive unit and route tests covering rendering, validation, PDF generation, email summaries, and configuration.
  • Documentation
    • Added implementation plan and task/checklists for the new list type.

@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 38397d0e-2601-461d-87f5-3d90e328641a

📥 Commits

Reviewing files that changed from the base of the PR and between 18e25c6 and d8c348c.

📒 Files selected for processing (3)
  • apps/web/package.json
  • apps/web/src/app.ts
  • apps/web/src/assets/css/web.scss
✅ Files skipped from review due to trivial changes (2)
  • apps/web/package.json
  • apps/web/src/assets/css/web.scss
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/src/app.ts

📝 Walkthrough

Walkthrough

Adds the @hmcts/magistrates-standard-list list type across the library, web app, PDF/email pipelines, and shared registration points. It includes schema, renderer, templates, locales, validation, tests, and wiring in publication, notifications, location data, and app module paths.

Changes

Magistrates Standard List

Layer / File(s) Summary
Ticket documentation
docs/tickets/771/*
Ticket, implementation plan, tasks, and review notes are added for the magistrates-standard-list work.
Schema and types
libs/list-types/magistrates-standard-list/src/schemas/magistrates-standard-list.json, libs/list-types/magistrates-standard-list/src/models/types.ts
Adds the JSON schema and the raw/rendered TypeScript interfaces for the list data model.
Validation and package scaffold
libs/list-types/magistrates-standard-list/src/validation/json-validator.ts, libs/list-types/magistrates-standard-list/src/config.ts, libs/list-types/magistrates-standard-list/tsconfig.json, libs/list-types/magistrates-standard-list/package.json, libs/list-types/magistrates-standard-list/src/index.ts, libs/list-types/magistrates-standard-list/src/locales/en.ts, libs/list-types/magistrates-standard-list/src/locales/cy.ts, libs/list-types/magistrates-standard-list/src/config.test.ts, libs/list-types/magistrates-standard-list/src/validation/json-validator.test.ts
Adds schema validation, filesystem config helpers, build/package metadata, barrel exports, locale strings, and config/validator tests.
Data renderer
libs/list-types/magistrates-standard-list/src/rendering/renderer.ts, libs/list-types/magistrates-standard-list/src/rendering/renderer.test.ts
Builds the rendered header and nested court-room data, with tests for location lookup, formatting, offences, restrictions, applications, and attendance fields.
Email summary builder
libs/list-types/magistrates-standard-list/src/email-summary/summary-builder.ts, libs/list-types/magistrates-standard-list/src/email-summary/summary-builder.test.ts
Adds case-summary extraction for defendants and application subjects, plus tests for name, offence, and prosecuting-authority mapping.
PDF generator and template
libs/list-types/magistrates-standard-list/src/pdf/pdf-generator.ts, libs/list-types/magistrates-standard-list/src/pdf/pdf-template.njk, libs/list-types/magistrates-standard-list/src/pdf/pdf-generator.test.ts
Renders magistrates-standard-list data to HTML, generates a PDF, and adds the PDF template and generator tests.
Web controller and page template
apps/web/src/pages/(list-types)/magistrates-standard-list/index.ts, apps/web/src/pages/(list-types)/magistrates-standard-list/magistrates-standard-list.njk, apps/web/src/pages/(list-types)/magistrates-standard-list/index.test.ts, apps/web/src/assets/css/list-types/magistrates-standard-list.scss, apps/web/src/assets/css/web.scss
Adds the GET route handler, page template, styles, and controller tests for the magistrates-standard-list page.
Cross-service registration
tsconfig.json, apps/web/package.json, apps/web/src/app.ts, libs/location/src/list-type-data.ts, libs/notifications/src/notification/notification-service.ts, libs/publication/src/processing/service.ts
Registers the new list type in app wiring, path aliases, location metadata, notification email generation, and publication PDF generation.
Possibly related issues
  • hmcts/cath-service#771 — matches the same magistrates-standard-list implementation scope.

|Possibly related PRs|

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding the Magistrates Standard List style guide and PDF support.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/771-Magistartes-Standard-List-style-guide

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

🎭 Playwright E2E Test Results

84 tests   52 ✅  6m 13s ⏱️
33 suites  32 💤
 1 files     0 ❌

Results for commit d8c348c.

♻️ This comment has been updated with latest results.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 13

🧹 Nitpick comments (1)
libs/list-types/magistrates-standard-list/src/index.ts (1)

1-7: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reorder this barrel to match the repo export rule.

The type export sits above functional exports, and the locale constants are not first. Small change, but worth fixing before this barrel becomes the pattern for the package.

As per coding guidelines, **/*.ts: Order module exports: top-level constants first, then exported functions, then other functions ordered by usage, with interfaces and types at the bottom.

Suggested fix
-export * from "./email-summary/summary-builder.js";
 export { cy as magistratesStandardListCy } from "./locales/cy.js";
 export { en as magistratesStandardListEn } from "./locales/en.js";
-export * from "./models/types.js";
+export * from "./email-summary/summary-builder.js";
 export * from "./pdf/pdf-generator.js";
 export * from "./rendering/renderer.js";
 export { validateMagistratesStandardList } from "./validation/json-validator.js";
+export * from "./models/types.js";

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 44c72578-2ff4-4451-8284-5a12f03206ad

📥 Commits

Reviewing files that changed from the base of the PR and between cbf0990 and f3cccc5.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (27)
  • apps/web/package.json
  • apps/web/src/app.ts
  • apps/web/src/pages/(list-types)/magistrates-standard-list/index.test.ts
  • apps/web/src/pages/(list-types)/magistrates-standard-list/index.ts
  • apps/web/src/pages/(list-types)/magistrates-standard-list/magistrates-standard-list.njk
  • docs/tickets/771/plan.md
  • docs/tickets/771/tasks.md
  • docs/tickets/771/ticket.md
  • libs/list-types/magistrates-standard-list/package.json
  • libs/list-types/magistrates-standard-list/src/config.ts
  • libs/list-types/magistrates-standard-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/magistrates-standard-list/src/email-summary/summary-builder.ts
  • libs/list-types/magistrates-standard-list/src/index.ts
  • libs/list-types/magistrates-standard-list/src/locales/cy.ts
  • libs/list-types/magistrates-standard-list/src/locales/en.ts
  • libs/list-types/magistrates-standard-list/src/models/types.ts
  • libs/list-types/magistrates-standard-list/src/pdf/pdf-generator.ts
  • libs/list-types/magistrates-standard-list/src/pdf/pdf-template.njk
  • libs/list-types/magistrates-standard-list/src/rendering/renderer.test.ts
  • libs/list-types/magistrates-standard-list/src/rendering/renderer.ts
  • libs/list-types/magistrates-standard-list/src/schemas/magistrates-standard-list.json
  • libs/list-types/magistrates-standard-list/src/validation/json-validator.ts
  • libs/list-types/magistrates-standard-list/tsconfig.json
  • libs/location/src/list-type-data.ts
  • libs/notifications/src/notification/notification-service.ts
  • libs/publication/src/processing/service.ts
  • tsconfig.json

Comment on lines +33 to +37
<div class="govuk-warning-text">
<span class="govuk-warning-text__icon" aria-hidden="true">!</span>
<strong class="govuk-warning-text__text">
<span class="govuk-visually-hidden">Warning</span>
{{ t.restrictionInformationBoldText }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Localise the warning text announced to assistive technology.

The visually hidden text is hardcoded to English, so Welsh pages will still announce “Warning” in English. Move this into the locale files and render it via t.

As per coding guidelines, "Implement Welsh language support on all user-facing text with separate en.ts and cy.ts content files."

Source: Coding guidelines

Comment on lines +50 to +52
<div class="govuk-form-group govuk-!-margin-top-4">
<h2 class="govuk-heading-m">{{ t.searchCases }}</h2>
<input class="govuk-input govuk-!-width-one-half" id="case-search-input" name="search" type="text">

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Give the search input an accessible name.

This input has no associated label, so screen-reader users get an unlabelled text box. Add a <label for="case-search-input"> or reference the existing heading with aria-labelledby.

Comment on lines +5 to +7
"dependencies": {
"@hmcts/location": "workspace:*"
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Declare @hmcts/publication here as well.

src/validation/json-validator.ts imports validateJson from @hmcts/publication, but this package does not declare that dependency. Right now resolution depends on workspace hoisting rather than this package’s own contract.

Suggested fix
   "dependencies": {
-    "`@hmcts/location`": "workspace:*"
+    "`@hmcts/location`": "workspace:*",
+    "`@hmcts/publication`": "workspace:*"
   },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"dependencies": {
"@hmcts/location": "workspace:*"
},
"dependencies": {
"`@hmcts/location`": "workspace:*",
"`@hmcts/publication`": "workspace:*"
},

Comment on lines +7 to +8
export const moduleRoot = __dirname;
export const schemaPath = path.join(__dirname, "schemas/magistrates-standard-list.json");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Rename these exported constants before the API spreads.

moduleRoot and schemaPath are new public constants, so this is the cheapest point to align them with the repo naming rule.

As per coding guidelines, **/*.{ts,tsx,js}: Use SCREAMING_SNAKE_CASE for constant declarations (e.g., MAX_FILE_SIZE, DEFAULT_TIMEOUT).

Suggested fix
-export const moduleRoot = __dirname;
-export const schemaPath = path.join(__dirname, "schemas/magistrates-standard-list.json");
+export const MODULE_ROOT = __dirname;
+export const SCHEMA_PATH = path.join(__dirname, "schemas/magistrates-standard-list.json");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const moduleRoot = __dirname;
export const schemaPath = path.join(__dirname, "schemas/magistrates-standard-list.json");
export const MODULE_ROOT = __dirname;
export const SCHEMA_PATH = path.join(__dirname, "schemas/magistrates-standard-list.json");

Source: Coding guidelines

Comment on lines +37 to +63
for (const caseItem of hearing.case ?? []) {
const defendant = caseItem.party?.find((p) => p.partyRole === "DEFENDANT");
const prosecutor = caseItem.party?.find((p) => p.partyRole === "PROSECUTING_AUTHORITY");
const fields: CaseSummary = [];

if (defendant) {
const name = extractPartyName(defendant);
if (name) fields.push({ label: "Name", value: name });
}

if (prosecutor) {
const authority = extractPartyName(prosecutor);
if (authority) fields.push({ label: "Prosecuting authority", value: authority });
}

fields.push({ label: "Reference", value: caseItem.caseUrn });

if (hearing.hearingType) {
fields.push({ label: "Hearing type", value: hearing.hearingType });
}

if (defendant) {
const offences = extractOffenceTitles(defendant);
if (offences) fields.push({ label: "Offence", value: offences });
}

summaries.push(fields);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Emit one summary per matching party, not per case/application.

Both branches use .find(...), so only the first DEFENDANT or first subject === true party is ever emitted. The contract described for this builder is one CaseSummary per defendant and per application subject, so multi-party hearings will drop entries from notification emails. Please iterate the filtered parties and push a separate fields array for each one, then add a regression covering two defendants and two subject parties.

Suggested direction
- const defendant = caseItem.party?.find((p) => p.partyRole === "DEFENDANT");
- const prosecutor = caseItem.party?.find((p) => p.partyRole === "PROSECUTING_AUTHORITY");
- const fields: CaseSummary = [];
-
- if (defendant) {
-   const name = extractPartyName(defendant);
-   if (name) fields.push({ label: "Name", value: name });
- }
- ...
- summaries.push(fields);
+ const prosecutor = caseItem.party?.find((p) => p.partyRole === "PROSECUTING_AUTHORITY");
+ for (const defendant of caseItem.party?.filter((p) => p.partyRole === "DEFENDANT") ?? []) {
+   const fields: CaseSummary = [];
+   const name = extractPartyName(defendant);
+   if (name) fields.push({ label: "Name", value: name });
+   ...
+   summaries.push(fields);
+ }

Apply the same pattern to application.party.

Also applies to: 66-86

Comment on lines +132 to +133
<p><span class="label">{{ t.asn }}</span>{{ hearing.partyInfo.asn }}</p>
<p><span class="label">{{ t.pncId }}</span>{{ hearing.partyInfo.pncId }}</p>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Hide empty ASN and PNC rows.

These fields are blank for organisation parties and many applications, so the PDF currently renders empty labels in the right-hand column. Guard them the same way as the other optional fields.

Suggested fix
-                  <p><span class="label">{{ t.asn }}</span>{{ hearing.partyInfo.asn }}</p>
-                  <p><span class="label">{{ t.pncId }}</span>{{ hearing.partyInfo.pncId }}</p>
+                  {% if hearing.partyInfo.asn %}
+                    <p><span class="label">{{ t.asn }}</span>{{ hearing.partyInfo.asn }}</p>
+                  {% endif %}
+                  {% if hearing.partyInfo.pncId %}
+                    <p><span class="label">{{ t.pncId }}</span>{{ hearing.partyInfo.pncId }}</p>
+                  {% endif %}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<p><span class="label">{{ t.asn }}</span>{{ hearing.partyInfo.asn }}</p>
<p><span class="label">{{ t.pncId }}</span>{{ hearing.partyInfo.pncId }}</p>
{% if hearing.partyInfo.asn %}
<p><span class="label">{{ t.asn }}</span>{{ hearing.partyInfo.asn }}</p>
{% endif %}
{% if hearing.partyInfo.pncId %}
<p><span class="label">{{ t.pncId }}</span>{{ hearing.partyInfo.pncId }}</p>
{% endif %}

Comment on lines +163 to +168
"offenceWording": {
"description": "Long description of offence",
"title": "Offence wording",
"type": "string",
"examples": ["driving whilst under the influence of alcohol"],
"pattern": "^(?!(?:.|\\r|\\n)*(?:<\\s*\\/[^>]*>|<[^>]*\\/>|&lt;\\s*\\/[^&]*&gt;|&lt;[^&]*\\/&gt;))(?:.|\\r|\\n)*$"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Tighten these anti-HTML patterns.

These regexes only reject closing or self-closing tags. Plain opening tags such as <script> or <img> still validate, which breaks the no-markup rule used elsewhere in this schema and leaves offenceWording able to flow into rendered output unchecked.

Suggested fix
-                "pattern": "^(?!(?:.|\\r|\\n)*(?:<\\s*\\/[^>]*>|<[^>]*\\/>|&lt;\\s*\\/[^&]*&gt;|&lt;[^&]*\\/&gt;))(?:.|\\r|\\n)*$"
+                "pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"

Apply the same replacement to both offenceWording and applicationParticulars.

Also applies to: 464-469

Comment on lines +432 to +470
"application": {
"title": "Application",
"description": "Application associated with the case",
"type": "array",
"items": {
"type": "object",
"title": "Application",
"required": ["applicationReference"],
"properties": {
"party": {
"type": "array",
"description": "party for the case",
"title": "Party",
"items": {
"type": "object",
"$ref": "#/$defs/party"
}
},
"applicationReference": {
"title": "Application Reference",
"description": "application reference",
"type": "string",
"examples": ["ABC1234567D"],
"pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"
},
"applicationType": {
"title": "Application Type",
"description": "application type",
"type": "string",
"examples": ["application type example"],
"pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"
},
"applicationParticulars": {
"title": "Application Particulars",
"description": "details of an application",
"type": "string",
"examples": ["application particulars example"],
"pattern": "^(?!(?:.|\\r|\\n)*(?:<\\s*/[^>]*>|<[^>]*\\/>|&lt;\\s*\\/[^&]*&gt;|&lt;[^&]*\\/&gt;))(?:.|\\r|\\n)*$"
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Keep the Application schema aligned with the exported type.

src/models/types.ts exposes reportingRestriction and reportingRestrictionDetails on Application, but this schema never validates them. That means validateMagistratesStandardList can accept malformed values for fields the rest of the package is allowed to read.

Suggested fix
                                           "applicationParticulars": {
                                             "title": "Application Particulars",
                                             "description": "details of an application",
                                             "type": "string",
                                             "examples": ["application particulars example"],
                                             "pattern": "^(?!(?:.|\\r|\\n)*(?:<\\s*/[^>]*>|<[^>]*\\/>|&lt;\\s*\\/[^&]*&gt;|&lt;[^&]*\\/&gt;))(?:.|\\r|\\n)*$"
+                                          },
+                                          "reportingRestriction": {
+                                            "title": "Reporting Restriction",
+                                            "type": "boolean"
+                                          },
+                                          "reportingRestrictionDetails": {
+                                            "title": "Reporting Restrictions Detail",
+                                            "type": "array",
+                                            "items": {
+                                              "type": "string",
+                                              "pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"
+                                            }
                                           }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"application": {
"title": "Application",
"description": "Application associated with the case",
"type": "array",
"items": {
"type": "object",
"title": "Application",
"required": ["applicationReference"],
"properties": {
"party": {
"type": "array",
"description": "party for the case",
"title": "Party",
"items": {
"type": "object",
"$ref": "#/$defs/party"
}
},
"applicationReference": {
"title": "Application Reference",
"description": "application reference",
"type": "string",
"examples": ["ABC1234567D"],
"pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"
},
"applicationType": {
"title": "Application Type",
"description": "application type",
"type": "string",
"examples": ["application type example"],
"pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"
},
"applicationParticulars": {
"title": "Application Particulars",
"description": "details of an application",
"type": "string",
"examples": ["application particulars example"],
"pattern": "^(?!(?:.|\\r|\\n)*(?:<\\s*/[^>]*>|<[^>]*\\/>|&lt;\\s*\\/[^&]*&gt;|&lt;[^&]*\\/&gt;))(?:.|\\r|\\n)*$"
}
"applicationParticulars": {
"title": "Application Particulars",
"description": "details of an application",
"type": "string",
"examples": ["application particulars example"],
"pattern": "^(?!(?:.|\\r|\\n)*(?:<\\s*/[^>]*>|<[^>]*\\/>|&lt;\\s*\\/[^&]*&gt;|&lt;[^&]*\\/&gt;))(?:.|\\r|\\n)*$"
},
"reportingRestriction": {
"title": "Reporting Restriction",
"type": "boolean"
},
"reportingRestrictionDetails": {
"title": "Reporting Restrictions Detail",
"type": "array",
"items": {
"type": "string",
"pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"
}
}

Comment on lines +25 to +28
import {
extractCaseSummary as extractMagistratesStandardSummary,
formatCaseSummaryForEmail as formatMagistratesStandardSummaryForEmail
} from "@hmcts/magistrates-standard-list";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== libs/notifications/package.json =="
jq '{dependencies, devDependencies, peerDependencies}' libs/notifications/package.json 2>/dev/null || cat libs/notifications/package.json

echo
echo "== matching dependency entries =="
rg -n '"`@hmcts/magistrates-standard-list`"' libs/notifications/package.json

Repository: hmcts/cath-service

Length of output: 941


Add the new workspace dependency to libs/notifications/package.json @hmcts/magistrates-standard-list is imported here but not declared for this package, which can break isolated installs or package-level builds.

Comment thread libs/publication/src/processing/service.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/web/src/pages/(list-types)/magistrates-standard-list/magistrates-standard-list.njk (1)

13-15: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Keep header.venueAddress on a single shape.

This block assumes header.venueAddress is an array, but the controller test for apps/web/src/pages/(list-types)/magistrates-standard-list/index.test.ts passes it as a string. If production data follows that contract, this loop will render one character per line. Please normalise the value before rendering, or update the template to handle the actual type consistently.

🧹 Nitpick comments (1)
libs/list-types/magistrates-standard-list/src/pdf/pdf-generator.test.ts (1)

3-8: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Rename const declarations to SCREAMING_SNAKE_CASE.

mockSavePdfToStorage, mockRenderedData, mockJsonData, baseOptions, and mockNunjucksEnv all break the repo constant naming rule. Please normalise these names consistently across the file. As per coding guidelines, **/*.{ts,tsx,js}: Use SCREAMING_SNAKE_CASE for constant declarations.

Also applies to: 37-69, 72-74

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e46fbe71-767f-4953-b253-433b01040836

📥 Commits

Reviewing files that changed from the base of the PR and between f3cccc5 and 180833c.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (14)
  • apps/web/src/assets/css/list-types/magistrates-standard-list.scss
  • apps/web/src/assets/css/web.scss
  • apps/web/src/pages/(list-types)/magistrates-standard-list/magistrates-standard-list.njk
  • docs/tickets/771/review.md
  • libs/list-types/magistrates-standard-list/package.json
  • libs/list-types/magistrates-standard-list/src/assets/css/magistrates-standard-list.scss
  • libs/list-types/magistrates-standard-list/src/config.test.ts
  • libs/list-types/magistrates-standard-list/src/config.ts
  • libs/list-types/magistrates-standard-list/src/locales/cy.ts
  • libs/list-types/magistrates-standard-list/src/locales/en.ts
  • libs/list-types/magistrates-standard-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/magistrates-standard-list/src/validation/json-validator.test.ts
  • libs/list-types/magistrates-standard-list/tsconfig.json
  • libs/publication/package.json
✅ Files skipped from review due to trivial changes (3)
  • libs/list-types/magistrates-standard-list/src/validation/json-validator.test.ts
  • apps/web/src/assets/css/list-types/magistrates-standard-list.scss
  • libs/list-types/magistrates-standard-list/src/locales/cy.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • libs/list-types/magistrates-standard-list/src/config.ts
  • libs/list-types/magistrates-standard-list/package.json
  • libs/list-types/magistrates-standard-list/tsconfig.json
  • libs/list-types/magistrates-standard-list/src/locales/en.ts

@github-actions

Copy link
Copy Markdown
Contributor

Preview Deployment Successful 🚀

Your preview environment is ready:

The environment will be automatically cleaned up when this PR is closed.

@junaidiqbalmoj junaidiqbalmoj linked an issue Jul 1, 2026 that may be closed by this pull request
25 tasks

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
apps/web/src/pages/(list-types)/magistrates-standard-list/magistrates-standard-list.njk (2)

1-204: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Template hand-rolls GOV.UK components instead of importing macros.

The whole page builds govuk-warning-text, govuk-accordion, govuk-details, and govuk-table markup by hand with raw classes, with no {% from "govuk/components/.../macro.njk" import ... %} anywhere in the file. This bypasses the design system's built-in accessibility/JS wiring and diverges from the intended pattern.

As per coding guidelines, "Use Nunjucks templates with .njk extension in apps/web/src/pages/ and import GOV.UK Design System macros."

Source: Coding guidelines


47-59: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Heading hierarchy broken: <h1> used repeatedly below an <h2> page title.

The page title (line 7) is an <h2>, but court room headings inside the loop (lines 53/56/58) are <h1>, and there can be multiple <h1> elements per page (one set per court room). This violates expected heading order and having a single top-level heading, which is a WCAG concern (1.3.1/2.4.6) for screen-reader navigation.

♿ Suggested fix
-          {% if room.courtHouseName %}
-            <h1 class="govuk-heading-l site-address">{{ room.courtHouseName }}</h1>
-          {% endif %}
-          {% if room.lja %}
-            <h1 class="govuk-heading-l site-address">{{ t.lja }}: {{ room.lja }}</h1>
-          {% endif %}
-          <h1 class="govuk-heading-l site-address">{{ room.courtRoomName }}</h1>
+          {% if room.courtHouseName %}
+            <h2 class="govuk-heading-l site-address">{{ room.courtHouseName }}</h2>
+          {% endif %}
+          {% if room.lja %}
+            <h2 class="govuk-heading-l site-address">{{ t.lja }}: {{ room.lja }}</h2>
+          {% endif %}
+          <h2 class="govuk-heading-l site-address">{{ room.courtRoomName }}</h2>
🧹 Nitpick comments (2)
libs/list-types/magistrates-standard-list/src/rendering/renderer.test.ts (1)

218-324: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider a fixture builder to cut duplication.

Each of these tests hand-rolls a full MagistratesStandardList object (several also spread ...FULL_JSON but then fully replace courtLists, making the spread a no-op). A small factory helper (e.g. buildCase(overrides) / buildHearing(overrides)) would shrink these blocks and make future schema changes easier to propagate across tests.

Also applies to: 343-398, 400-458, 482-601, 603-647

libs/list-types/magistrates-standard-list/src/email-summary/summary-builder.test.ts (1)

185-200: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Test title says "empty name" but asserts undefined.

Minor wording mismatch — the field is undefined, not an empty string, so the description could read "should not include Name field" for accuracy.

✏️ Suggested wording tweak
-  it("should return empty name when party has neither individual nor organisation details", () => {
+  it("should omit Name field when party has neither individual nor organisation details", () => {

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c19b5a66-a84d-4beb-9476-e452831084a5

📥 Commits

Reviewing files that changed from the base of the PR and between 180833c and a4b9ddc.

📒 Files selected for processing (7)
  • apps/web/src/pages/(list-types)/magistrates-standard-list/magistrates-standard-list.njk
  • libs/list-types/magistrates-standard-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/magistrates-standard-list/src/locales/cy.ts
  • libs/list-types/magistrates-standard-list/src/locales/en.ts
  • libs/list-types/magistrates-standard-list/src/pdf/pdf-template.njk
  • libs/list-types/magistrates-standard-list/src/rendering/renderer.test.ts
  • libs/list-types/magistrates-standard-list/src/rendering/renderer.ts
✅ Files skipped from review due to trivial changes (2)
  • libs/list-types/magistrates-standard-list/src/locales/en.ts
  • libs/list-types/magistrates-standard-list/src/locales/cy.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • libs/list-types/magistrates-standard-list/src/pdf/pdf-template.njk
  • libs/list-types/magistrates-standard-list/src/rendering/renderer.ts

Comment on lines +131 to +135
{% if offence.offenceWording %}
<tr class="govuk-table__row">
<td class="govuk-table__cell">{{ offence.offenceWording }}</td>
</tr>
{% endif %}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Offence wording row lacks a label cell, unlike its siblings.

Every other row in this table has a label <td> plus a value <td>, but the offenceWording row only has a single cell. This is inconsistent for a table structure and gives no context to a screen reader user landing on that row.

💡 Suggested fix
                                   {% if offence.offenceWording %}
                                     <tr class="govuk-table__row">
+                                      <td class="govuk-table__cell"><span class="linked-cases-heading">{{ t.offenceWording }}</span></td>
                                       <td class="govuk-table__cell">{{ offence.offenceWording }}</td>
                                     </tr>
                                   {% endif %}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{% if offence.offenceWording %}
<tr class="govuk-table__row">
<td class="govuk-table__cell">{{ offence.offenceWording }}</td>
</tr>
{% endif %}
{% if offence.offenceWording %}
<tr class="govuk-table__row">
<td class="govuk-table__cell"><span class="linked-cases-heading">{{ t.offenceWording }}</span></td>
<td class="govuk-table__cell">{{ offence.offenceWording }}</td>
</tr>
{% endif %}

@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment Successful 🚀

Your preview environment is ready:

The environment will be automatically cleaned up when this PR is closed.

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment Successful 🚀

Your preview environment is ready:

The environment will be automatically cleaned up when this PR is closed.

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment Successful 🚀

Your preview environment is ready:

The environment will be automatically cleaned up when this PR is closed.

… types

Keeps magistrates-standard-list additions from this branch alongside crown
daily/firm/warned list, SSCS daily hearing lists, SIAC/POAC/PAAC, FTT, GRC,
WPAFCC, and UTIAC list types merged from master. Runs yarn install to link
the newly added magistrates-standard-list workspace package.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Jul 3, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment Successful 🚀

Your preview environment is ready:

The environment will be automatically cleaned up when this PR is closed.

@junaidiqbalmoj
junaidiqbalmoj merged commit 65a5ca0 into master Jul 3, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Style Guide: Implement Magistrates Standard List

2 participants