Skip to content

Feature/431 sscs tribunal non strategic publishing - #701

Merged
junaidiqbalmoj merged 27 commits into
masterfrom
feature/431-sscs-tribunal-non-strategic-publishing
Jul 3, 2026
Merged

Feature/431 sscs tribunal non strategic publishing#701
junaidiqbalmoj merged 27 commits into
masterfrom
feature/431-sscs-tribunal-non-strategic-publishing

Conversation

@junaidiqbalmoj

@junaidiqbalmoj junaidiqbalmoj commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Jira link

#431

Change description

Add SSCS Lists

Summary by CodeRabbit

Release Notes

  • New Features

    • Added SSCS Daily Hearing List publishing for eight regions (Midlands, South East, Wales & South West, Scotland, North East, North West, London, Liverpool).
    • Enabled generation of PDFs and automated email notifications for SSCS Daily Hearing Lists.
    • Added Welsh language support for SSCS Daily Hearing List pages and generated content.
  • Bug Fixes

    • Improved SSCS Daily Hearing List routing/module registration and reliability during startup.
  • Documentation

    • Added implementation task checklist and code review notes for SSCS Tribunal non-strategic publishing.

junaidiqbalmoj and others added 4 commits June 10, 2026 16:27
- Add 8 new SSCS Tribunal locations across 4 new regions (South West, Scotland, North East, North West)
- Add 8 new SSCS list types (SSCS_MIDLANDS through SSCS_LIVERPOOL) as non-strategic with MANUAL_UPLOAD provenance
- Implement new sscs-daily-hearing-list library module with page controller, Nunjucks template, PDF generator, email summary builder, Excel converter, JSON schema, and English/Welsh translations
- Register module in apps/web and root tsconfig

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
It was showing error on screen and not displaying anything
@coderabbitai

coderabbitai Bot commented Jun 10, 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 a new @hmcts/sscs-daily-hearing-list workspace package with Excel conversion, JSON schema validation, a data renderer, email summary builder, PDF generator, and a web page controller. Eight SSCS regional list types (IDs 28–35) and corresponding location/region data are registered. The module is wired into publication PDF processing, admin upload handlers, notifications, and web app routing.

Changes

SSCS Daily Hearing List Implementation

Layer / File(s) Summary
Module structure, contracts, and base configuration
libs/list-types/sscs-daily-hearing-list/package.json, libs/list-types/sscs-daily-hearing-list/tsconfig.json, libs/list-types/sscs-daily-hearing-list/src/config.ts, libs/list-types/sscs-daily-hearing-list/src/config.test.ts, libs/list-types/sscs-daily-hearing-list/src/models/types.ts, libs/list-types/sscs-daily-hearing-list/src/schemas/sscs-daily-hearing-list.json
Creates ESM package manifest, TypeScript project config, ESM-safe moduleRoot/pageRoutes/assets exports, SscsDailyHearing interface, SscsDailyHearingList type, and draft-07 JSON schema with HTML-tag-rejecting patterns; validated by config test suite.
List-type and location reference data
libs/location/src/list-type-data.ts, libs/location/src/location-data.ts
Appends eight SSCS daily hearing list entries (IDs 28–35) to listTypeData; adds eight tribunal location entries (IDs 13–20) and four new regions (IDs 7–10) to locationData.
Excel conversion and converter registration
libs/list-types/sscs-daily-hearing-list/src/conversion/sscs-config.ts, libs/list-types/sscs-daily-hearing-list/src/conversion/sscs-config.test.ts
Defines SSCS_EXCEL_CONFIG with nine fields (required/optional), per-field validateNoHtmlTags validators, and minRows: 1; creates one converter and registers it for eight numeric IDs and eight list names; tests verify fields, headers, required flags, and HTML-tag validator behaviour.
Renderer, email summary, and module public API
libs/list-types/sscs-daily-hearing-list/src/rendering/renderer.ts, libs/list-types/sscs-daily-hearing-list/src/rendering/renderer.test.ts, libs/list-types/sscs-daily-hearing-list/src/email-summary/summary-builder.ts, libs/list-types/sscs-daily-hearing-list/src/email-summary/summary-builder.test.ts, libs/list-types/sscs-daily-hearing-list/src/index.ts
Exports renderSscsDailyHearingListData (header + hearings) and extractCaseSummary (labelled case-summary tuples); index.ts registers converters via side-effect import and re-exports all public API; both modules are fully unit tested.
PDF generator and Nunjucks PDF template
libs/list-types/sscs-daily-hearing-list/src/pdf/pdf-generator.ts, libs/list-types/sscs-daily-hearing-list/src/pdf/pdf-template.njk, libs/list-types/sscs-daily-hearing-list/src/pdf/pdf-generator.test.ts
generateSscsDailyHearingListPdf renders list data into pdf-template.njk, generates PDF via generatePdfFromHtml, persists to storage, and returns typed success/failure results; template renders header, important-information box, conditional hearings table, and optional footer; tests cover success, oversize, generation failure, and renderer-options verification.
Page controller, Nunjucks page template, and controller tests
apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.ts, apps/web/src/pages/(list-types)/sscs-daily-hearing-list/sscs-daily-hearing-list.njk, apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.test.ts
GET handler reads artefactId, loads and schema-validates the uploaded JSON, derives locale-aware list title and important-information text, renders view; returns 400/404/500 on error conditions; page template renders header, expandable important-information details, searchable hearings table, and data source; 356-line test suite covers all error branches and locale/content assertions.
Publication PDF pipeline integration
libs/publication/src/processing/service.ts, libs/publication/src/processing/service.test.ts, libs/publication/package.json
Introduces SSCS_FRIENDLY_NAMES map and sscsGeneratorForListType factory; extends PDF_GENERATOR_REGISTRY with eight SSCS region entries; adds en/cy generatePublicationPdf tests asserting list title, court name, important-information text, and PDF result fields.
Web app routing, admin wiring, notifications, and path aliases
tsconfig.json, apps/web/src/app.ts, apps/web/src/app.test.ts, apps/web/src/pages/(admin)/non-strategic-upload/index.ts, apps/web/src/pages/(admin)/non-strategic-upload-summary/index.ts, libs/admin-pages/package.json, apps/web/src/pages/(admin)/non-strategic-upload/index.test.ts, apps/web/src/pages/(admin)/non-strategic-upload-summary/index.test.ts, libs/notifications/package.json, libs/notifications/src/notification/notification-service.ts, libs/list-types/common/src/validation/list-type-validator.test.ts
Adds TS path aliases for the new package; registers sscsDailyHearingListModuleRoot in configureGovuk modulePaths; adds side-effect imports in admin upload/summary handlers; wires SSCS case summary extraction and email formatting into EMAIL_BUILDER_REGISTRY for eight SSCS list type names; updates test mocks and applies as any session-cast fixes in existing upload tests; updates validator test fixture to include SJP list type and civil daily cause list mock.
Ticket documentation
docs/tickets/431/tasks.md, docs/tickets/431/review.md
Adds completed task checklist and code review report for Issue #431, noting unresolved Welsh localisation gap, unused _t parameter, and email capitalisation typo.

