Skip to content

Feature-801- Add Chancery Appeals (ChD) daily cause list - #931

Open
alao-daniel wants to merge 1 commit into
masterfrom
Feature-801-Chancery-Appeals-(ChD)-daily-cause-list
Open

Feature-801- Add Chancery Appeals (ChD) daily cause list#931
alao-daniel wants to merge 1 commit into
masterfrom
Feature-801-Chancery-Appeals-(ChD)-daily-cause-list

Conversation

@alao-daniel

@alao-daniel alao-daniel commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Jira link

#801

Change description

implement chancery appeals daily cause list style guide + PDF
closes #801

Checklist

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

Summary by CodeRabbit

  • New Features
    • Added the Chancery Appeals (ChD) Daily Cause List.
    • Users can view hearing details, search cases, see important information and access data-source details.
    • Added English and Welsh language support.
    • Added PDF downloads and email notification support.
    • Added Excel upload and validation support for publishing lists.
  • Documentation
    • Added implementation guidance, acceptance criteria and review documentation.
  • Tests
    • Added coverage for page display, validation, translations, PDF generation and empty-list scenarios.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

The pull request adds the Chancery Appeals CHD daily cause list. It provides Excel conversion, Welsh and English rendering, PDF generation, web routing, notifications, publication registration, metadata, and supporting documentation.

Chancery Appeals CHD daily cause list

Layer / File(s) Summary
List module and conversion foundation
libs/list-types/chancery-appeals-chd-daily-cause-list/*, libs/list-types/common/src/list-type-data.ts, tsconfig.json
Adds the standalone list-type package, shared CHD/KB conversion configuration, list metadata, public exports, and Welsh and English locale data.
HTML and PDF rendering
libs/list-types/chancery-appeals-chd-daily-cause-list/src/rendering/*, libs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/*
Adds localised HTML rendering, PDF generation and templates, including hearing tables, empty states, provenance, caution text, and generation error results.
Web route and page rendering
apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/*
Adds the guarded GET handler and page template. The route validates artefacts, selects the locale, renders hearing data, and resolves provenance labels.
Application service registration
apps/web/src/app.ts, apps/web/src/pages/(admin)/*, libs/publication/*, libs/notifications/*, apps/web/package.json, docs/tickets/801/*
Registers the module with application paths, upload conversion, publication PDF processing, and notification email formatting. Adds ticket implementation records and workspace dependencies.

Sequence Diagram(s)

sequenceDiagram
  participant UploadRoute
  participant ChanceryAppealsChdConverter
  participant PublicationService
  participant ChanceryAppealsChdPdfGenerator
  participant NotificationService
  UploadRoute->>ChanceryAppealsChdConverter: convert uploaded Excel data
  ChanceryAppealsChdConverter-->>PublicationService: register validated hearing list
  PublicationService->>ChanceryAppealsChdPdfGenerator: generate downloadable PDF
  PublicationService->>NotificationService: build daily-list email summary
Loading

Possibly related issues

  • Issue 807: Adds a closely related Chancery Division daily cause-list module using shared CHD infrastructure.
  • Issue 813: Covers non-strategic Chancery Division cause-list publishing through Excel upload and PDF rendering.
  • Issue 808: Implements related Chancery Division validation, conversion, rendering, and registration flows.

Possibly related PRs

  • hmcts/cath-service#913: Adds another Chancery Division daily cause-list module using the same shared conversion, rendering, PDF, and notification integration points.
  • hmcts/cath-service#929: Adds a related Chancery Division list with parallel application, publication, notification, and list-type wiring.
  • hmcts/cath-service#856: Adds comprehensive Nunjucks rendering tests for Welsh, empty-state, and structural assertions.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.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 identifies the main change: adding the Chancery Appeals (ChD) daily cause list.
Linked Issues check ✅ Passed The changes address issue #801 through list registration, ordered validation, Excel upload support, rendering, localisation, PDF generation, and metadata.
Out of Scope Changes check ✅ Passed The reviewed changes support the Chancery Appeals daily cause list and issue #801 objectives without unrelated code changes.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch Feature-801-Chancery-Appeals-(ChD)-daily-cause-list

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


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: afaf772b-8564-4e82-960c-add651569440

📥 Commits

Reviewing files that changed from the base of the PR and between df61527 and 5dd6238.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (31)
  • apps/web/package.json
  • 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
  • apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/chancery-appeals-chd-daily-cause-list.njk
  • apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/chancery-appeals-chd-daily-cause-list.njk.test.ts
  • apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.test.ts
  • apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.ts
  • docs/tickets/801/plan.md
  • docs/tickets/801/review.md
  • docs/tickets/801/tasks.md
  • docs/tickets/801/ticket.md
  • libs/list-types/chancery-appeals-chd-daily-cause-list/package.json
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/config.ts
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/conversion/chancery-appeals-chd-daily-cause-list-config.test.ts
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/conversion/chancery-appeals-chd-daily-cause-list-config.ts
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/index.ts
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/locales/cy.ts
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/locales/en.ts
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-generator.ts
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-template.njk
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/rendering/renderer.test.ts
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/rendering/renderer.ts
  • libs/list-types/chancery-appeals-chd-daily-cause-list/tsconfig.json
  • libs/list-types/common/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

Comment thread apps/web/package.json
"@hmcts/auth": "workspace:*",
"@hmcts/azure-blob": "workspace:*",
"@hmcts/care-standards-tribunal-weekly-hearing-list": "workspace:*",
"@hmcts/chancery-appeals-chd-daily-cause-list": "workspace:*",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- package manifests ---'
for f in apps/web/package.json libs/notifications/package.json libs/publication/package.json; do
  echo "--- $f"
  cat -n "$f" | sed -n '1,90p'
done
printf '%s\n' '--- workspace configuration ---'
for f in package.json pnpm-workspace.yaml yarn.lock pnpm-lock.yaml package-lock.json; do
  if [ -f "$f" ]; then
    echo "--- $f"
    sed -n '1,180p' "$f"
  fi
done
printf '%s\n' '--- package identity and references ---'
rg -n --glob 'package.json' --glob '!node_modules/**' '"name"|"version"|`@hmcts/chancery-appeals-chd-daily-cause-list`|workspace:\*' .

Repository: hmcts/cath-service

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -e
target=$(git ls-files '*/package.json' | while read -r f; do
  if grep -q '"name": "`@hmcts/chancery-appeals-chd-daily-cause-list`"' "$f"; then
    printf '%s\n' "$f"
  fi
