Skip to content

feat(list-types): add 5 non-strategic hearing list types (#429) - #761

Merged
junaidiqbalmoj merged 37 commits into
masterfrom
feat/429-non-strategic-hearing-list-types
Jul 3, 2026
Merged

feat(list-types): add 5 non-strategic hearing list types (#429)#761
junaidiqbalmoj merged 37 commits into
masterfrom
feat/429-non-strategic-hearing-list-types

Conversation

@junaidiqbalmoj

@junaidiqbalmoj junaidiqbalmoj commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds 5 new non-strategic hearing list types: GRC Weekly (ID:28), WPAFCC Weekly (ID:29), UTIAC Statutory Appeal Daily (ID:30), UTIAC JR London Daily (ID:31), UTIAC JR Leeds Daily (ID:32)
  • Each list type includes web rendering, PDF generation, email summary extraction, and English/Welsh i18n
  • Fixes "for week commencing" text missing from GRC and WPAFCC weekly list publication titles
  • Fixes reporting restriction link order in GRC weekly list (telephone/video hearing link first)
  • Adds shortenedFriendlyName to all 5 new list types so they display correctly in the /non-strategic-upload dropdown
  • Adds subJurisdictionIds to all 5 entries to resolve seed error

Test plan

  • Run yarn db:migrate:dev to seed the new list types with correct shortenedFriendlyName values
  • Verify /non-strategic-upload dropdown shows short names (e.g. "GRC Weekly Hearing List") for all 5 new types
  • Upload a GRC weekly list and verify publication title includes "for week commencing"
  • Verify reporting restriction links on GRC weekly list page: "What to expect when joining a telephone or video hearing" appears before "Observe a court or tribunal hearing..."
  • Run yarn test to confirm all unit tests pass
  • Verify PDF output matches web rendering for all 5 list types

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added new hearing list pages for GRC weekly, WPAFCC weekly, and UTIAC daily variants, including searchable tables, updated headings, and back-to-top links.
    • Expanded publication summaries and email content to cover the new list types.
    • Added support for the new list types across web pages, PDFs, and notifications.
  • Bug Fixes

    • Improved display names and date labels for list summaries.
    • Added stronger validation and error handling for list loading and rendering.
  • Style

    • Added spacing for the back-to-top section and updated shared list-type registrations.

junaidiqbalmoj and others added 2 commits June 19, 2026 17:04
Implements GRC Weekly (ID:28), WPAFCC Weekly (ID:29), UTIAC SA Daily (ID:30),
UTIAC JR London Daily (ID:31), and UTIAC JR Leeds Daily (ID:32) hearing list types
with full web rendering, PDF generation, email summary extraction, and i18n support.

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

coderabbitai Bot commented Jun 19, 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
📝 Walkthrough

Walkthrough

Adds eight new non-strategic hearing-list library packages (GRC weekly, WPAFCC weekly, UTIAC statutory appeal daily, UTIAC JR London/Leeds/Birmingham/Cardiff/Manchester daily), each with converters, schemas, renderers, email summaries, PDF generators, locales, and validators. Extends the web app with corresponding page controllers, Nunjucks templates, and test suites, then wires all types into list metadata, PDF generation, email notifications, GOV.UK module registration, and TypeScript path aliases.

Changes

Non-strategic hearing lists (GRC, WPAFCC, UTIAC)

Layer / File(s) Summary
Shared list-type handler render factories
apps/web/src/pages/(list-types)/list-type-handler.ts
Adds createWeeklyHearingListRender, createUtiacDailyRender, createUtiacJrRegionalDailyRender, and LIST_LOAD_SERVER_ERROR — shared render pipeline factories consumed by all new controllers.
GRC weekly library
libs/list-types/grc-weekly-hearing-list/...
Full library package: package.json, config, data model, Excel converter with tests, JSON schema, renderer with tests, email summary builder with tests, PDF generator with tests, PDF template, Welsh/English locales, JSON validator, and barrel index.
WPAFCC weekly library
libs/list-types/wpafcc-weekly-hearing-list/...
Full library package with the same structure as GRC, targeting the War Pensions and Armed Forces Compensation tribunal.
UTIAC statutory appeal daily library
libs/list-types/utiac-statutory-appeal-daily-hearing-list/...
Full daily library; differs from weekly by using displayFrom for the list date rather than a per-row Excel date column.
UTIAC JR Leeds daily library (canonical implementation)
libs/list-types/utiac-jr-leeds-daily-hearing-list/...
Canonical daily implementation that exports renderUtiacJrDailyHearingListData, createUtiacJrDailyHearingListPdfGenerator, and base locale objects reused by all three regional variants.
UTIAC JR London daily library
libs/list-types/utiac-jr-london-daily-hearing-list/...
Independent full implementation with a distinct field set (adds representative and location columns).
UTIAC JR regional variants (Birmingham, Cardiff, Manchester)
libs/list-types/utiac-jr-birmingham-daily-hearing-list/..., libs/list-types/utiac-jr-cardiff-daily-hearing-list/..., libs/list-types/utiac-jr-manchester-daily-hearing-list/...
Thin variant libraries that re-export renderer, types, email summary, validator, and PDF generator from the Leeds canonical package, each adding only a locale title override and its own converter config with tests.
Web page controllers and templates
apps/web/src/pages/(list-types)/grc-weekly-hearing-list/..., apps/web/src/pages/(list-types)/wpafcc-weekly-hearing-list/..., apps/web/src/pages/(list-types)/utiac-*/...
Adds or rewrites eight GET controllers (all using createSimpleListTypeHandler) plus Nunjucks page templates, with full test coverage: happy path, 400/404/500 errors, displayFrom forwarding, and Welsh locale handling.
Platform wiring and metadata
libs/location/src/list-type-data.ts, libs/publication/src/processing/service.ts, libs/notifications/src/notification/notification-service.ts, apps/web/src/app.ts, tsconfig.json, libs/*/package.json, apps/web/src/pages/(public)/summary-of-publications/index.ts, apps/web/src/pages/(admin)/non-strategic-upload-summary/index.ts, apps/web/src/assets/css/back-to-top.scss
Registers list-type metadata (IDs 28–32), extends PDF generation and email notification registries, wires GOV.UK module roots, adds TypeScript path aliases, updates package dependencies, extends the week-commencing Set, prioritises shortenedFriendlyName in upload display names, and adds a back-to-top margin style.
Ticket documentation
docs/tickets/429/...
Adds ticket specification, implementation plan, task checklist, and code-review record for the workstream.

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant GET as createSimpleListTypeHandler GET
  participant getArtefactById
  participant getPublicationJson
  participant validate as createJsonValidator
  participant renderFn as createWeeklyHearingListRender / createUtiacDailyRender
  participant res as Express Response

  Browser->>GET: GET ?artefactId=...
  GET->>getArtefactById: artefactId
  getArtefactById-->>GET: artefact or null
  GET->>getPublicationJson: artefactId
  getPublicationJson-->>GET: JSON payload or null
  GET->>validate: JSON payload
  validate-->>GET: ValidationResult
  GET->>renderFn: jsonData + artefact metadata
  renderFn-->>GET: header + hearings + dataSource
  GET->>res: render(template, payload) or errors/common (400/404/500)
  res-->>Browser: HTML response
Loading

Possibly related issues

  • hmcts/cath-service#643 — Directly aligned with this PR's addition and wiring of UTIAC JR daily hearing list modules in apps/web/src/app.ts and the corresponding library packages.
  • hmcts/cath-service#613 — Overlaps directly on GRC and WPAFCC weekly hearing list implementations, including the same list-type modules, renderers, templates, and app registration changes.

Possibly related PRs

  • hmcts/cath-service#167: Both PRs extend apps/web/src/app.ts modulePaths to register additional non-strategic list-type module roots into GOV.UK module setup.
  • hmcts/cath-service#325: Both PRs extend EMAIL_BUILDER_REGISTRY in libs/notifications/src/notification/notification-service.ts — the retrieved PR introduces the registry pattern; this PR populates it with eight new hearing-list case-summary builders.
  • hmcts/cath-service#765: Both PRs modify the shared list-type handler infrastructure in apps/web/src/pages/(list-types)/list-type-handler.ts by adding or expanding factory functions used across list-type controllers.
🚥 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 summarises the main change: adding five non-strategic hearing list types.
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 feat/429-non-strategic-hearing-list-types

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 19, 2026

Copy link
Copy Markdown
Contributor

🎭 Playwright E2E Test Results

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

Results for commit 00b28f9.

♻️ This comment has been updated with latest results.

junaidiqbalmoj and others added 2 commits June 22, 2026 09:30
- non-strategic-upload-summary now shows shortenedFriendlyName (e.g. "WPAFCC
  Weekly Hearing List") instead of the full englishFriendlyName
- Align WPAFCC schema with pip-data-management reference: replace judges/members
  fields with a single panel field, make additionalInformation required

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

@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.

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

Caution

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

⚠️ Outside diff range comments (1)
libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/config.ts (1)

1-10: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Rename constants to SCREAMING_SNAKE_CASE across all five config.ts files.

The constants moduleRoot, assets, and schemaPath are module-level const exports and should use SCREAMING_SNAKE_CASE per coding guidelines. This affects all five list-type configs:

  • libs/list-types/wpafcc-weekly-hearing-list/src/config.ts
  • libs/list-types/grc-weekly-hearing-list/src/config.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/config.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/config.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/config.ts

Downstream consumers (web page handlers) will need matching import updates.

🔧 Proposed fix (example for wpafcc, apply to all five)
- export const moduleRoot = __dirname;
- export const assets = path.join(__dirname, "assets/");
- export const schemaPath = path.join(__dirname, "schemas/wpafcc-weekly-hearing-list.json");
+ export const MODULE_ROOT = __dirname;
+ export const ASSETS = path.join(__dirname, "assets/");
+ export const SCHEMA_PATH = path.join(__dirname, "schemas/wpafcc-weekly-hearing-list.json");

Then update all five web handlers to import with the new names (e.g., import { SCHEMA_PATH } from "@hmcts/wpafcc-weekly-hearing-list/config" and use SCHEMA_PATH in place of schemaPath).

Source: Coding guidelines

🟠 Major comments (21)
docs/tickets/429/ticket.md-81-87 (1)

81-87: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Correct the specification table to show the actual list type IDs (28–32, not 24–28).

The specification table lists IDs as 24–28, but these are stale. Per the technical plan (plan.md, line 23), IDs 24–27 are already assigned to SJP list types, and the correct next available IDs are 28–32. The actual implementation in libs/location/src/list-type-data.ts (from the relevant code snippets) confirms IDs 28–32. Update the table to avoid confusion:

| GRC Weekly Hearing List | ... | 28 |
| WPAFCC Weekly Hearing List | ... | 29 |
| UTIAC Statutory Appeal Daily Hearing List | ... | 30 |
| UTIAC JR London Daily Hearing List | ... | 31 |
| UTIAC JR Leeds Daily Hearing List | ... | 32 |
libs/list-types/grc-weekly-hearing-list/src/schemas/grc-weekly-hearing-list.json-9-10 (1)

9-10: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Align schema required fields with the TypeScript model contract.

Line 9 omits members and additionalInformation from required, but GrcWeeklyHearing requires both as string. Because validated data is cast to GrcWeeklyHearingList downstream, this can leak undefined into render/PDF paths.

Suggested fix
-    "required": ["date", "hearingTime", "caseReferenceNumber", "caseName", "judges", "modeOfHearing", "venue"],
+    "required": [
+      "date",
+      "hearingTime",
+      "caseReferenceNumber",
+      "caseName",
+      "judges",
+      "members",
+      "modeOfHearing",
+      "venue",
+      "additionalInformation"
+    ],

Also applies to: 41-46, 59-64

libs/list-types/grc-weekly-hearing-list/src/locales/cy.ts-4-4 (1)

4-4: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Replace placeholder Welsh strings before merge.

These keys still contain placeholder tokens and will be shown verbatim in Welsh pages/PDF output. This breaks the bilingual content requirement for this list type.

Also applies to: 13-13, 16-16, 19-28

libs/list-types/wpafcc-weekly-hearing-list/src/locales/cy.ts-4-4 (1)

4-4: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Complete the missing Welsh translations in this locale file.

Several user-facing keys are still placeholders, so Welsh output will render non-localised marker text instead of real content.

Also applies to: 13-13, 17-25

libs/list-types/utiac-jr-leeds-daily-hearing-list/src/models/types.ts-2-8 (1)

2-8: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Type/schema contract mismatch: additionalInformation required in type, optional in schema.

The interface marks additionalInformation as non-optional string (line 8), but the JSON schema (file utiac-jr-leeds-daily-hearing-list.json) does not include it in the required array (line 9). When Excel is converted with additionalInformation marked as optional, the resulting JSON may omit it. The renderer will then destructure undefined into the template, violating the type contract.

Action: Either mark additionalInformation as optional in the interface (additionalInformation?: string;) or add it to the schema's required array, depending on intent.

libs/list-types/utiac-jr-london-daily-hearing-list/src/locales/cy.ts-4-25 (1)

4-25: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Replace placeholder Welsh strings before release.

Several cy keys still contain [WELSH TRANSLATION REQUIRED: ...] placeholders, so Welsh users will see non-production placeholder content on the live page.

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

libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/locales/cy.ts-5-25 (1)

5-25: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Complete the Welsh translations for all placeholder keys.

This cy locale still ships placeholder markers ([WELSH TRANSLATION REQUIRED: ...]), which will surface directly in the Welsh UI.

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

libs/list-types/grc-weekly-hearing-list/src/pdf/pdf-template.njk-2-2 (1)

2-2: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Localisation is incomplete for Welsh output paths.

The template hard-codes English in both the document language (lang="en") and empty-state copy (No hearings scheduled.), so Welsh PDFs are partially untranslated.

Suggested fix
-<html lang="en">
+<html lang="{{ locale }}">
...
-    <p>No hearings scheduled.</p>
+    <p>{{ t.noHearingsScheduled }}</p>
// Also pass locale into template render context from the generator:
const html = env.render("pdf-template.njk", {
  // ...
  locale: options.locale
});

Also applies to: 58-58

libs/list-types/wpafcc-weekly-hearing-list/src/pdf/pdf-template.njk-2-2 (1)

2-2: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Localisation is incomplete in the PDF template.

Line 2 hardcodes lang="en" and Line 55 hardcodes English text. For Welsh output, this leaves metadata/content partially untranslated.

Suggested fix
-<html lang="en">
+<html lang="{{ locale }}">
@@
-    <p>No hearings scheduled.</p>
+    <p>{{ t.noHearingsScheduled }}</p>
// In the corresponding pdf-generator render context:
 const html = env.render("pdf-template.njk", {
+  locale: options.locale,
   header: renderedData.header,
   hearings: renderedData.hearings,
   dataSource: provenanceLabel,
   t: translations,
   pdfStyles: PDF_BASE_STYLES
 });

Also applies to: 55-55

libs/list-types/utiac-jr-london-daily-hearing-list/src/pdf/pdf-generator.ts-60-60 (1)

60-60: ⚠️ Potential issue | 🟠 Major

Use nullish coalescing to handle optional sizeBytes instead of non-null assertion.

The non-null assertion on pdfResult.sizeBytes! bypasses type safety. Although generatePdfFromHtml sets sizeBytes on success, the type system doesn't guarantee it remains non-undefined after the success and buffer checks at line 53. This leaves the code vulnerable to passing undefined to savePdfToStorage, which expects a number.

Proposed fix
-    return await savePdfToStorage(options.artefactId, pdfResult.pdfBuffer, pdfResult.sizeBytes!);
+    const sizeBytes = pdfResult.sizeBytes ?? pdfResult.pdfBuffer.length;
+    return await savePdfToStorage(options.artefactId, pdfResult.pdfBuffer, sizeBytes);
libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/pdf/pdf-generator.ts-60-60 (1)

60-60: ⚠️ Potential issue | 🟠 Major

Remove non-null assertion on sizeBytes and provide a fallback value.

The sizeBytes property is optional in PdfGenerationResult, yet the non-null assertion bypasses type safety without runtime verification. If sizeBytes is absent, the function still proceeds to check size limits with an undefined value.

Suggested fix
-    return await savePdfToStorage(options.artefactId, pdfResult.pdfBuffer, pdfResult.sizeBytes!);
+    const sizeBytes = pdfResult.sizeBytes ?? pdfResult.pdfBuffer.length;
+    return await savePdfToStorage(options.artefactId, pdfResult.pdfBuffer, sizeBytes);
apps/web/src/pages/(list-types)/wpafcc-weekly-hearing-list/index.ts-18-19 (1)

18-19: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Externalise the temp upload directory path here as well

Line 18-19 hardcodes runtime filesystem layout. Please move this directory into env/config, consistent with other runtime settings.

As per coding guidelines, "Use environment variables for all configuration values and secrets, never hardcode them".

Source: Coding guidelines

libs/location/src/list-type-data.ts-360-360 (1)

360-360: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Do not ship Welsh placeholder text in list metadata

welshFriendlyName for ids 31 and 32 is still placeholder content. This will appear verbatim in Welsh journeys and breaks bilingual readiness for these list types.

This conflicts with the PR objective claiming complete English/Welsh support for all five new list types.

Also applies to: 372-372

apps/web/src/pages/(list-types)/grc-weekly-hearing-list/index.ts-18-19 (1)

18-19: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Externalise the temp upload directory path

Hardcoding MONOREPO_ROOT/TEMP_UPLOAD_DIR at Line 18-19 makes runtime behaviour depend on directory depth. Please source this from environment/config and only fall back to a safe default.

Proposed change
-const MONOREPO_ROOT = path.join(__dirname, "..", "..", "..", "..", "..", "..");
-const TEMP_UPLOAD_DIR = path.join(MONOREPO_ROOT, "storage", "temp", "uploads");
+const TEMP_UPLOAD_DIR =
+  process.env.TEMP_UPLOAD_DIR ??
+  path.join(process.cwd(), "storage", "temp", "uploads");

As per coding guidelines, "Use environment variables for all configuration values and secrets, never hardcode them".

Source: Coding guidelines

apps/web/src/pages/(admin)/non-strategic-upload-summary/index.ts-23-25 (1)

23-25: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Welsh locale can now show English list names

At Line 23-25, shortenedFriendlyName takes precedence for both locales. In cy, this can override available Welsh names and surface English text.

Proposed locale-safe precedence
-const listTypeName = listType
-  ? listType.shortenedFriendlyName || (locale === "cy" ? listType.welshFriendlyName : listType.friendlyName) || uploadData.listType
-  : uploadData.listType;
+const listTypeName = listType
+  ? locale === "cy"
+    ? listType.welshFriendlyName || listType.shortenedFriendlyName || listType.friendlyName || uploadData.listType
+    : listType.shortenedFriendlyName || listType.friendlyName || uploadData.listType
+  : uploadData.listType;

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

apps/web/src/pages/(list-types)/utiac-jr-london-daily-hearing-list/index.ts-32-33 (1)

32-33: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Localise error messages for Welsh requests.

All error responses are currently hardcoded in English, so Welsh users can receive non-Welsh error content. Route these messages through locale content objects.

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

Also applies to: 44-45, 59-60, 72-73, 101-102

Source: Coding guidelines

apps/web/src/pages/(list-types)/utiac-statutory-appeal-daily-hearing-list/index.ts-32-33 (1)

32-33: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Localise error messages for Welsh requests.

All error responses are currently hardcoded in English, so Welsh users can receive non-Welsh error content. Route these messages through locale content objects.

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

Also applies to: 44-45, 59-60, 72-73, 101-102

Source: Coding guidelines

apps/web/src/pages/(list-types)/utiac-jr-london-daily-hearing-list/index.ts-64-64 (1)

64-64: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Handle JSON parse failures as invalid data, not server errors.

A malformed uploaded JSON file currently drops into the outer catch and returns 500. This is bad input and should return the same 400 invalid-data response as schema validation failures.

Suggested fix
-    const jsonData: UtiacJrLondonHearingList = JSON.parse(jsonContent);
+    let jsonData: UtiacJrLondonHearingList;
+    try {
+      jsonData = JSON.parse(jsonContent) as UtiacJrLondonHearingList;
+    } catch {
+      return res.status(400).render("errors/common", {
+        en,
+        cy,
+        errorTitle: "Invalid Data",
+        errorMessage: "The list data is invalid"
+      });
+    }

Also applies to: 96-103

apps/web/src/pages/(list-types)/utiac-jr-london-daily-hearing-list/index.ts-55-56 (1)

55-56: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid logging raw error payloads in this path.

These console.error calls log raw exceptions and validation details. Keep logs sanitised (stable error codes/metadata only) to reduce risk of sensitive data leakage.

As per coding guidelines, "Never include sensitive data in application logs".

Also applies to: 68-68, 97-97

Source: Coding guidelines

apps/web/src/pages/(list-types)/utiac-statutory-appeal-daily-hearing-list/index.ts-55-56 (1)

55-56: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid logging raw error payloads in this path.

These console.error calls log raw exceptions and validation details. Keep logs sanitised (stable error codes/metadata only) to reduce risk of sensitive data leakage.

As per coding guidelines, "Never include sensitive data in application logs".

Also applies to: 68-68, 97-97

Source: Coding guidelines

apps/web/src/pages/(list-types)/utiac-statutory-appeal-daily-hearing-list/index.ts-64-64 (1)

64-64: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Handle JSON parse failures as invalid data, not server errors.

A malformed uploaded JSON file currently drops into the outer catch and returns 500. This is bad input and should return the same 400 invalid-data response as schema validation failures.

Suggested fix
-    const jsonData: UtiacStatutoryAppealHearingList = JSON.parse(jsonContent);
+    let jsonData: UtiacStatutoryAppealHearingList;
+    try {
+      jsonData = JSON.parse(jsonContent) as UtiacStatutoryAppealHearingList;
+    } catch {
+      return res.status(400).render("errors/common", {
+        en,
+        cy,
+        errorTitle: "Invalid Data",
+        errorMessage: "The list data is invalid"
+      });
+    }

Also applies to: 96-103

🟡 Minor comments (6)
libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/conversion/utiac-sa-config.ts-64-66 (1)

64-66: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Rename converter constant to SCREAMING_SNAKE_CASE.

This constant breaches the project naming rule for constants; rename it and update the two registration calls.

Suggested patch
-const utiacSaConverter = createConverter(UTIAC_SA_EXCEL_CONFIG);
-registerConverter(30, utiacSaConverter);
-registerConverterByName("UTIAC_STATUTORY_APPEAL_DAILY_HEARING_LIST", utiacSaConverter);
+const UTIAC_SA_CONVERTER = createConverter(UTIAC_SA_EXCEL_CONFIG);
+registerConverter(30, UTIAC_SA_CONVERTER);
+registerConverterByName("UTIAC_STATUTORY_APPEAL_DAILY_HEARING_LIST", UTIAC_SA_CONVERTER);

As per coding guidelines, "Use SCREAMING_SNAKE_CASE for constant declarations (e.g., MAX_FILE_SIZE, DEFAULT_TIMEOUT)".

Source: Coding guidelines

libs/list-types/grc-weekly-hearing-list/src/config.ts-4-5 (1)

4-5: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use SCREAMING_SNAKE_CASE for local constants to match repo rule.

Rename these locals to upper snake case for consistency with the project’s constant naming standard.

Suggested patch
-const __filename = fileURLToPath(import.meta.url);
-const __dirname = path.dirname(__filename);
+const __FILENAME = fileURLToPath(import.meta.url);
+const __DIRNAME = path.dirname(__FILENAME);

-export const moduleRoot = __dirname;
-export const assets = path.join(__dirname, "assets/");
-export const schemaPath = path.join(__dirname, "schemas/grc-weekly-hearing-list.json");
+export const moduleRoot = __DIRNAME;
+export const assets = path.join(__DIRNAME, "assets/");
+export const schemaPath = path.join(__DIRNAME, "schemas/grc-weekly-hearing-list.json");

As per coding guidelines, "Use SCREAMING_SNAKE_CASE for constant declarations (e.g., MAX_FILE_SIZE, DEFAULT_TIMEOUT)".

Source: Coding guidelines

libs/list-types/utiac-jr-leeds-daily-hearing-list/src/pdf/pdf-template.njk-53-53 (1)

53-53: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localise the empty-state message.

No hearings scheduled. is hard-coded, so Welsh PDFs will still show English when there are no hearings.

💡 Proposed fix
-    <p>No hearings scheduled.</p>
+    <p>{{ t.noHearingsScheduled }}</p>
libs/list-types/utiac-jr-london-daily-hearing-list/src/pdf/pdf-template.njk-55-55 (1)

55-55: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localise the empty-state message.

No hearings scheduled. is hard-coded and bypasses translation keys, so Welsh output is incomplete when no hearings exist.

💡 Proposed fix
-    <p>No hearings scheduled.</p>
+    <p>{{ t.noHearingsScheduled }}</p>
libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/pdf/pdf-template.njk-55-55 (1)

55-55: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Localise the no-hearings fallback text.

The empty-state string is hard-coded in English, which breaks full Welsh localisation for this PDF path.

💡 Proposed fix
-    <p>No hearings scheduled.</p>
+    <p>{{ t.noHearingsScheduled }}</p>
apps/web/src/pages/(list-types)/grc-weekly-hearing-list/index.test.ts-111-111 (1)

111-111: ⚠️ Potential issue | 🟡 Minor

Remove as any casts from mocked artefact objects

TypeScript strict mode is enabled and the Artefact interface is fully defined and exported. The mockArtefact objects already conform to the Artefact type, so the as any casts are unnecessary and bypass type safety. Prefer using satisfies Artefact or rely on type inference to catch potential shape regressions.

Applies to lines: 111, 186, 213, 267

Source: Coding guidelines

🧹 Nitpick comments (28)
docs/tickets/429/plan.md (1)

31-62: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Add language specifier to the fenced code block.

For consistency with markdown best practices and to assist syntax highlighting, add a language identifier to the code fence. Change:

<<<<<<< line 31

libs/list-types/grc-weekly-hearing-list/

to:

```bash
libs/list-types/grc-weekly-hearing-list/

(Use `bash` or `text` depending on the intent; here `text` is more appropriate since this is a directory tree, not executable code.)

<!-- cr-comment:v1:add37a15150023272a4a92dd -->

</blockquote></details>
<details>
<summary>libs/list-types/wpafcc-weekly-hearing-list/src/locales/en.ts (1)</summary><blockquote>

`3-3`: _🧹 Nitpick_ | _🔵 Trivial_ | _⚡ Quick win_

**Align exported constant naming with SCREAMING_SNAKE_CASE.**

`en` is a constant declaration and does not follow the constant naming rule. Use an uppercase constant and export it as `en` to preserve the public contract.

<details>
<summary>Suggested change</summary>

```diff
-export const en = {
+const EN = {
@@
-};
+};
+
+export { EN as en };

As per coding guidelines, "Use SCREAMING_SNAKE_CASE for constant declarations (e.g., MAX_FILE_SIZE, DEFAULT_TIMEOUT)".

Source: Coding guidelines

libs/list-types/utiac-jr-leeds-daily-hearing-list/src/locales/en.ts (1)

3-3: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use SCREAMING_SNAKE_CASE for the locale constant.

en is declared as a constant but does not follow the naming convention. Prefer an uppercase constant and export alias to keep the existing API shape.

Suggested change
-export const en = {
+const EN = {
@@
-};
+};
+
+export { EN as en };

As per coding guidelines, "Use SCREAMING_SNAKE_CASE for constant declarations (e.g., MAX_FILE_SIZE, DEFAULT_TIMEOUT)".

Source: Coding guidelines

libs/list-types/utiac-jr-leeds-daily-hearing-list/src/locales/cy.ts (1)

1-34: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Welsh translations incomplete: nine fields have placeholder text.

Lines 4, 5, 13, 17, and 19–24 contain [WELSH TRANSLATION REQUIRED: ...] placeholders. These will render as English fallback text rather than Welsh. If Welsh language support is required for this release, complete the translations; otherwise, document this as a known limitation or defer to a follow-up task.

libs/list-types/utiac-jr-leeds-daily-hearing-list/src/conversion/utiac-jr-leeds-config.ts (1)

58-60: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Align constant naming with SCREAMING_SNAKE_CASE convention.

Rename the converter constant to match the repo constant naming rule.

Suggested diff
-const utiacJrLeedsConverter = createConverter(UTIAC_JR_LEEDS_EXCEL_CONFIG);
-registerConverter(32, utiacJrLeedsConverter);
-registerConverterByName("UTIAC_JR_LEEDS_DAILY_HEARING_LIST", utiacJrLeedsConverter);
+const UTIAC_JR_LEEDS_CONVERTER = createConverter(UTIAC_JR_LEEDS_EXCEL_CONFIG);
+registerConverter(32, UTIAC_JR_LEEDS_CONVERTER);
+registerConverterByName("UTIAC_JR_LEEDS_DAILY_HEARING_LIST", UTIAC_JR_LEEDS_CONVERTER);

As per coding guidelines, "Use SCREAMING_SNAKE_CASE for constant declarations (e.g., MAX_FILE_SIZE, DEFAULT_TIMEOUT)".

Source: Coding guidelines

libs/list-types/utiac-jr-london-daily-hearing-list/src/conversion/utiac-jr-london-config.ts (1)

64-66: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use SCREAMING_SNAKE_CASE for the converter constant.

Please rename this constant to follow the project constant naming convention.

Suggested diff
-const utiacJrLondonConverter = createConverter(UTIAC_JR_LONDON_EXCEL_CONFIG);
-registerConverter(31, utiacJrLondonConverter);
-registerConverterByName("UTIAC_JR_LONDON_DAILY_HEARING_LIST", utiacJrLondonConverter);
+const UTIAC_JR_LONDON_CONVERTER = createConverter(UTIAC_JR_LONDON_EXCEL_CONFIG);
+registerConverter(31, UTIAC_JR_LONDON_CONVERTER);
+registerConverterByName("UTIAC_JR_LONDON_DAILY_HEARING_LIST", UTIAC_JR_LONDON_CONVERTER);

As per coding guidelines, "Use SCREAMING_SNAKE_CASE for constant declarations (e.g., MAX_FILE_SIZE, DEFAULT_TIMEOUT)".

Source: Coding guidelines

libs/list-types/wpafcc-weekly-hearing-list/src/rendering/renderer.ts (1)

4-22: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Reorder exported symbols to match module export ordering.

Move exported function declarations above exported interfaces/types in this module.

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.

Source: Coding guidelines

libs/list-types/wpafcc-weekly-hearing-list/src/rendering/renderer.test.ts (1)

5-140: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add a Welsh-locale assertion for renderer output.

Current cases only assert locale: "en". Add at least one locale: "cy" assertion for header date/time formatting to guard the EN/CY i18n path introduced in this change set.

libs/list-types/grc-weekly-hearing-list/src/rendering/renderer.ts (1)

4-22: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Align export order with repository TypeScript convention.

Please place exported functions before exported interfaces/types in this module.

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.

Source: Coding guidelines

libs/list-types/utiac-jr-leeds-daily-hearing-list/src/rendering/renderer.ts (1)

4-22: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Reorder module exports so interfaces/types are last.

This file currently exports interfaces before the exported renderer function; please reorder to match the project’s module layout rule.

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.

Source: Coding guidelines

libs/list-types/utiac-jr-london-daily-hearing-list/src/rendering/renderer.ts (1)

4-22: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Apply the repository export-order pattern in this renderer module.

Reorder exports so the exported function is declared before exported interfaces/types.

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.

Source: Coding guidelines

libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/rendering/renderer.ts (1)

4-22: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Reorder exports to keep interfaces/types at the bottom of the module.

Please move exported interfaces below the exported renderer function for consistency with the project rule.

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.

Source: Coding guidelines

libs/list-types/grc-weekly-hearing-list/src/pdf/pdf-generator.ts (1)

20-24: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Move the local type to the bottom of the module.

PdfGenerationOptions is declared before the exported function; this file should place interfaces/types at the bottom for consistency with the project rule.

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”.

Source: Coding guidelines

libs/list-types/grc-weekly-hearing-list/src/pdf/pdf-generator.test.ts (1)

23-46: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Rename top-level constants to SCREAMING_SNAKE_CASE.

mockRenderedData and mockHearingList should follow the repository constant naming rule.

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

Source: Coding guidelines

libs/list-types/wpafcc-weekly-hearing-list/src/pdf/pdf-generator.ts (1)

20-24: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Move the local type declaration to the bottom of the file.

PdfGenerationOptions currently appears before the exported function; keep interfaces/types at the bottom to match the module ordering rule.

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”.

Source: Coding guidelines

libs/list-types/wpafcc-weekly-hearing-list/src/pdf/pdf-generator.test.ts (1)

23-44: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Apply SCREAMING_SNAKE_CASE to top-level constants.

Top-level constants (mockRenderedData, mockHearingList) do not follow the project naming convention.

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

Source: Coding guidelines

libs/list-types/utiac-jr-london-daily-hearing-list/src/index.ts (1)

4-11: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Place the type export after value exports in this barrel.

export type { ValidationResult } is currently above value exports; move type/interface exports to the bottom.

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”.

Source: Coding guidelines

libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/index.ts (1)

4-11: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Reorder exports so type exports are at the bottom.

export type { ValidationResult } should be moved below the value exports to follow the module ordering convention.

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”.

Source: Coding guidelines

libs/list-types/utiac-jr-leeds-daily-hearing-list/src/pdf/pdf-generator.ts (1)

17-23: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Align constant naming and type placement with repository rules.

Line 17–18 constants are not SCREAMING_SNAKE_CASE, and Line 20 interface placement is above the exported function rather than at the bottom.

Suggested refactor
-const __filename = fileURLToPath(import.meta.url);
-const __dirname = path.dirname(__filename);
-
-interface PdfGenerationOptions extends BasePdfGenerationOptions<UtiacJrLeedsHearingList> {
-  displayFrom: Date;
-}
+const __FILENAME = fileURLToPath(import.meta.url);
+const __DIRNAME = path.dirname(__FILENAME);
@@
-    const env = configureNunjucks(__dirname);
+    const env = configureNunjucks(__DIRNAME);
@@
 }
+
+interface PdfGenerationOptions extends BasePdfGenerationOptions<UtiacJrLeedsHearingList> {
+  displayFrom: Date;
+}

As per coding guidelines, "Use SCREAMING_SNAKE_CASE for constant declarations (e.g., MAX_FILE_SIZE, DEFAULT_TIMEOUT)" and "**/*.ts: ... with interfaces and types at the bottom".

Source: Coding guidelines

libs/list-types/utiac-jr-leeds-daily-hearing-list/src/pdf/pdf-generator.test.ts (1)

23-44: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use SCREAMING_SNAKE_CASE for test constants.

Line 23 and Line 33 constants (mockRenderedData, mockHearingList) do not match the repository naming rule for constants.

As per coding guidelines, "Use SCREAMING_SNAKE_CASE for constant declarations (e.g., MAX_FILE_SIZE, DEFAULT_TIMEOUT)".

Source: Coding guidelines

libs/list-types/grc-weekly-hearing-list/src/index.ts (1)

4-11: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Move type exports to the bottom of the module export block.

ValidationResult type export is currently above value exports; this should be placed last to match the TS export-order rule.

As per coding guidelines, "**/*.ts: Order module exports ... with interfaces and types at the bottom".

Source: Coding guidelines

libs/list-types/wpafcc-weekly-hearing-list/src/index.ts (1)

4-11: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Move type exports to the bottom of the module export block.

ValidationResult type export should come after value exports to comply with the project’s TS export ordering convention.

As per coding guidelines, "**/*.ts: Order module exports ... with interfaces and types at the bottom".

Source: Coding guidelines

libs/list-types/utiac-jr-leeds-daily-hearing-list/src/index.ts (1)

4-11: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Move type exports to the bottom of the module export block.

ValidationResult type export is currently before value exports; place it at the end to match the repository rule.

As per coding guidelines, "**/*.ts: Order module exports ... with interfaces and types at the bottom".

Source: Coding guidelines

libs/list-types/utiac-jr-london-daily-hearing-list/src/pdf/pdf-generator.ts (1)

20-24: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Move the interface/type declaration to the bottom of the module.

Place PdfGenerationOptions after exported and internal functions to match the project’s TypeScript ordering convention.
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”.

Source: Coding guidelines

libs/list-types/utiac-jr-london-daily-hearing-list/src/pdf/pdf-generator.test.ts (1)

55-79: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add an explicit oversize PDF test case.

This suite misses the exceedsMaxSize path; adding the >2MB scenario here would lock down behaviour consistently across list types.

libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/pdf/pdf-generator.ts (1)

20-24: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Move interface/type declarations to the end of the module.

PdfGenerationOptions should be placed at the bottom to follow the project’s export/type ordering rule.
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”.

Source: Coding guidelines

apps/web/src/pages/(list-types)/utiac-jr-london-daily-hearing-list/index.test.ts (1)

59-276: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add regression tests for malformed JSON and Welsh error output.

Please add cases for invalid JSON payloads (parse failure path) and res.locals.locale = "cy" error rendering. That will lock the controller’s failure contracts and i18n behaviour.

apps/web/src/pages/(list-types)/utiac-statutory-appeal-daily-hearing-list/index.test.ts (1)

59-276: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Add regression tests for malformed JSON and Welsh error output.

Please add cases for invalid JSON payloads (parse failure path) and res.locals.locale = "cy" error rendering. This keeps failure handling and i18n behaviour locked down.


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8dfc9363-1873-454e-bca3-359a6dd704d4

📥 Commits

Reviewing files that changed from the base of the PR and between 5a364d0 and f0d6a25.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (109)
  • apps/web/src/app.ts
  • apps/web/src/assets/css/back-to-top.scss
  • apps/web/src/pages/(admin)/non-strategic-upload-summary/index.ts
  • apps/web/src/pages/(list-types)/grc-weekly-hearing-list/grc-weekly-hearing-list.njk
  • apps/web/src/pages/(list-types)/grc-weekly-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/grc-weekly-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-jr-leeds-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/utiac-jr-leeds-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-jr-leeds-daily-hearing-list/utiac-jr-leeds-daily-hearing-list.njk
  • apps/web/src/pages/(list-types)/utiac-jr-london-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/utiac-jr-london-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-jr-london-daily-hearing-list/utiac-jr-london-daily-hearing-list.njk
  • apps/web/src/pages/(list-types)/utiac-statutory-appeal-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/utiac-statutory-appeal-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-statutory-appeal-daily-hearing-list/utiac-statutory-appeal-daily-hearing-list.njk
  • apps/web/src/pages/(list-types)/wpafcc-weekly-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/wpafcc-weekly-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/wpafcc-weekly-hearing-list/wpafcc-weekly-hearing-list.njk
  • apps/web/src/pages/(public)/summary-of-publications/index.ts
  • docs/tickets/429/plan.md
  • docs/tickets/429/review.md
  • docs/tickets/429/tasks.md
  • docs/tickets/429/ticket.md
  • libs/list-types/grc-weekly-hearing-list/package.json
  • libs/list-types/grc-weekly-hearing-list/src/config.ts
  • libs/list-types/grc-weekly-hearing-list/src/conversion/grc-config.ts
  • libs/list-types/grc-weekly-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/grc-weekly-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/grc-weekly-hearing-list/src/index.ts
  • libs/list-types/grc-weekly-hearing-list/src/locales/cy.ts
  • libs/list-types/grc-weekly-hearing-list/src/locales/en.ts
  • libs/list-types/grc-weekly-hearing-list/src/models/types.ts
  • libs/list-types/grc-weekly-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/grc-weekly-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/grc-weekly-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/grc-weekly-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/grc-weekly-hearing-list/src/rendering/renderer.ts
  • libs/list-types/grc-weekly-hearing-list/src/schemas/grc-weekly-hearing-list.json
  • libs/list-types/grc-weekly-hearing-list/tsconfig.json
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/package.json
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/config.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/conversion/utiac-jr-leeds-config.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/schemas/utiac-jr-leeds-daily-hearing-list.json
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/tsconfig.json
  • libs/list-types/utiac-jr-london-daily-hearing-list/package.json
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/config.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/conversion/utiac-jr-london-config.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/schemas/utiac-jr-london-daily-hearing-list.json
  • libs/list-types/utiac-jr-london-daily-hearing-list/tsconfig.json
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/package.json
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/config.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/conversion/utiac-sa-config.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/schemas/utiac-statutory-appeal-daily-hearing-list.json
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/tsconfig.json
  • libs/list-types/wpafcc-weekly-hearing-list/package.json
  • libs/list-types/wpafcc-weekly-hearing-list/src/config.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/conversion/wpafcc-config.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/index.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/locales/cy.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/locales/en.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/models/types.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/wpafcc-weekly-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/rendering/renderer.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/schemas/wpafcc-weekly-hearing-list.json
  • libs/list-types/wpafcc-weekly-hearing-list/tsconfig.json
  • libs/location/src/list-type-data.ts
  • libs/notifications/package.json
  • libs/notifications/src/notification/notification-service.ts
  • libs/publication/package.json
  • libs/publication/src/processing/service.ts
  • tsconfig.json

junaidiqbalmoj and others added 4 commits June 22, 2026 10:00
…ormation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hearing lists

Implements IDs 33-35 following the same pattern as the existing London (31)
and Leeds (32) variants. Each includes web rendering, PDF generation, email
summary extraction, Excel conversion, and English/Welsh i18n.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The upload validation dynamically imports each list type package and looks for
an exported function starting with "validate". All 8 packages were missing this,
causing schema validation to fail. Added src/validation/json-validator.ts and
exported the validate function from index.ts for each package.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… JR list types

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

@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: 12

🧹 Nitpick comments (7)
apps/web/src/pages/(list-types)/utiac-jr-manchester-daily-hearing-list/index.test.ts (1)

109-109: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Replace as any fixture casts with a narrow typed test factory.

The casts on Line 109, Line 202, Line 230, and Line 265 bypass strict checks and can mask fixture contract drift.

As per coding guidelines, “Enable TypeScript strict mode and avoid any type without justification”.

Also applies to: 202-202, 230-230, 265-265

Source: Coding guidelines

libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/rendering/renderer.ts (1)

4-20: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Move interfaces/types below function exports to match module ordering rules.

Place RenderOptions and RenderedData at the bottom of the module after exported function declarations.

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”.

Source: Coding guidelines

libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/config.ts (1)

7-9: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use SCREAMING_SNAKE_CASE for exported constants in config.

Rename exported constants to SCREAMING_SNAKE_CASE for consistency with repository standards.

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

Source: Coding guidelines

libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/pdf/pdf-generator.ts (1)

20-24: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Reorder module members to keep types at the bottom.

PdfGenerationOptions is currently declared before the exported function, which breaks the module ordering convention used in this repo.

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

Suggested reorder
-interface PdfGenerationOptions extends BasePdfGenerationOptions<UtiacJrCardiffHearingList> {
-  displayFrom: Date;
-}
-
 export async function generateUtiacJrCardiffDailyHearingListPdf(options: PdfGenerationOptions): Promise<PdfGenerationResult> {
   // ...
 }
+
+interface PdfGenerationOptions extends BasePdfGenerationOptions<UtiacJrCardiffHearingList> {
+  displayFrom: Date;
+}

Source: Coding guidelines

libs/list-types/utiac-jr-manchester-daily-hearing-list/src/rendering/renderer.ts (1)

4-20: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Move exported interfaces below function exports to match module order convention.

The interfaces are declared before the exported function in this module; please place interfaces/types at the bottom for consistency with the repo rule.

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

Source: Coding guidelines

libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/rendering/renderer.ts (1)

4-22: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Reorder exports to keep interfaces/types at the bottom.

The exported interfaces are declared before the exported function, which conflicts with the module ordering rule.

♻️ Suggested reorder
-export interface RenderOptions {
-  locale: string;
-  courtName: string;
-  displayFrom: Date;
-  lastReceivedDate: string;
-  listTitle: string;
-}
-
-export interface RenderedData {
-  header: {
-    listTitle: string;
-    listForDate: string;
-    lastUpdatedDate: string;
-    lastUpdatedTime: string;
-  };
-  hearings: UtiacJrCardiffHearing[];
-}
-
 export function renderUtiacJrCardiffDailyHearingListData(hearingList: UtiacJrCardiffHearingList, options: RenderOptions): RenderedData {
   const listForDate = formatDisplayDate(options.displayFrom, options.locale);
   const { date: lastUpdatedDate, time: lastUpdatedTime } = formatLastUpdatedDateTime(options.lastReceivedDate, options.locale);
@@
   };
 }
+
+export interface RenderOptions {
+  locale: string;
+  courtName: string;
+  displayFrom: Date;
+  lastReceivedDate: string;
+  listTitle: string;
+}
+
+export interface RenderedData {
+  header: {
+    listTitle: string;
+    listForDate: string;
+    lastUpdatedDate: string;
+    lastUpdatedTime: string;
+  };
+  hearings: UtiacJrCardiffHearing[];
+}

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".

Source: Coding guidelines

libs/list-types/utiac-jr-manchester-daily-hearing-list/src/config.ts (1)

7-9: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Use SCREAMING_SNAKE_CASE for exported module constants.

These module-level constants are currently camelCase and do not follow the constant naming standard.

♻️ Suggested rename pattern
-export const moduleRoot = __dirname;
-export const assets = path.join(__dirname, "assets/");
-export const schemaPath = path.join(__dirname, "schemas/utiac-jr-manchester-daily-hearing-list.json");
+export const MODULE_ROOT = __dirname;
+export const ASSETS = path.join(__dirname, "assets/");
+export const SCHEMA_PATH = path.join(__dirname, "schemas/utiac-jr-manchester-daily-hearing-list.json");

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

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6aa7ad60-9e3b-4a5c-a7a8-5792d945acbb

📥 Commits

Reviewing files that changed from the base of the PR and between f0d6a25 and 4f5d8fa.

📒 Files selected for processing (69)
  • apps/web/src/app.ts
  • apps/web/src/pages/(list-types)/utiac-jr-birmingham-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/utiac-jr-birmingham-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-jr-birmingham-daily-hearing-list/utiac-jr-birmingham-daily-hearing-list.njk
  • apps/web/src/pages/(list-types)/utiac-jr-cardiff-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/utiac-jr-cardiff-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-jr-cardiff-daily-hearing-list/utiac-jr-cardiff-daily-hearing-list.njk
  • apps/web/src/pages/(list-types)/utiac-jr-manchester-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/utiac-jr-manchester-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-jr-manchester-daily-hearing-list/utiac-jr-manchester-daily-hearing-list.njk
  • apps/web/src/pages/(list-types)/utiac-statutory-appeal-daily-hearing-list/utiac-statutory-appeal-daily-hearing-list.njk
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/package.json
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/config.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/conversion/utiac-jr-birmingham-config.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/schemas/utiac-jr-birmingham-daily-hearing-list.json
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/tsconfig.json
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/package.json
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/config.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/conversion/utiac-jr-cardiff-config.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/schemas/utiac-jr-cardiff-daily-hearing-list.json
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/tsconfig.json
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/package.json
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/config.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/conversion/utiac-jr-manchester-config.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/schemas/utiac-jr-manchester-daily-hearing-list.json
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/tsconfig.json
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/wpafcc-weekly-hearing-list/src/schemas/wpafcc-weekly-hearing-list.json
  • libs/location/src/list-type-data.ts
  • libs/notifications/package.json
  • libs/notifications/src/notification/notification-service.ts
  • libs/publication/package.json
  • libs/publication/src/processing/service.ts
  • tsconfig.json
✅ Files skipped from review due to trivial changes (19)
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/tsconfig.json
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/tsconfig.json
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/schemas/utiac-jr-birmingham-daily-hearing-list.json
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/schemas/utiac-jr-manchester-daily-hearing-list.json
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/config.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/tsconfig.json
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/package.json
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/package.json
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/package.json
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/index.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/wpafcc-weekly-hearing-list/src/schemas/wpafcc-weekly-hearing-list.json
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/locales/en.ts
  • libs/notifications/src/notification/notification-service.ts
  • libs/publication/package.json
  • tsconfig.json
  • apps/web/src/pages/(list-types)/utiac-statutory-appeal-daily-hearing-list/utiac-statutory-appeal-daily-hearing-list.njk
  • libs/publication/src/processing/service.ts
  • libs/notifications/package.json
  • libs/location/src/list-type-data.ts

Comment thread apps/web/src/pages/(list-types)/utiac-jr-birmingham-daily-hearing-list/index.ts Outdated
Comment thread apps/web/src/pages/(list-types)/utiac-jr-cardiff-daily-hearing-list/index.ts Outdated
Comment thread apps/web/src/pages/(list-types)/utiac-jr-manchester-daily-hearing-list/index.ts Outdated
Comment thread apps/web/src/pages/(list-types)/utiac-jr-manchester-daily-hearing-list/index.ts Outdated
Comment on lines +101 to +127
it("should pass correct render options to renderer", async () => {
// Arrange
vi.mocked(generatePdfFromHtml).mockResolvedValue({
success: true,
pdfBuffer: Buffer.from("PDF"),
sizeBytes: 100
});

const displayFrom = new Date("2025-06-15");

// Act
await generateUtiacJrManchesterDailyHearingListPdf({
artefactId: "test-render-options",
displayFrom,
locale: "cy",
locationId: "999",
jsonData: mockHearingList
});

// Assert
expect(renderUtiacJrManchesterDailyHearingListData).toHaveBeenCalledWith(mockHearingList, {
locale: "cy",
courtName: "Upper Tribunal (Immigration and Asylum) Chamber",
displayFrom,
lastReceivedDate: expect.any(String),
listTitle: "Upper Tribunal (Immigration and Asylum) Chamber - Judicial Review: Manchester Daily Hearing 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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Update the Welsh-locale assertion to a Welsh title source.

The test sets locale: "cy" but expects an English listTitle, which locks in non-localised behaviour and reduces useful i18n coverage.

Suggested fix
+import { utiacJrManchesterDailyHearingListCy } from "../locales/cy.js";
...
     expect(renderUtiacJrManchesterDailyHearingListData).toHaveBeenCalledWith(mockHearingList, {
       locale: "cy",
       courtName: "Upper Tribunal (Immigration and Asylum) Chamber",
       displayFrom,
       lastReceivedDate: expect.any(String),
-      listTitle: "Upper Tribunal (Immigration and Asylum) Chamber - Judicial Review: Manchester Daily Hearing List"
+      listTitle: utiacJrManchesterDailyHearingListCy.pageTitle
     });

Comment thread libs/list-types/utiac-jr-manchester-daily-hearing-list/src/pdf/pdf-generator.ts Outdated
junaidiqbalmoj and others added 3 commits June 22, 2026 11:05
…hema structure

Replace London-style fields (location, representative) with Leeds-style fields
(venue) for Manchester and Birmingham UTIAC JR list types across schemas,
types, Excel config, renderers, templates, and locales.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace London-style fields (location, representative) with Leeds-style fields
(venue) across schema, types, Excel config, renderer, templates, locales, and
tests. Add Cardiff to PACKAGE_ALIASES so JSON schema validation also uses Leeds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… PDF across Leeds/Manchester/Birmingham/Cardiff

All four UTIAC JR daily hearing list variants share identical structure.
This commit eliminates the duplication by:

- Extracting a single shared Nunjucks web template into the Leeds lib
  (utiac-jr-daily-hearing-list.njk) and pointing all four controllers at it
- Exporting shared pdfTemplateDir, UtiacJrHearing types, renderUtiacJrDailyHearingListData,
  and extractCaseSummary from the Leeds lib
- Replacing duplicate renderer, types, email-summary, and PDF template files
  in Manchester, Birmingham, and Cardiff with re-exports from Leeds
- Adding conversion config tests for all four variants to bring coverage above 80%
- Adding provenance branch coverage tests to all four PDF generators

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

@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: 2

🧹 Nitpick comments (3)
libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/rendering/renderer.ts (1)

1-2: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Reorder exports to keep types at the bottom.

Swap these two exports so the function export comes first and the type export is last in the module.

Suggested ordering
-export type { RenderedData, RenderOptions } from "`@hmcts/utiac-jr-leeds-daily-hearing-list`";
 export { renderUtiacJrDailyHearingListData as renderUtiacJrCardiffDailyHearingListData } from "`@hmcts/utiac-jr-leeds-daily-hearing-list`";
+export type { RenderedData, RenderOptions } from "`@hmcts/utiac-jr-leeds-daily-hearing-list`";

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

Source: Coding guidelines

libs/list-types/utiac-jr-manchester-daily-hearing-list/src/email-summary/summary-builder.ts (1)

1-1: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Order re-exported constant before re-exported functions.

Please place SPECIAL_CATEGORY_DATA_WARNING first in this export list to match module export ordering conventions.

Proposed fix
-export { extractCaseSummary, formatCaseSummaryForEmail, SPECIAL_CATEGORY_DATA_WARNING } from "`@hmcts/utiac-jr-leeds-daily-hearing-list`";
+export { SPECIAL_CATEGORY_DATA_WARNING, extractCaseSummary, formatCaseSummaryForEmail } from "`@hmcts/utiac-jr-leeds-daily-hearing-list`";

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”.

Source: Coding guidelines

libs/list-types/utiac-jr-manchester-daily-hearing-list/src/rendering/renderer.ts (1)

1-2: 🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Reorder exports so the function export appears before type exports.

Move the aliased render function export above the type export to align with module export ordering conventions.

Proposed fix
-export type { RenderedData, RenderOptions } from "`@hmcts/utiac-jr-leeds-daily-hearing-list`";
 export { renderUtiacJrDailyHearingListData as renderUtiacJrManchesterDailyHearingListData } from "`@hmcts/utiac-jr-leeds-daily-hearing-list`";
+export type { RenderedData, RenderOptions } from "`@hmcts/utiac-jr-leeds-daily-hearing-list`";

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”.

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4ec7172f-9701-411b-9d0f-6411b9a15cd7

📥 Commits

Reviewing files that changed from the base of the PR and between 4f5d8fa and c8155b2.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (63)
  • apps/web/src/pages/(list-types)/utiac-jr-birmingham-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-jr-cardiff-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-jr-leeds-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-jr-manchester-daily-hearing-list/index.ts
  • libs/list-types/common/src/validation/list-type-validator.ts
  • libs/list-types/grc-weekly-hearing-list/src/index.ts
  • libs/list-types/grc-weekly-hearing-list/src/validation/json-validator.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/conversion/utiac-jr-birmingham-config.test.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/conversion/utiac-jr-birmingham-config.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/schemas/utiac-jr-birmingham-daily-hearing-list.json
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/validation/json-validator.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/conversion/utiac-jr-cardiff-config.test.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/conversion/utiac-jr-cardiff-config.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/schemas/utiac-jr-cardiff-daily-hearing-list.json
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/validation/json-validator.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/config.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/conversion/utiac-jr-leeds-config.test.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/utiac-jr-daily-hearing-list.njk
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/validation/json-validator.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/validation/json-validator.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/conversion/utiac-jr-manchester-config.test.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/conversion/utiac-jr-manchester-config.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/schemas/utiac-jr-manchester-daily-hearing-list.json
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/validation/json-validator.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/validation/json-validator.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/index.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/validation/json-validator.ts
💤 Files with no reviewable changes (1)
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/utiac-jr-daily-hearing-list.njk
✅ Files skipped from review due to trivial changes (13)
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/validation/json-validator.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/conversion/utiac-jr-cardiff-config.test.ts
  • libs/list-types/grc-weekly-hearing-list/src/validation/json-validator.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/locales/en.ts
  • libs/list-types/common/src/validation/list-type-validator.ts
  • libs/list-types/grc-weekly-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/email-summary/summary-builder.test.ts
🚧 Files skipped from review as they are similar to previous changes (26)
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/config.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/conversion/utiac-jr-birmingham-config.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/conversion/utiac-jr-manchester-config.ts
  • libs/list-types/utiac-jr-london-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-leeds-daily-hearing-list/src/models/types.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/index.ts
  • libs/list-types/wpafcc-weekly-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/locales/en.ts
  • libs/list-types/utiac-jr-birmingham-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • apps/web/src/pages/(list-types)/utiac-jr-cardiff-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-jr-birmingham-daily-hearing-list/index.ts
  • libs/list-types/utiac-statutory-appeal-daily-hearing-list/src/index.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/rendering/renderer.test.ts
  • apps/web/src/pages/(list-types)/utiac-jr-manchester-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/utiac-jr-leeds-daily-hearing-list/index.ts
  • libs/list-types/utiac-jr-cardiff-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/utiac-jr-manchester-daily-hearing-list/src/rendering/renderer.test.ts

Comment on lines +23 to +27
"hearingTime": {
"title": "Hearing time",
"type": "string",
"pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$",
"examples": ["10:00am"]

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.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

hearingTime schema does not enforce time format.

Line 26 only blocks HTML tags. This diverges from the converter contract (validateTimeFormatSimple) and allows invalid times through JSON validation that Excel ingestion would reject.

Suggested schema tightening
       "hearingTime": {
         "title": "Hearing time",
         "type": "string",
-        "pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$",
+        "pattern": "^(?:[1-9]|1[0-2])(?::[0-5][0-9])?(?:am|pm)$",
         "examples": ["10:00am"]
       },

Comment on lines +129 to +149
it("should include provenance label in rendered output when provenance is provided", async () => {
// Arrange
vi.mocked(generatePdfFromHtml).mockResolvedValue({
success: true,
pdfBuffer: Buffer.from("PDF"),
sizeBytes: 100
});

// Act
const result = await generateUtiacJrLeedsDailyHearingListPdf({
artefactId: "provenance-test",
displayFrom: new Date("2025-01-15"),
locale: "en",
locationId: "240",
jsonData: mockHearingList,
provenance: "MANUAL_UPLOAD"
});

// Assert
expect(result.success).toBe(true);
});

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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Provenance test currently verifies success only.

Line 129 says the test checks provenance label rendering, but Line 148 only asserts successful execution. Please assert the rendered HTML/path includes the provenance-derived text so this branch is genuinely covered.

Suggested strengthening
   it("should include provenance label in rendered output when provenance is provided", async () => {
@@
     // Assert
     expect(result.success).toBe(true);
+    expect(generatePdfFromHtml).toHaveBeenCalledTimes(1);
+    const [html] = vi.mocked(generatePdfFromHtml).mock.calls[0];
+    expect(html).toMatch(/manual upload|MANUAL_UPLOAD/i);
   });

junaidiqbalmoj and others added 6 commits June 22, 2026 12:31
…across all 4 variants

Extract shared locale fields into baseEn/baseCy in Leeds; Manchester/Birmingham/Cardiff
spread the base and override only pageTitle. Delete 3 redundant JSON schema files (runtime
already redirects via PACKAGE_ALIASES). Replace duplicate PDF generator implementations with
a factory pattern from Leeds, deferring instantiation to avoid circular init.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…olidation refactor

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…on from list-type libs

Replace imports of ValidationResult, validateJson, and PROVENANCE_LABELS from
@hmcts/publication with equivalents already in @hmcts/list-types-common.
Remove @hmcts/publication from package.json for all 8 affected list-type libs
to eliminate the publication -> list-types -> publication cycle detected by Turborepo.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ype libs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ordering issue

Top-level const caused "createJsonValidator is not a function" when publication
loaded these modules before list-types-common was fully initialised. Move the
call inside the exported function so it runs lazily at call time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…m/Manchester/Cardiff variants

These 3 variants have no src/schemas/ or src/pdf/*.njk — they delegate to Leeds.
The copy commands were failing with "No matches found".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@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.

Revert the $schema declaration back to draft-07 across all four schemas
and revert the AJV import to the standard build — 2020-12 is not needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@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.

…AFCC subject line text

- Zero-pad single-digit days in formatDisplayDate, formatLastUpdatedDateTime, and formatDdMmYyyyDate (day: "2-digit" / "dd MMMM yyyy")
- Split GRC importantInformationText into two paragraphs so the recording/criminal offence sentence renders separately in HTML and PDF
- Update WPAFCC importantInformationText subject line to include "(need to include any other information required by the tribunal)"
- Update renderer and date-formatting tests to expect zero-padded dates

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@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 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.

@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 dace5aa into master Jul 3, 2026
26 checks passed
hmctsclaudecode Bot pushed a commit that referenced this pull request Jul 9, 2026
10 STATUS + IMPL changes (closed issue + merged closing PR → verified):
  REQ-0078 (#301): implemented → verified (PR #458)
  REQ-0105 (#428): in_progress  → verified (PR #749)
  REQ-0106 (#429): approved     → verified (PR #761)
  REQ-0107 (#431): implemented → verified (PR #701)
  REQ-0108 (#434): approved     → verified (PR #772)
  REQ-0109 (#436): implemented → verified (PR #727)
  REQ-0112 (#467): implemented → verified (PR #670)
  REQ-0124 (#563): approved     → verified (PR #782)
  REQ-0135 (#569): in_progress  → verified (PR #748)
  REQ-0137 (#729): approved     → verified (PR #766)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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: Tribunal non-strategic publishing - GRC, WPAFCC & UTIAC

3 participants