Possibly related issues

  • hmcts/cath-service#597: This PR implements the SSCS Daily Hearing List module—including config, models, schema, rendering, PDF generation, page controller, and list type registration—which directly corresponds to the acceptance criteria in that issue.

Possibly related PRs

  • hmcts/cath-service#320: Extends the publication PDF processing pipeline in libs/publication/src/processing/service.ts with new list-type generator factories; this PR uses the same pattern for SSCS.
  • hmcts/cath-service#204: Modifies apps/web/src/app.ts to register additional hearing-list module roots via configureGovuk(...) modulePaths, the same integration point used in this PR.
  • hmcts/cath-service#663: Integrates a new daily list module by extending configureGovuk(...) modulePaths in apps/web/src/app.ts, using the same mechanism as this PR for SSCS.
🚥 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 references the main change: SSCS tribunal non-strategic publishing integration. It correctly identifies the feature's core domain and purpose.
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.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/431-sscs-tribunal-non-strategic-publishing

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.

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

🧹 Nitpick comments (5)
libs/system-admin-pages/src/user-management/validation.ts (1)

1-1: ⚡ Quick win

Consider deleting unused constant.

The underscore prefix suppresses the linter warning but retains dead code. Per YAGNI principle, this constant should be removed entirely.

(Note: docs/tickets/431/review.md already documents this as a suggestion.)

🧹 Proposed fix
-const _ALPHANUMERIC_REGEX = /^[a-zA-Z0-9]+$/;
 const UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
libs/publication/src/processing/service.test.ts (1)

287-308: 💤 Low value

Consider verifying importantInformationText in the Welsh test.

The Welsh locale test verifies listTitle and courtName but not importantInformationText. Whilst the English test already covers this field, adding the assertion here would make the test more complete and self-contained.

📝 Suggested addition
 expect(generateSscsDailyHearingListPdf).toHaveBeenCalledWith(
   expect.objectContaining({
     listTitle: "Rhestr Gwrandawiadau Dyddiol Tribiwnlys Nawdd Cymdeithasol a Chynhaliaeth Plant Gogledd Ddwyrain Lloegr",
-    courtName: "Rhestr Gwrandawiadau Dyddiol Tribiwnlys Nawdd Cymdeithasol a Chynhaliaeth Plant Gogledd Ddwyrain Lloegr"
+    courtName: "Rhestr Gwrandawiadau Dyddiol Tribiwnlys Nawdd Cymdeithasol a Chynhaliaeth Plant Gogledd Ddwyrain Lloegr",
+    importantInformationText: "Important information for North East"
   })
 );
libs/list-types/sscs-daily-hearing-list/package.json (1)

17-17: ⚖️ Poor tradeoff

Consider simplifying the Nunjucks build script.

The nested shell commands with find, mkdir -p, and variable substitution are fragile and may fail on non-Unix platforms or with unusual file paths.

Alternative approach using simpler commands
-    "build:nunjucks": "mkdir -p dist/pages && cd src/pages && find . -name '*.njk' -exec sh -c 'mkdir -p ../../dist/pages/$(dirname {}) && cp {} ../../dist/pages/{}' \\; && cd ../.. && mkdir -p dist/pdf && cd src/pdf && find . -name '*.njk' -exec sh -c 'mkdir -p ../../dist/pdf/$(dirname {}) && cp {} ../../dist/pdf/{}' \\;",
+    "build:nunjucks": "mkdir -p dist/pages dist/pdf && cp -R src/pages/*.njk dist/pages/ && cp -R src/pdf/*.njk dist/pdf/",

Or use a Node.js script for cross-platform reliability.

libs/list-types/sscs-daily-hearing-list/src/conversion/sscs-config.test.ts (1)

33-44: ⚡ Quick win