done)
printf '%s\n' '--- target package manifest ---'
for f in $target; do
  cat -n "$f"
done
printf '%s\n' '--- target package lock entries ---'
rg -n -A12 -B2 'chancery-appeals-chd-daily-cause-list' yarn.lock
printf '%s\n' '--- exact internal dependency usage ---'
rg -n '"`@hmcts/`[^"]+": "[0-9]+\.[0-9]+\.[0-9]+"' --glob 'package.json' apps libs | head -80

Repository: hmcts/cath-service

Length of output: 5340


Pin @hmcts/chancery-appeals-chd-daily-cause-list to 1.0.0.

Replace workspace:* with 1.0.0 in apps/web/package.json, libs/notifications/package.json, and libs/publication/package.json. This satisfies the repository requirement for pinned dependency versions.

📍 Affects 3 files
  • apps/web/package.json#L32-L32 (this comment)
  • libs/notifications/package.json#L25-L25
  • libs/publication/package.json#L27-L27

Source: Coding guidelines

Comment on lines +103 to +106
vi.mocked(getArtefactById).mockResolvedValue(mockArtefact as any);
vi.mocked(getPublicationJson).mockResolvedValue(mockJsonData);
mockValidate.mockReturnValue({ isValid: true, errors: [] });
vi.mocked(renderChanceryAppealsChdDailyCauseList).mockReturnValue(mockRenderedData as any);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -P '\bas\s+any\b|\bany\b' \
  'apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.test.ts'

