Feature-801- Add Chancery Appeals (ChD) daily cause list - #931
Feature-801- Add Chancery Appeals (ChD) daily cause list#931alao-daniel wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughChangesThe 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
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
Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (1)
yarn.lockis excluded by!**/yarn.lock,!**/*.lock
📒 Files selected for processing (31)
apps/web/package.jsonapps/web/src/app.tsapps/web/src/pages/(admin)/non-strategic-upload-summary/index.tsapps/web/src/pages/(admin)/non-strategic-upload/index.tsapps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/chancery-appeals-chd-daily-cause-list.njkapps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/chancery-appeals-chd-daily-cause-list.njk.test.tsapps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.test.tsapps/web/src/pages/(list-types)/chancery-appeals-chd-daily-cause-list/index.tsdocs/tickets/801/plan.mddocs/tickets/801/review.mddocs/tickets/801/tasks.mddocs/tickets/801/ticket.mdlibs/list-types/chancery-appeals-chd-daily-cause-list/package.jsonlibs/list-types/chancery-appeals-chd-daily-cause-list/src/config.tslibs/list-types/chancery-appeals-chd-daily-cause-list/src/conversion/chancery-appeals-chd-daily-cause-list-config.test.tslibs/list-types/chancery-appeals-chd-daily-cause-list/src/conversion/chancery-appeals-chd-daily-cause-list-config.tslibs/list-types/chancery-appeals-chd-daily-cause-list/src/index.tslibs/list-types/chancery-appeals-chd-daily-cause-list/src/locales/cy.tslibs/list-types/chancery-appeals-chd-daily-cause-list/src/locales/en.tslibs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-generator.test.tslibs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-generator.tslibs/list-types/chancery-appeals-chd-daily-cause-list/src/pdf/pdf-template.njklibs/list-types/chancery-appeals-chd-daily-cause-list/src/rendering/renderer.test.tslibs/list-types/chancery-appeals-chd-daily-cause-list/src/rendering/renderer.tslibs/list-types/chancery-appeals-chd-daily-cause-list/tsconfig.jsonlibs/list-types/common/src/list-type-data.tslibs/notifications/package.jsonlibs/notifications/src/notification/notification-service.tslibs/publication/package.jsonlibs/publication/src/processing/service.tstsconfig.json
| "@hmcts/auth": "workspace:*", | ||
| "@hmcts/azure-blob": "workspace:*", | ||
| "@hmcts/care-standards-tribunal-weekly-hearing-list": "workspace:*", | ||
| "@hmcts/chancery-appeals-chd-daily-cause-list": "workspace:*", |
There was a problem hiding this comment.
📐 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 -80Repository: 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-L25libs/publication/package.json#L27-L27
Source: Coding guidelines
| vi.mocked(getArtefactById).mockResolvedValue(mockArtefact as any); | ||
| vi.mocked(getPublicationJson).mockResolvedValue(mockJsonData); | ||
| mockValidate.mockReturnValue({ isValid: true, errors: [] }); | ||
| vi.mocked(renderChanceryAppealsChdDailyCauseList).mockReturnValue(mockRenderedData as any); |
There was a problem hiding this comment.
📐 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 -200Repository: 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 -160Repository: 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 -160Repository: 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))}")
PYRepository: 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}")
PYRepository: 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
| req.query = { artefactId: "test-artefact-123" }; | ||
| res.locals = { locale: "cy" }; |
There was a problem hiding this comment.
📐 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/pagesRepository: 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 300Repository: 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 500Repository: 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 300Repository: 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")
PYRepository: 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.jsonRepository: 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
| 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" | ||
| }); |
There was a problem hiding this comment.
🎯 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
| "@hmcts/chd-kb-common": "workspace:*", | ||
| "@hmcts/list-types-common": "workspace:*", | ||
| "@hmcts/pdf-generation": "workspace:*", | ||
| "@hmcts/postgres-prisma": "workspace:*", |
There was a problem hiding this comment.
📐 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')}")
PYRepository: 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}")
PYRepository: 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
| export async function generateChanceryAppealsChdDailyCauseListPdf(options: PdfGenerationOptions): Promise<PdfGenerationResult> { | ||
| try { | ||
| const renderedData = renderChanceryAppealsChdDailyCauseList(options.jsonData, { | ||
| locale: options.locale, | ||
| contentDate: options.contentDate, | ||
| lastReceivedDate: new Date().toISOString() | ||
| }); |
There was a problem hiding this comment.
🎯 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/pagesRepository: 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 600Repository: 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
doneRepository: 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])
PYRepository: 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"> | |||
There was a problem hiding this comment.
🎯 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: passoptions.localeto 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
|
Preview Deployment Successful 🚀Your preview environment is ready:
The environment will be automatically cleaned up when this PR is closed. |
🎭 Playwright E2E Test Results82 tests 52 ✅ 6m 25s ⏱️ Results for commit 5dd6238. |
|



Jira link
#801
Change description
implement chancery appeals daily cause list style guide + PDF
closes #801
Checklist
Summary by CodeRabbit