Test coverage gap: should explicitly verify optional fields.

The test "should mark most fields as required" only verifies that certain fields are marked required, but doesn't check that additionalInformation is marked optional. This gap means the schema/converter mismatch wouldn't be caught by tests.

🧪 Proposed test improvement
   it("should mark most fields as required", () => {
     const requiredFields = SSCS_EXCEL_CONFIG.fields.filter((f) => f.required).map((f) => f.fieldName);
+    const optionalFields = SSCS_EXCEL_CONFIG.fields.filter((f) => !f.required).map((f) => f.fieldName);
 
     expect(requiredFields).toContain("venue");
     expect(requiredFields).toContain("appealReferenceNumber");
     expect(requiredFields).toContain("hearingType");
     expect(requiredFields).toContain("appellant");
     expect(requiredFields).toContain("courtroom");
     expect(requiredFields).toContain("hearingTime");
     expect(requiredFields).toContain("tribunal");
     expect(requiredFields).toContain("respondent");
+    
+    expect(optionalFields).toContain("additionalInformation");
+    expect(optionalFields.length).toBe(1);
   });
libs/list-types/sscs-daily-hearing-list/src/pages/index.ts (1)

89-92: ⚡ Quick win

Simplify nested ternary for better readability.

The nested ternary operator for determining listTitle is difficult to follow. Consider extracting this logic into a helper function or using if-else statements.

♻️ Proposed refactor
-    const listTitle =
-      locale === "cy"
-        ? (listTypeEntry?.welshFriendlyName ?? listTypeEntry?.englishFriendlyName ?? t.listForDate)
-        : (listTypeEntry?.englishFriendlyName ?? t.listForDate);
+    const listTitle = 
+      locale === "cy" 
+        ? listTypeEntry?.welshFriendlyName || listTypeEntry?.englishFriendlyName || t.listForDate
+        : listTypeEntry?.englishFriendlyName || t.listForDate;

Alternatively, extract to a helper function:

function getListTitle(listTypeEntry: any, locale: string, fallback: string): string {
  if (locale === "cy") {
    return listTypeEntry?.welshFriendlyName || listTypeEntry?.englishFriendlyName || fallback;
  }
  return listTypeEntry?.englishFriendlyName || fallback;
}

const listTitle = getListTitle(listTypeEntry, locale, t.listForDate);

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3fcf502f-a42f-4c81-90a1-14b098e496c2

📥 Commits

Reviewing files that changed from the base of the PR and between 8116021 and eac6f31.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (36)
  • apps/web/src/app.test.ts
  • apps/web/src/app.ts
  • docs/tickets/431/review.md
  • docs/tickets/431/tasks.md
  • libs/admin-pages/package.json
  • libs/admin-pages/src/pages/non-strategic-upload-summary/index.ts
  • libs/admin-pages/src/pages/non-strategic-upload/index.ts
  • libs/list-types/sscs-daily-hearing-list/package.json
  • libs/list-types/sscs-daily-hearing-list/src/config.test.ts
  • libs/list-types/sscs-daily-hearing-list/src/config.ts
  • libs/list-types/sscs-daily-hearing-list/src/conversion/sscs-config.test.ts
  • libs/list-types/sscs-daily-hearing-list/src/conversion/sscs-config.ts
  • libs/list-types/sscs-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/sscs-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/sscs-daily-hearing-list/src/index.ts
  • libs/list-types/sscs-daily-hearing-list/src/models/types.ts
  • libs/list-types/sscs-daily-hearing-list/src/pages/cy.ts
  • libs/list-types/sscs-daily-hearing-list/src/pages/en.ts
  • libs/list-types/sscs-daily-hearing-list/src/pages/index.test.ts
  • libs/list-types/sscs-daily-hearing-list/src/pages/index.ts
  • libs/list-types/sscs-daily-hearing-list/src/pages/sscs-daily-hearing-list.njk
  • libs/list-types/sscs-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/sscs-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/sscs-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/sscs-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/sscs-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/sscs-daily-hearing-list/src/schemas/sscs-daily-hearing-list.json
  • libs/list-types/sscs-daily-hearing-list/tsconfig.json
  • libs/location/src/list-type-data.ts
  • libs/location/src/location-data.ts
  • libs/publication/package.json
  • libs/publication/src/processing/service.test.ts
  • libs/publication/src/processing/service.ts
  • libs/subscriptions/src/repository/service.test.ts
  • libs/system-admin-pages/src/user-management/validation.ts
  • tsconfig.json

path: path.join(__dirname, "pages"),
prefix: "/sscs-daily-hearing-list"
};
export const assets = path.join(__dirname, "assets/");

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify if assets directory exists and if the assets export is used anywhere

# Check if assets directory exists
if [ -d "libs/list-types/sscs-daily-hearing-list/src/assets" ]; then
  echo "✓ Assets directory exists"
  fd -t f . libs/list-types/sscs-daily-hearing-list/src/assets
else
  echo "✗ Assets directory not found"
fi

# Search for usage of the assets export
echo ""
echo "Searching for usage of 'assets' import from config..."
rg -n "assets.*from.*sscs-daily-hearing-list.*config" --type=ts

Repository: hmcts/cath-service

Length of output: 146


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Locate any assets directory within the module path
echo "== assets directories under sscs-daily-hearing-list =="
fd -t d "assets" libs/list-types/sscs-daily-hearing-list || true
fd -t d "assets" libs/list-types/sscs-daily-hearing-list -a || true