Repository: hmcts/cath-service

Length of output: 1282


🏁 Script executed:

#!/bin/bash
set -euo pipefail

file='apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.test.ts'

printf '%s\n' '--- test structure and fixtures ---'
sed -n '1,140p' "$file"
printf '%s\n' '--- remaining test sections ---'
sed -n '140,270p' "$file"
sed -n '270,450p' "$file"

printf '%s\n' '--- related declarations and implementations ---'
rg -n -S \
  'getArtefactById|renderChanceryAppealsChdDailyCauseList|mockArtefact|mockRenderedData|mockJsonData' \
  'apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list' \
  apps/web/src/libs apps/web/src 2>/dev/null | head -200

Repository: hmcts/cath-service

Length of output: 43979


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- relevant tracked files ---'
git ls-files | rg '(^|/)(chancery-appeals-chd-daily-cause-list|publication|list-types-common)(/|$)|package.json$|tsconfig.*json$' | head -250

printf '%s\n' '--- imported symbol declarations ---'
rg -n -S \
  'export .*getArtefactById|function getArtefactById|const getArtefactById|export .*renderChanceryAppealsChdDailyCauseList|function renderChanceryAppealsChdDailyCauseList|const renderChanceryAppealsChdDailyCauseList' \
  --glob '*.ts' --glob '*.tsx' --glob '*.d.ts' . | head -200

printf '%s\n' '--- page controller ---'
cat -n 'apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.ts'

Repository: hmcts/cath-service

Length of output: 12078


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- publication artefact types and API ---'
sed -n '1,140p' libs/publication/src/repository/model.ts
sed -n '70,115p' libs/publication/src/repository/queries.ts
sed -n '1,120p' libs/publication/src/index.ts

printf '%s\n' '--- Chancery list types and renderer contract ---'
cat -n libs/list-types/chancery-appeals-chd-daily-cause-list/src/index.ts
cat -n libs/list-types/chancery-appeals-chd-daily-cause-list/src/rendering/renderer.ts

printf '%s\n' '--- shared handler input contract ---'
rg -n -S 'createSimpleListTypeHandler|type .*Artefact|interface .*Artefact|jsonData|render:' \
  'apps/web/src/pages/list-type-handler.ts' 'apps/web/src/pages/(list-types)' \
  --glob '*.ts' | head -160

Repository: hmcts/cath-service

Length of output: 28826


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- ChD/KB shared hearing types ---'
rg -n -S \
  'export (type|interface).*ChdKbHearing|type ChdKbHearing|interface ChdKbHearing|ChdKbHearingList' \
  libs/list-types/chd-kb-common --glob '*.ts'

printf '%s\n' '--- shared type definitions ---'
rg -l -S 'ChdKbHearing|ChdKbHearingList' libs/list-types/chd-kb-common --glob '*.ts' |
  while IFS= read -r file; do
    echo "### $file"
    sed -n '1,220p' "$file"
  done

printf '%s\n' '--- comparable typed fixture patterns ---'
rg -n -S 'satisfies (Artefact|.*HearingList|.*RenderedData)|function makeArtefact|const makeArtefact|type .*Fixture' \
  'apps/web/src/pages/(list-types)' --glob '*.test.ts' | head -160

Repository: hmcts/cath-service

Length of output: 11081


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

path = Path("apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.test.ts")
source = path.read_text()

required = {
    "artefactId", "type", "locationId", "listTypeId", "contentDate",
    "sensitivity", "language", "displayFrom", "displayTo",
    "lastReceivedDate", "isFlatFile", "provenance", "noMatch",
}
blocks = re.findall(r"const mockArtefact = \{(.*?)\n\s*\};", source, re.S)

print(f"mockArtefact literals: {len(blocks)}")
for index, block in enumerate(blocks, 1):
    keys = set(re.findall(r"^\s*([A-Za-z_][A-Za-z0-9_]*)\s*:", block, re.M))
    print(f"fixture {index} missing Artefact keys: {sorted(required - keys)}")

print(f"remaining 'as any' casts: {len(re.findall(r'\\bas\\s+any\\b', source))}")
PY

Repository: hmcts/cath-service

Length of output: 419


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

path = Path("apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.test.ts")
source = path.read_text()

required = {
    "artefactId", "type", "locationId", "listTypeId", "contentDate",
    "sensitivity", "language", "displayFrom", "displayTo",
    "lastReceivedDate", "isFlatFile", "provenance", "noMatch",
}
blocks = re.findall(r"const mockArtefact = \{(.*?)\n\s*\};", source, re.S)
any_casts = len(re.findall(r"\bas\s+any\b", source))

print(f"mockArtefact literals: {len(blocks)}")
for index, block in enumerate(blocks, 1):
    keys = set(re.findall(r"^\s*([A-Za-z_][A-Za-z0-9_]*)\s*:", block, re.M))
    print(f"fixture {index} missing Artefact keys: {sorted(required - keys)}")

print(f"remaining 'as any' casts: {any_casts}")
PY

Repository: hmcts/cath-service

Length of output: 1165


Replace the any casts with typed fixtures.

Define an Artefact fixture builder with defaults for required fields. Type valid hearing and rendered-data fixtures with ChdKbHearingList and RenderedData. Keep intentionally invalid JSON untyped. This removes all 13 as any casts and preserves contract checking.

Source: Coding guidelines

Comment on lines +303 to +304
req.query = { artefactId: "test-artefact-123" };
res.locals = { locale: "cy" };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C3 --glob '*.test.ts' '\?lng=cy|[?&]lng=cy' apps/web/src/pages

Repository: hmcts/cath-service

Length of output: 50374


🏁 Script executed:

set -euo pipefail

FILE='apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.test.ts'
printf '%s\n' '--- target test ---'
cat -n "$FILE" | sed -n '1,460p'

printf '%s\n' '--- related page files ---'
fd -t f . 'apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list' | sort

printf '%s\n' '--- locale and query handling in the target area ---'
rg -n -C4 'locale|lng|query|render|res\.locals|Request|Response' \
  'apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list'

Repository: hmcts/cath-service

Length of output: 50374


🏁 Script executed:

set -euo pipefail

TARGET='apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.ts'

printf '%s\n' '--- target controller ---'
cat -n "$TARGET"

printf '%s\n' '--- locale middleware definitions and registration ---'
rg -n -C5 --glob '*.ts' --glob '*.tsx' \
  'res\.locals\.locale|locals\.locale|query\.lng|req\.query\.lng|i18n|localeMiddleware|language' \
  apps/web/src apps/web/libs libs 2>/dev/null | head -n 400

printf '%s\n' '--- route registration for the target controller ---'
rg -n -C8 'chancery-appeals-chd-daily-cause-list|from "\./.*index\.js"|GET' apps/web/src | head -n 300

Repository: hmcts/cath-service

Length of output: 34594


🏁 Script executed:

set -euo pipefail

printf '%s\n' '--- list-type handler locations ---'
fd -t f 'list-type-handler' apps/web/src

printf '%s\n' '--- list-type handler implementation ---'
HANDLER=$(fd -t f 'list-type-handler' apps/web/src | head -n 1)
test -n "$HANDLER"
cat -n "$HANDLER"

printf '%s\n' '--- app middleware and route mounting ---'
rg -n -C6 --glob '*.ts' \
  'res\.locals\.locale|req\.query\.lng|query\.lng|locale\s*=|createSimpleListTypeHandler|list-types' \
  apps/web/src | head -n 500

Repository: hmcts/cath-service

Length of output: 50374


🏁 Script executed:

set -euo pipefail

HANDLER='apps/web/src/pages/(list-types)/list-type-handler.ts'

printf '%s\n' '--- list-type handler implementation ---'
cat -n "$HANDLER"