# 2) Find the actual config.ts file path and search for imports of it
echo
echo "== Imports of config.ts (moduleRoot/pageRoutes/assets consumers) =="
rg -n "sscs-daily-hearing-list.*/config(\.js|\.ts)?|sscs-daily-hearing-list/src/config" . -S --type=ts --type=tsx || true

# 3) Search for symbol usage: `assets` import from this config module
echo
echo "== Imports that pull in `assets` from the config module =="
rg -n "from ['\"].*sscs-daily-hearing-list.*config['\"]" libs -S --type=ts --type=tsx | head -n 200 || true
rg -n "(\bassets\b)\s*[,}]" libs/list-types/sscs-daily-hearing-list -S --type=ts --type=tsx || true

# 4) Search for runtime reference to the exported value (string 'assets/' or path usage)
echo
echo "== Direct string/path references to 'assets/' in the repo =="
rg -n "assets/\"|\bassets\b\s*\)" . -S --type=ts --type=tsx --type=js --type=mjs || true

Repository: hmcts/cath-service

Length of output: 476


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Locate any assets directory within the module path
echo "== assets directories under sscs-daily-hearing-list =="
fd -t d "assets" libs/list-types/sscs-daily-hearing-list || true

# 2) Find imports of the config module from anywhere in the repo
echo
echo "== Imports of sscs-daily-hearing-list config module =="
rg -n "sscs-daily-hearing-list.*/config(\.js|\.ts)?|sscs-daily-hearing-list/src/config" . -S --type=ts --type=tsx || true

# 3) Search for consumers importing `assets` specifically
echo
echo "== Imports that include `assets` from the config module =="
rg -n "from ['\"].*sscs-daily-hearing-list.*config['\"]" . -S --type=ts --type=tsx | head -n 200 || true
rg -n "import\s*\{[^}]*\bassets\b[^}]*\}\s*from\s*['\"].*sscs-daily-hearing-list.*config['\"]" . -S --type=ts --type=tsx || true

# 4) Search for direct string/path references that might indicate usage
echo
echo "== Direct references to 'assets/' or `assets` path join =="
rg -n "assets/\"|path\.join\([^)]*['\"]assets\/?['\"]" . -S --type=ts --type=tsx || true

Repository: hmcts/cath-service

Length of output: 617


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate module config.ts
echo "== Locate config.ts =="
fd -t f "config.ts" libs/list-types/sscs-daily-hearing-list -a || true

# Inspect config.ts
CONFIG_PATH=$(fd -t f -a "config.ts" libs/list-types/sscs-daily-hearing-list | head -n 1 || true)
if [ -n "${CONFIG_PATH:-}" ]; then
  echo
  echo "== config.ts: content (first 200 lines) =="
  sed -n '1,200p' "$CONFIG_PATH" | cat -n
fi

# Check for assets directories
echo
echo "== assets directories under sscs-daily-hearing-list =="
fd -t d -i "assets" libs/list-types/sscs-daily-hearing-list || true

echo
echo "== specifically src/assets under module =="
if [ -d "libs/list-types/sscs-daily-hearing-list/src/assets" ]; then
  echo "✓ libs/list-types/sscs-daily-hearing-list/src/assets exists"
  fd -t f . libs/list-types/sscs-daily-hearing-list/src/assets || true
else
  echo "✗ libs/list-types/sscs-daily-hearing-list/src/assets does not exist"
fi

# Searches for imports / usage of `assets`
echo
echo "== Find imports that destructure `assets` from the module's config =="
rg -n --glob '*.ts' --glob '*.tsx' \
  "\\{[^}]*\\bassets\\b[^}]*\\}\\s*from\\s*['\"][^'\"]*sscs-daily-hearing-list[^'\"]*config['\"]" \
  libs || true

echo
echo "== Find any reference to `config.assets` in repo =="
rg -n --glob '*.ts' --glob '*.tsx' "\\bconfig\\.assets\\b" libs || true

echo
echo "== Find direct references to the exported string 'assets/' =="
rg -n --glob '*.ts' --glob '*.tsx' "\\bassets/\"" libs || true

echo
echo "== Find direct references to identifier `assets` within this list-type package =="
rg -n --glob '*.ts' --glob '*.tsx' "\\bassets\\b" libs/list-types/sscs-daily-hearing-list || true

Repository: hmcts/cath-service

Length of output: 4260


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate module config.ts
echo "== Locate config.ts =="
fd -t f "config.ts" libs/list-types/sscs-daily-hearing-list -a || true

# Inspect config.ts
CONFIG_PATH=$(fd -t f -a "config.ts" libs/list-types/sscs-daily-hearing-list | head -n 1 || true)
if [ -n "${CONFIG_PATH:-}" ]; then
  echo
  echo "== config.ts: content (first 200 lines) =="
  sed -n '1,200p' "$CONFIG_PATH" | cat -n
fi

# Check for assets directories
echo
echo "== assets directories under sscs-daily-hearing-list =="
fd -t d -i "assets" libs/list-types/sscs-daily-hearing-list || true

echo
echo "== specifically src/assets under module =="
if [ -d "libs/list-types/sscs-daily-hearing-list/src/assets" ]; then
  echo "✓ libs/list-types/sscs-daily-hearing-list/src/assets exists"
  fd -t f . libs/list-types/sscs-daily-hearing-list/src/assets || true
else
  echo "✗ libs/list-types/sscs-daily-hearing-list/src/assets does not exist"