printf '%s\n' '--- likely locale middleware files ---'
fd -t f -i 'locale|i18n|language|middleware' apps/web/src | sort

printf '%s\n' '--- locale middleware references (focused) ---'
rg -n -C8 --glob '*.ts' \
  'res\.locals\.locale|req\.query\.lng|query\.lng|setLocale|localeMiddleware' \
  apps/web/src | head -n 300

Repository: hmcts/cath-service

Length of output: 38409


🏁 Script executed:

set -euo pipefail

python3 - <<'PY'
from pathlib import Path

handler = Path("apps/web/src/pages/(list-types)/list-type-handler.ts").read_text()
test = Path("apps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.test.ts").read_text()

locale_line = 'const locale = res.locals.locale || "en";'
query_line = 'req.query.lng'

print("handler_reads_res_locals_locale:", locale_line in handler)
print("handler_reads_query_lng:", query_line in handler)
print("welsh_test_sets_query_lng:", 'lng: "cy"' in test)
print("welsh_test_sets_res_locals_cy:", 'res.locals = { locale: "cy" }' in test)

if locale_line not in handler or query_line in handler:
    raise SystemExit("Unexpected locale resolution in target handler")
if 'lng: "cy"' in test or 'res.locals = { locale: "cy" }' not in test:
    raise SystemExit("Unexpected Welsh test setup")
PY

Repository: hmcts/cath-service

Length of output: 294


🏁 Script executed:

set -euo pipefail

printf '%s\n' '--- all locale assignments in tracked source ---'
rg -n -C4 --glob '*.ts' --glob '*.tsx' \
  'locals\.locale\s*=|locale\s*=\s*.*query|query\.lng|req\.query\.lng|lng.*locals' . \
  | head -n 500

printf '%s\n' '--- app construction and test entry points ---'
cat -n apps/web/src/app.ts | sed -n '1,260p'
printf '%s\n' '--- web test scripts ---'
rg -n -C3 '"test"|vitest|supertest|app\(' apps/web/package.json package.json

Repository: hmcts/cath-service

Length of output: 50374


Cover Welsh rendering through the locale middleware.

Keep this controller unit test for res.locals.locale, but add a route-level test that requests ?lng=cy and asserts Welsh output. Setting res.locals.locale directly does not cover the middleware mapping.

Source: Coding guidelines