fi

# Searches for imports / usage of `assets`
echo
echo "== Find imports that destructure `assets` from the module's config =="
rg -n --glob '*.ts' --glob '*.tsx' \
  "\\{[^}]*\\bassets\\b[^}]*\\}\\s*from\\s*['\"][^'\"]*sscs-daily-hearing-list[^'\"]*config['\"]" \
  libs || true

echo
echo "== Find any reference to `config.assets` in repo =="
rg -n --glob '*.ts' --glob '*.tsx' "\\bconfig\\.assets\\b" libs || true

echo
echo "== Find direct references to the string 'assets/' =="
rg -n --glob '*.ts' --glob '*.tsx' "\\bassets/\"" libs || true

echo
echo "== Find direct references to identifier `assets` within this list-type package =="
rg -n --glob '*.ts' --glob '*.tsx' "\\bassets\\b" libs/list-types/sscs-daily-hearing-list || true

Repository: hmcts/cath-service

Length of output: 4251


Check assets export usage in sscs-daily-hearing-list

  • libs/list-types/sscs-daily-hearing-list/src/config.ts exports assets pointing at __dirname/assets/ (trailing slash), but this module contains no assets/ directory.
  • No repo references were found that import { assets } from this config module or use config.assets; only libs/list-types/sscs-daily-hearing-list/src/config.test.ts references the export.

Either add the missing assets directory/files or remove/adjust the assets export + its test to match actual usage.

Comment thread apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.ts Outdated
Comment thread apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.ts Outdated
listTitle
});

const importantInformationText = getImportantInformationText(listTypeName, en);

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

Pass locale-specific translations to getImportantInformationText.

The function is called with the hardcoded en object instead of the locale-specific t, meaning Welsh pages will incorrectly display English important information text.

🐛 Proposed fix
-    const importantInformationText = getImportantInformationText(listTypeName, en);
+    const importantInformationText = getImportantInformationText(listTypeName, t);

Also update the function signature at line 25:

-function getImportantInformationText(listTypeName: string | undefined, _t: typeof en): string {
+function getImportantInformationText(listTypeName: string | undefined, t: typeof en | typeof cy): string {

Note: Currently the importantInformationByListType mapping only exists in en.ts. You'll need to create a Welsh version in cy.ts or handle the fallback appropriately.

📝 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
const importantInformationText = getImportantInformationText(listTypeName, en);
const importantInformationText = getImportantInformationText(listTypeName, t);

</span>
</summary>
<div class="govuk-details__text">
{% for line in importantInformationText.split('\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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add safety check for importantInformationText.

The code calls .split('\n') on importantInformationText without checking if it's defined. If the text is missing for a list type, this will cause a runtime error.

🛡️ Proposed fix
-        {% for line in importantInformationText.split('\n') %}
+        {% for line in (importantInformationText or '').split('\n') %}
           {% if line %}
📝 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
{% for line in importantInformationText.split('\n') %}
{% for line in (importantInformationText or '').split('\n') %}

Comment on lines +125 to +153
it("should pass correct render options to renderer", async () => {
vi.mocked(generatePdfFromHtml).mockResolvedValue({
success: true,
pdfBuffer: Buffer.from("PDF"),
sizeBytes: 100
});

const contentDate = new Date("2026-01-01");
const listTitle = "London Social Security and Child Support Tribunal Daily Hearing List";

await generateSscsDailyHearingListPdf({
artefactId: "test-render-options",
contentDate,
locale: "cy",
locationId: "19",
jsonData: mockHearingList,
listTitle,
courtName: "London Social Security and Child Support Tribunal",
importantInformationText: "Open justice is a fundamental principle."
});

expect(renderSscsDailyHearingListData).toHaveBeenCalledWith(mockHearingList, {
locale: "cy",
courtName: "London Social Security and Child Support Tribunal",
contentDate,
lastReceivedDate: expect.any(String),
listTitle
});
});

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.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Test does not verify lastReceivedDate value, allowing timestamp bugs to slip through.

Line 150 uses expect.any(String) which accepts any string value, including the hardcoded new Date().toISOString() currently in the implementation. The test should verify that the lastReceivedDate passed to the renderer matches the value from the artefact options, not just that it's present.

♻️ Strengthen the assertion
     await generateSscsDailyHearingListPdf({
       artefactId: "test-render-options",
       contentDate,
       locale: "cy",
       locationId: "19",
       jsonData: mockHearingList,
       listTitle,
       courtName: "London Social Security and Child Support Tribunal",
-      importantInformationText: "Open justice is a fundamental principle."
+      importantInformationText: "Open justice is a fundamental principle.",
+      lastReceivedDate: "2026-01-01T10:00:00Z"
     });

     expect(renderSscsDailyHearingListData).toHaveBeenCalledWith(mockHearingList, {
       locale: "cy",
       courtName: "London Social Security and Child Support Tribunal",
       contentDate,
-      lastReceivedDate: expect.any(String),
+      lastReceivedDate: "2026-01-01T10:00:00Z",
       listTitle
     });
📝 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
it("should pass correct render options to renderer", async () => {
vi.mocked(generatePdfFromHtml).mockResolvedValue({
success: true,
pdfBuffer: Buffer.from("PDF"),
sizeBytes: 100
});
const contentDate = new Date("2026-01-01");
const listTitle = "London Social Security and Child Support Tribunal Daily Hearing List";
await generateSscsDailyHearingListPdf({
artefactId: "test-render-options",
contentDate,
locale: "cy",
locationId: "19",
jsonData: mockHearingList,
listTitle,
courtName: "London Social Security and Child Support Tribunal",
importantInformationText: "Open justice is a fundamental principle."
});
expect(renderSscsDailyHearingListData).toHaveBeenCalledWith(mockHearingList, {
locale: "cy",
courtName: "London Social Security and Child Support Tribunal",
contentDate,
lastReceivedDate: expect.any(String),
listTitle
});
});
it("should pass correct render options to renderer", async () => {
vi.mocked(generatePdfFromHtml).mockResolvedValue({
success: true,
pdfBuffer: Buffer.from("PDF"),
sizeBytes: 100
});
const contentDate = new Date("2026-01-01");
const listTitle = "London Social Security and Child Support Tribunal Daily Hearing List";
await generateSscsDailyHearingListPdf({
artefactId: "test-render-options",
contentDate,
locale: "cy",
locationId: "19",
jsonData: mockHearingList,
listTitle,
courtName: "London Social Security and Child Support Tribunal",
importantInformationText: "Open justice is a fundamental principle.",
lastReceivedDate: "2026-01-01T10:00:00Z"
});
expect(renderSscsDailyHearingListData).toHaveBeenCalledWith(mockHearingList, {
locale: "cy",
courtName: "London Social Security and Child Support Tribunal",
contentDate,
lastReceivedDate: "2026-01-01T10:00:00Z",
listTitle
});
});

Comment on lines +29 to +35
const renderedData = renderSscsDailyHearingListData(options.jsonData, {
locale: options.locale,
courtName: options.courtName,
contentDate: options.contentDate,
lastReceivedDate: new Date().toISOString(),
listTitle: options.listTitle
});

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 | 🔴 Critical | ⚡ Quick win

Hardcoded lastReceivedDate timestamp produces incorrect "last updated" display.

Line 33 creates a fresh timestamp at PDF generation time rather than using the artefact's actual lastReceivedDate. This means the rendered PDF will show "last updated" as the generation time, not when the hearing list data was genuinely received, misrepresenting data freshness to users.

Add lastReceivedDate: string to PdfGenerationOptions (or ensure BasePdfGenerationOptions includes it) and pass the artefact's timestamp through.

🐛 Proposed fix
 interface PdfGenerationOptions extends BasePdfGenerationOptions<SscsDailyHearingList> {
   contentDate: Date;
   listTitle: string;
   courtName: string;
   importantInformationText: string;
+  lastReceivedDate: string;
 }
     const renderedData = renderSscsDailyHearingListData(options.jsonData, {
       locale: options.locale,
       courtName: options.courtName,
       contentDate: options.contentDate,
-      lastReceivedDate: new Date().toISOString(),
+      lastReceivedDate: options.lastReceivedDate,
       listTitle: options.listTitle
     });

@@ -0,0 +1,66 @@
<!DOCTYPE html>
<html lang="en">

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

Make the lang attribute dynamic to support Welsh.

The lang attribute is hardcoded to "en", but the template must support both English and Welsh locales. The locale is available in the rendering context and should be used here.

🌐 Proposed fix
-<html lang="en">
+<html lang="{{ locale }}">

You'll need to ensure locale is passed to the template context in pdf-generator.ts.

As per coding guidelines, every user-facing page must support both English and Welsh languages.

📝 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
<html lang="en">
<html lang="{{ locale }}">

Source: Coding guidelines

</tbody>
</table>
{% else %}
<p>No hearings scheduled.</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.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace hardcoded English text with translated string.

The text "No hearings scheduled." is hardcoded in English, breaking Welsh language support. Use a translated string from the t object instead.

🌐 Proposed fix
-    <p>No hearings scheduled.</p>
+    <p>{{ t.noHearingsScheduled }}</p>

Add the corresponding translations to en.ts and cy.ts:

// en.ts
noHearingsScheduled: "No hearings scheduled."

// cy.ts
noHearingsScheduled: "Dim gwrandawiadau wedi'u trefnu."

As per coding guidelines, every user-facing page must support both English and Welsh languages.

📝 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>No hearings scheduled.</p>
<p>{{ t.noHearingsScheduled }}</p>

Source: Coding guidelines

"type": "array",
"items": {
"type": "object",
"required": ["venue", "appealReferenceNumber", "hearingType", "appellant", "courtroom", "hearingTime", "tribunal", "respondent", "additionalInformation"],

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 | 🔴 Critical | ⚡ Quick win

Root cause: additionalInformation required/optional contract mismatch across schema and converter.

The JSON schema marks additionalInformation as required (line 8 of sscs-daily-hearing-list.json), whilst the Excel converter config marks it as optional (required: false on line 56 of sscs-config.ts). This contract violation will cause validation failures when Excel files lacking additional information are converted and then validated. Both files must agree on whether this field is required or optional.

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

@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

🎭 Playwright E2E Test Results

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

Results for commit 8cb85f3.

♻️ This comment has been updated with latest results.

@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 and others added 3 commits June 11, 2026 09:05
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Fixes YN0028 lockfile immutability error in CI caused by vitest version
mismatch after master merged chore(deps): update vitest monorepo to v4.1.8.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
…ishing

Resolves yarn.lock conflict by regenerating lockfile after merging master.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <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.

junaidiqbalmoj and others added 3 commits June 15, 2026 17:21
…blishing

# Conflicts:
#	apps/web/src/app.test.ts
#	apps/web/src/app.ts
#	apps/web/src/pages/(admin)/non-strategic-upload-summary/index.ts
#	apps/web/src/pages/(admin)/non-strategic-upload/index.ts
…ng new architecture

Move SSCS page controller, template, and tests from libs to apps/web/src/pages/(list-types)
following the pattern established in master. Move cy/en translations to libs/locales/,
export with camelCase aliases from index.ts, remove pageRoutes from config and add schemaPath.
Fix TypeScript errors in non-strategic upload tests and remove stale @ts-expect-error directive.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <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

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)/sscs-daily-hearing-list/index.ts (1)

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

Handle malformed JSON as invalid data, not a server error.

If JSON parsing fails, the request currently falls through to the outer catch and returns 500. This is bad input data and should return the existing 400 invalid-data response path.

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

     const validationResult = validate(jsonData);
🧹 Nitpick comments (1)
apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.test.ts (1)

349-349: Avoid as any in the render payload assertion.

The as any cast weakens strict typing in this test. Use toMatchObject with expect.stringContaining instead to maintain type safety without the escape hatch.

Suggested fix
-      expect((renderCall[1] as any).importantInformationText).toContain("sscsa-sutton@justice.gov.uk");
+      expect(renderCall[1]).toMatchObject({
+        importantInformationText: expect.stringContaining("sscsa-sutton@justice.gov.uk")
+      });

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0688aea4-b548-4512-b7bd-f5d7e3eaa6b0

📥 Commits

Reviewing files that changed from the base of the PR and between f544094 and 817a4fc.

📒 Files selected for processing (9)
  • apps/web/src/app.test.ts
  • apps/web/src/app.ts
  • apps/web/src/pages/(admin)/non-strategic-upload-summary/index.test.ts
  • apps/web/src/pages/(admin)/non-strategic-upload-summary/index.ts
  • apps/web/src/pages/(admin)/non-strategic-upload/index.test.ts
  • apps/web/src/pages/(admin)/non-strategic-upload/index.ts
  • apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/sscs-daily-hearing-list/sscs-daily-hearing-list.njk
💤 Files with no reviewable changes (1)
  • apps/web/src/pages/(list-types)/sscs-daily-hearing-list/sscs-daily-hearing-list.njk
✅ Files skipped from review due to trivial changes (2)
  • apps/web/src/pages/(admin)/non-strategic-upload-summary/index.test.ts
  • apps/web/src/pages/(admin)/non-strategic-upload/index.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/src/app.test.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

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

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)/sscs-daily-hearing-list/index.ts (1)

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

Handle malformed JSON as invalid data, not a server error.

If JSON parsing fails, the request currently falls through to the outer catch and returns 500. This is bad input data and should return the existing 400 invalid-data response path.

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

     const validationResult = validate(jsonData);
🧹 Nitpick comments (1)
apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.test.ts (1)

349-349: Avoid as any in the render payload assertion.

The as any cast weakens strict typing in this test. Use toMatchObject with expect.stringContaining instead to maintain type safety without the escape hatch.

Suggested fix
-      expect((renderCall[1] as any).importantInformationText).toContain("sscsa-sutton@justice.gov.uk");
+      expect(renderCall[1]).toMatchObject({
+        importantInformationText: expect.stringContaining("sscsa-sutton@justice.gov.uk")
+      });

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 0688aea4-b548-4512-b7bd-f5d7e3eaa6b0

📥 Commits

Reviewing files that changed from the base of the PR and between f544094 and 817a4fc.

📒 Files selected for processing (9)
  • apps/web/src/app.test.ts
  • apps/web/src/app.ts
  • apps/web/src/pages/(admin)/non-strategic-upload-summary/index.test.ts
  • apps/web/src/pages/(admin)/non-strategic-upload-summary/index.ts
  • apps/web/src/pages/(admin)/non-strategic-upload/index.test.ts
  • apps/web/src/pages/(admin)/non-strategic-upload/index.ts
  • apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/sscs-daily-hearing-list/sscs-daily-hearing-list.njk
💤 Files with no reviewable changes (1)
  • apps/web/src/pages/(list-types)/sscs-daily-hearing-list/sscs-daily-hearing-list.njk
✅ Files skipped from review due to trivial changes (2)
  • apps/web/src/pages/(admin)/non-strategic-upload-summary/index.test.ts
  • apps/web/src/pages/(admin)/non-strategic-upload/index.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/src/app.test.ts
🛑 Comments failed to post (2)
apps/web/src/pages/(admin)/non-strategic-upload-summary/index.ts (1)

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

Use friendly English name as fallback before raw list type value.

At Line 24, the current fallback can render a raw identifier when Welsh text is missing, even if friendlyName exists. Prefer friendlyName before uploadData.listType to keep user-facing text readable.

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

Suggested patch
-  const listTypeName = listType ? (locale === "cy" ? listType.welshFriendlyName : listType.friendlyName) || uploadData.listType : uploadData.listType;
+  const listTypeName = listType
+    ? (locale === "cy" ? listType.welshFriendlyName : listType.friendlyName) || listType.friendlyName || uploadData.listType
+    : uploadData.listType;
📝 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.

  const listTypeName = listType
    ? (locale === "cy" ? listType.welshFriendlyName : listType.friendlyName) || listType.friendlyName || uploadData.listType
    : uploadData.listType;

Source: Coding guidelines

apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.ts (1)

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

Move upload-directory configuration to environment variables.

MONOREPO_ROOT/TEMP_UPLOAD_DIR are derived from a hardcoded relative filesystem layout. This is fragile across deployment layouts and breaks the repo’s configuration rule.

Suggested fix
-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;
+
+if (!TEMP_UPLOAD_DIR) {
+  throw new Error("TEMP_UPLOAD_DIR environment variable must be set");
+}

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

Source: Coding guidelines

junaidiqbalmoj and others added 3 commits June 16, 2026 08:56
…-list module

The civil-daily-cause-list module was added to the monorepo so the test for
'no JSON schema available' could no longer use CIVIL_DAILY_CAUSE_LIST (ID 1).
Switch to CROWN_COURT_DAILY_LIST (ID 99) which has no corresponding package,
and add a mock for @hmcts/civil-daily-cause-list to prevent the real module
import from causing test timeouts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The @hmcts/sscs-daily-hearing-list module registers converters at import
time via sscs-config.ts, which requires createConverter, registerConverter,
registerConverterByName and validateNoHtmlTags from @hmcts/list-types-common.
Using importOriginal spreads the real module so all exports are available,
matching the pattern used in care-standards-tribunal tests.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Register all 8 SSCS list type variants in EMAIL_BUILDER_REGISTRY so
Gov Notifier emails include the case summary and PDF download link.

Fixes missing email summary (HEARING_TIME, HEARING_TYPE, APPEAL_REFERENCE_NUMBER)
and missing PDF download link for SSCS publications.

Also adds missing @hmcts/civil-daily-cause-list, @hmcts/family-daily-cause-list,
and @hmcts/sscs-daily-hearing-list to notifications package dependencies.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <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: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9a94ef4f-b226-4651-9f51-365507b67981

📥 Commits

Reviewing files that changed from the base of the PR and between 817a4fc and 6a2c04e.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (4)
  • apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.test.ts
  • libs/list-types/common/src/validation/list-type-validator.test.ts
  • libs/notifications/package.json
  • libs/notifications/src/notification/notification-service.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/web/src/pages/(list-types)/sscs-daily-hearing-list/index.test.ts


const rcjStandardConfig: EmailBuilderConfig = { extract: extractRcjSummary as SummaryExtractor, format: formatRcjSummaryForEmail };
const adminCourtConfig: EmailBuilderConfig = { extract: extractAdminCourtSummary as SummaryExtractor, format: formatAdminCourtSummaryForEmail };
const sscsConfig: EmailBuilderConfig = { extract: extractSscsSummary as SummaryExtractor, format: formatSscsSummaryForEmail };

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

Use SCREAMING_SNAKE_CASE for the new constant.

Line 60 introduces sscsConfig, which breaks the repository constant naming rule. Rename it and its usages (e.g. SSCS_CONFIG) to keep lint/compliance consistent.

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

Suggested patch
-const sscsConfig: EmailBuilderConfig = { extract: extractSscsSummary as SummaryExtractor, format: formatSscsSummaryForEmail };
+const SSCS_CONFIG: EmailBuilderConfig = { extract: extractSscsSummary as SummaryExtractor, format: formatSscsSummaryForEmail };
@@
-  SSCS_LONDON_DAILY_HEARING_LIST: sscsConfig,
-  SSCS_MIDLANDS_DAILY_HEARING_LIST: sscsConfig,
-  SSCS_SOUTH_EAST_DAILY_HEARING_LIST: sscsConfig,
-  SSCS_WALES_AND_SOUTH_WEST_DAILY_HEARING_LIST: sscsConfig,
-  SSCS_SCOTLAND_DAILY_HEARING_LIST: sscsConfig,
-  SSCS_NORTH_EAST_DAILY_HEARING_LIST: sscsConfig,
-  SSCS_NORTH_WEST_DAILY_HEARING_LIST: sscsConfig,
-  SSCS_LIVERPOOL_DAILY_HEARING_LIST: sscsConfig
+  SSCS_LONDON_DAILY_HEARING_LIST: SSCS_CONFIG,
+  SSCS_MIDLANDS_DAILY_HEARING_LIST: SSCS_CONFIG,
+  SSCS_SOUTH_EAST_DAILY_HEARING_LIST: SSCS_CONFIG,
+  SSCS_WALES_AND_SOUTH_WEST_DAILY_HEARING_LIST: SSCS_CONFIG,
+  SSCS_SCOTLAND_DAILY_HEARING_LIST: SSCS_CONFIG,
+  SSCS_NORTH_EAST_DAILY_HEARING_LIST: SSCS_CONFIG,
+  SSCS_NORTH_WEST_DAILY_HEARING_LIST: SSCS_CONFIG,
+  SSCS_LIVERPOOL_DAILY_HEARING_LIST: SSCS_CONFIG

Source: Coding guidelines

junaidiqbalmoj and others added 2 commits June 29, 2026 16:17
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.

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

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

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

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

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

junaidiqbalmoj and others added 2 commits July 3, 2026 12:42
Resolves conflicts between SSCS tribunal list types (this branch) and the new
tribunal list types added in master (SIAC, FTT, GRC, SEND, WPAFCC, UTIAC etc).
Both sets of list types are preserved with non-overlapping IDs (SSCS renumbered
to 49-55 in list-type-data.ts, locations 17-24 in location-data.ts).

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 8698aff into master Jul 3, 2026
46 of 47 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 - SSCS Hearing Lists

3 participants