Comment on lines +19 to +26
guardArtefact: (artefact, res) => {
if (artefact.listTypeName !== SUPPORTED_LIST_TYPE) {
res.status(400).render("errors/common", {
en,
cy,
errorTitle: "Invalid List Type",
errorMessage: "This list type is not supported by this module"
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Localise the guarded list-type error.

When a Welsh request uses an unsupported list type, Lines 24-25 always render English text. Add these strings to both locale files and select them from res.locals.locale.

As per coding guidelines, "Every page must provide English and Welsh content and select the current locale through the i18n middleware."

Source: Coding guidelines

Comment on lines +26 to +29
"@hmcts/chd-kb-common": "workspace:*",
"@hmcts/list-types-common": "workspace:*",
"@hmcts/pdf-generation": "workspace:*",
"@hmcts/postgres-prisma": "workspace:*",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C2 -P '"(`@hmcts/chd-kb-common`|`@hmcts/list-types-common`|`@hmcts/pdf-generation`|`@hmcts/postgres-prisma`|express)"\s*:' \
  --glob 'package.json' .

Repository: hmcts/cath-service

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json
from pathlib import Path

target = Path("libs/list-types/chancery-appeals-chd-daily-cause-list/package.json")
data = json.loads(target.read_text())

print("TARGET")
for section in ("dependencies", "peerDependencies", "devDependencies"):
    for name, spec in data.get(section, {}).items():
        if name in {
            "`@hmcts/chd-kb-common`",
            "`@hmcts/list-types-common`",
            "`@hmcts/pdf-generation`",
            "`@hmcts/postgres-prisma`",
            "express",
        }:
            print(f"{section}: {name} = {spec}")

print("\nWORKSPACE MANIFESTS")
wanted = {
    "`@hmcts/chd-kb-common`",
    "`@hmcts/list-types-common`",
    "`@hmcts/pdf-generation`",
    "`@hmcts/postgres-prisma`",
    "express",
}
for path in sorted(Path(".").rglob("package.json")):
    try:
        manifest = json.loads(path.read_text())
    except (OSError, json.JSONDecodeError):
        continue
    name = manifest.get("name")
    if name in wanted:
        print(f"{path}: {name} = {manifest.get('version')}")
PY

Repository: hmcts/cath-service

Length of output: 695


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' 'ROOT CONFIGURATION'
for file in package.json pnpm-lock.yaml yarn.lock package-lock.json; do
  if [ -f "$file" ]; then
    echo "--- $file"
    if [ "$file" = "package.json" ]; then
      python3 - <<'PY'
import json
from pathlib import Path
p = Path("package.json")
d = json.loads(p.read_text())
for section in ("dependencies", "devDependencies", "peerDependencies", "overrides", "resolutions", "pnpm"):
    if section in d:
        print(f"{section}:")
        print(json.dumps(d[section], indent=2))
PY
    else
      rg -n -C2 '(^|[[:space:]"'\''])express(@|:|[[:space:]]|$)|express@' "$file" | head -80 || true
    fi
  fi
done

printf '%s\n' 'EXPRESS DECLARATIONS'
python3 - <<'PY'
import json
from pathlib import Path

for path in sorted(Path(".").rglob("package.json")):
    try:
        d = json.loads(path.read_text())
    except (OSError, json.JSONDecodeError):
        continue
    for section in ("dependencies", "devDependencies", "peerDependencies", "optionalDependencies"):
        spec = d.get(section, {}).get("express")
        if spec is not None:
            print(f"{path}: {section}.express = {spec}")
PY

Repository: hmcts/cath-service

Length of output: 8191


Pin the dependency specifications.

Use 1.0.0 for the four workspace dependencies and 5.2.1 for the Express peer dependency.

Source: Coding guidelines

Comment on lines +24 to +30
export async function generateChanceryAppealsChdDailyCauseListPdf(options: PdfGenerationOptions): Promise<PdfGenerationResult> {
try {
const renderedData = renderChanceryAppealsChdDailyCauseList(options.jsonData, {
locale: options.locale,
contentDate: options.contentDate,
lastReceivedDate: new Date().toISOString()
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the PDF generator and publication processor before inspecting timestamp flow.
ast-grep outline libs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-generator.ts --items all
ast-grep outline libs/publication/src/processing/service.ts --items all

# Inspect the generation option contract and all receipt-timestamp propagation sites.
rg -n -C 4 'BasePdfGenerationOptions|lastReceivedDate|contentDate|generateChanceryAppealsChdDailyCauseListPdf' \
  libs/list-types/common libs/list-types/chancery-appeals-chd-daily-cause-list libs/publication apps/web/src/pages

Repository: hmcts/cath-service

Length of output: 50375


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- PDF generator ---'
cat -n libs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-generator.ts

printf '%s\n' '--- Chancery option and renderer definitions ---'
rg -n -C 8 'PdfGenerationOptions|BasePdfGenerationOptions|renderChanceryAppealsChdDailyCauseList|lastReceivedDate' \
  libs/list-types/chancery-appeals-chd-daily-cause-list \
  libs/list-types/common \
  --glob '*.ts' --glob '*.tsx'

printf '%s\n' '--- PDF generation call sites ---'
rg -n -C 10 'generateChanceryAppealsChdDailyCauseListPdf|generatePdf|pdfGeneration' \
  libs apps --glob '*.ts' --glob '*.tsx' \
  | head -n 600

Repository: hmcts/cath-service

Length of output: 50375


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- Publication processing files ---'
fd -t f -e ts -e tsx . libs/publication apps | rg '/(processing|publication|pdf)/|service\.ts$' | head -n 200

printf '%s\n' '--- Artefact receipt and PDF option construction ---'
rg -n -C 12 'lastReceivedDate|generateChanceryAppealsChdDailyCauseListPdf' \
  libs/publication apps libs/list-types/chancery-appeals-chd-daily-cause-list \
  --glob '*.ts' --glob '*.tsx' --glob '!*.test.ts' --glob '!*.spec.ts' \
  | head -n 1000

printf '%s\n' '--- Relevant publication service source ---'
for file in $(fd -t f -e ts . libs/publication | rg 'service\.ts$|processor|processing'); do
  if rg -q 'lastReceivedDate|generate.*Pdf|PdfGenerationOptions' "$file"; then
    echo "--- $file"
    cat -n "$file"
  fi
done

Repository: hmcts/cath-service

Length of output: 50375


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
import re

generator = Path("libs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-generator.ts").read_text()
renderer = Path("libs/list-types/chancery-appeals-chd-daily-cause-list/src/rendering/renderer.ts").read_text()
artefact_model = Path("libs/publication/src/repository/model.ts").read_text()
processing = Path("libs/publication/src/processing/service.ts").read_text()
queries = Path("libs/publication/src/repository/queries.ts").read_text()

assert 'lastReceivedDate: new Date().toISOString()' in generator
assert 'lastReceivedDate: string;' in renderer
assert 'lastReceivedDate: Date;' in artefact_model
assert 'lastReceivedDate: true' in queries
assert 'CHANCERY_APPEALS_CHD_DAILY_CAUSE_LIST' in processing
assert 'generateChanceryAppealsChdDailyCauseListPdf({ ...p' in processing

print("PDF renderer receives generation time:", "lastReceivedDate: new Date().toISOString()" in generator)
print("Artefact model contains receipt timestamp:", "lastReceivedDate: Date;" in artefact_model)
print("Repository selects receipt timestamp:", "lastReceivedDate: true" in queries)
print("Publication processor routes Chancery PDF generation:", bool(re.search(
    r'CHANCERY_APPEALS_CHD_DAILY_CAUSE_LIST:.*generateChanceryAppealsChdDailyCauseListPdf',
    processing,
    re.S,
)))
print("Generator options declare receipt timestamp:", "lastReceivedDate" in generator.split("interface PdfGenerationOptions", 1)[1].split("}", 1)[0])
PY

Repository: hmcts/cath-service

Length of output: 401


Pass lastReceivedDate to PDF rendering

The artefact model and repository provide lastReceivedDate, but PDF generation uses new Date().toISOString(). Add this value to PdfGenerationOptions and pass it to renderChanceryAppealsChdDailyCauseList so retries do not change the rendered lastUpdated value.

@@ -0,0 +1,74 @@
<!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.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Set the PDF document language from the selected locale.

Welsh PDF content currently declares <html lang="en">. Assistive technology can therefore use English pronunciation for Welsh content.

  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-template.njk#L2-L2: replace the fixed language value with a template locale value.
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-generator.ts#L40-L47: pass options.locale to the template render context.
📍 Affects 2 files
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-template.njk#L2-L2 (this comment)
  • libs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-generator.ts#L40-L47

@sonarqubecloud

Copy link
Copy Markdown

@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

🎭 Playwright E2E Test Results

82 tests   52 ✅  6m 25s ⏱️
31 suites  30 💤
 1 files     0 ❌

Results for commit 5dd6238.

@hmctsclaudecode

Copy link
Copy Markdown

⚠️ This PR now conflicts with master

Merging master into this branch would conflict in 7 file(s):

  • 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
  • libs/list-types/common/src/list-type-data.ts
  • libs/notifications/src/notification/notification-service.ts
  • libs/publication/src/processing/service.ts
  • tsconfig.json

Nothing has been changed on your branch. Rebase with /auto-rebase locally, or git fetch origin && git rebase origin/master.

Re-checked automatically on every push to master.

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.

Chancery Appeals (ChD) daily cause list

2 participants