Skip to content

Feature/434 Add CIC, SEND and AST tribunal hearing lists - #772

Merged
junaidiqbalmoj merged 11 commits into
masterfrom
feature/434-add-tribunal-hearing-lists
Jul 3, 2026
Merged

Feature/434 Add CIC, SEND and AST tribunal hearing lists#772
junaidiqbalmoj merged 11 commits into
masterfrom
feature/434-add-tribunal-hearing-lists

Conversation

@KianKwa

@KianKwa KianKwa commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Jira link

#434

Change description

Add CIC, SEND and AST tribunal hearing lists

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 new hearing list pages for SEND (daily), CIC (weekly), and AST (daily) with Welsh/English support, search, tables, and “Important information” sections.
    • Enabled PDF generation and email summaries for these new list types.
    • Extended admin upload/import to support the new hearing list formats.
  • Bug Fixes
    • Improved uploaded-list display names with better Welsh locale fallbacks and “week commencing” display for weekly lists.
    • Updated date formatting to use zero-padded day values for consistent presentation.
  • Tests
    • Added coverage for the new pages, rendering, and PDF generation paths.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Three new hearing list types are added end-to-end: SEND daily, CIC weekly, and AST daily. The change set adds their packages, schemas, renderers, PDF/email support, web pages, shared registries, and the related location, dependency, and documentation wiring.

Changes

SEND, CIC, and AST Hearing List Rollout

Layer / File(s) Summary
Master data, workspace config, and docs
libs/location/src/..., libs/location/src/list-type-data.ts, tsconfig.json, apps/web/package.json, libs/notifications/package.json, libs/publication/package.json, libs/list-types/common/package.json, docs/tickets/434/*
Location data, list-type data, TS path aliases, workspace dependencies, and ticket/task documentation are extended for the three new hearing list types.
Shared PDF utility and date formatting
libs/list-types/common/src/pdf/pdf-utilities.ts, libs/list-types/common/src/index.ts, libs/list-types/common/src/rendering/date-formatting.ts, libs/list-types/common/src/rendering/date-formatting.test.ts
Common PDF generation now takes contentDate, renders list templates through Nunjucks, and persists generated PDFs; date formatting changes switch long-form dates to zero-padded days and update tests accordingly.
SEND daily hearing list package
libs/list-types/send-daily-hearing-list/**
The SEND package adds its config, schema, model, converter, locales, renderer, email summary builder, PDF generator, template, entrypoint, and tests.
CIC weekly hearing list package
libs/list-types/cic-weekly-hearing-list/**
The CIC package adds its config, schema, model, converter, locales, renderer, email summary builder, PDF generator, template, entrypoint, and tests.
AST daily hearing list package
libs/list-types/ast-daily-hearing-list/**
The AST package adds its config, schema, model, converter, locales, renderer, email summary builder, PDF generator, template, entrypoint, and tests.
Admin upload and publication display
apps/web/src/pages/(admin)/non-strategic-upload/index.ts, apps/web/src/pages/(admin)/manual-upload-summary/index.ts, apps/web/src/pages/(admin)/non-strategic-upload-summary/index.ts, apps/web/src/pages/(public)/summary-of-publications/index.ts
Non-strategic upload registers the new converters, and upload-summary/publication display logic changes how list type names and weekly display names are derived.
PDF and notification registry wiring
libs/publication/src/processing/service.ts, libs/notifications/src/notification/notification-service.ts
Publication PDF generation and notification email registries are extended to support the SEND, CIC, and AST list types.
SEND web route and template
apps/web/src/pages/(list-types)/send-daily-hearing-list/index.ts, send-daily-hearing-list.njk, index.test.ts
The SEND page controller fetches and validates publication JSON, renders the SEND template, and its tests cover success, error paths, and Welsh locale handling.
CIC web route and template
apps/web/src/pages/(list-types)/cic-weekly-hearing-list/index.ts, cic-weekly-hearing-list.njk, index.test.ts
The CIC page controller fetches and validates publication JSON, renders the CIC template, and its tests cover success, error paths, and Welsh locale handling.
AST web route and template
apps/web/src/pages/(list-types)/ast-daily-hearing-list/index.ts, ast-daily-hearing-list.njk, index.test.ts
The AST page controller fetches and validates publication JSON, renders the AST template, and its tests cover success, error paths, and Welsh locale handling.

Possibly related issues

Possibly related PRs

  • hmcts/cath-service#325: Both PRs extend EMAIL_BUILDER_REGISTRY in libs/notifications/src/notification/notification-service.ts with additional hearing list types.
  • hmcts/cath-service#320: Both PRs add PDF generation and notification plumbing for new list types via the same publication processing and notifications integration points.
  • hmcts/cath-service#181: Both PRs change how list-type display names are derived from list type metadata.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 17.65% 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 accurately summarises the main change: adding CIC, SEND and AST tribunal hearing lists.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/434-add-tribunal-hearing-lists

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

❤️ Share

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

@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

🎭 Playwright E2E Test Results

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

Results for commit 4dc55b5.

♻️ This comment has been updated with latest results.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 12

Note

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

Caution

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

⚠️ Outside diff range comments (1)
.claude/worktrees/vibe-438 (1)

1-155: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Remove this checked-in worktree artefact.

This file is unrelated to the hearing-list change and appears to be a local .claude/worktrees snapshot containing an infra diff, so it should not ship in this PR.

🟡 Minor comments (10)
docs/tickets/434/tasks.md-106-106 (1)

106-106: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Fix CIC template field access guidance.

Line 106 currently instructs hearing.venuePlatform, which conflicts with the defined data key "venue/platform" and can lead to broken rendering if followed literally. Please update the checklist text to bracket notation guidance.

apps/web/src/pages/(public)/summary-of-publications/index.ts-61-62 (1)

61-62: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Rename constant to SCREAMING_SNAKE_CASE.

Line 61 declares a constant as weeklyListTypes; please rename it (for example, WEEKLY_LIST_TYPES) to match the project’s constant naming rule.

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

Source: Coding guidelines

libs/list-types/send-daily-hearing-list/src/rendering/renderer.test.ts-20-21 (1)

20-21: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Avoid timezone-flaky date construction in tests.

Using new Date("2025-06-20") can shift calendar day by runtime timezone. Build the date with numeric components (for example new Date(2025, 5, 20)) so expected outputs stay stable.

Also applies to: 44-45, 59-60, 73-74

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

23-25: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Normalise locale to supported values before rendering.

Line 23 can pass arbitrary locale into renderSendDailyHearingListData, while t falls back to EN unless locale is exactly cy. That can yield mixed-language output. Clamp locale to "en" | "cy" first.

Also applies to: 77-79

apps/web/src/pages/(list-types)/cic-weekly-hearing-list/index.test.ts-108-109 (1)

108-109: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Replace as any artefact casts with a concrete typed fixture.

The as any casts here bypass type safety and can hide controller contract changes in tests.

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

Also applies to: 177-177, 197-197, 239-239

Source: Coding guidelines

libs/list-types/cic-weekly-hearing-list/src/schemas/cic-weekly-hearing-list.json-19-19 (1)

19-19: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Tighten hearingTime schema to match runtime validation.

Line 19 allows values such as 00am and 19pm, while the converter validation only allows 1–12 hours. Aligning both avoids inconsistent acceptance paths.

Suggested fix
-        "pattern": "^\\d{1,2}([:.]\\d{2})?[ap]m\\s*$",
+        "pattern": "^(0?[1-9]|1[0-2])([:.][0-5][0-9])?[ap]m\\s*$",
libs/list-types/cic-weekly-hearing-list/src/email-summary/summary-builder.ts-6-12 (1)

6-12: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Format the hearing date before adding it to the email summary.

renderCicWeeklyHearingListData formats hearing.date for display, which implies this field is still in source format here. Returning it verbatim will leak the raw date value into emails; the current test only passes because it feeds an already formatted string. Use the same display-date formatting here, or pass a preformatted date into this builder.

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

2-2: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Welsh PDFs still contain hard-coded English.

lang="en" and No hearings scheduled. bypass the locale data, so a Welsh render still announces English metadata and fallback text.

Also applies to: 58-60

apps/web/src/pages/(list-types)/cic-weekly-hearing-list/cic-weekly-hearing-list.njk-53-82 (1)

53-82: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Handle the empty-list case in the page template.

renderCicWeeklyHearingListData accepts an empty array, but this template always renders an empty table shell. That leaves users with a blank results area instead of a clear “no hearings” message.

libs/list-types/ast-daily-hearing-list/src/pdf/pdf-template.njk-55-56 (1)

55-56: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Translate the empty-state text.

No hearings scheduled. bypasses the locale bundle, so Welsh PDFs fall back to English whenever the list is empty. Render this through t like the rest of the template.

Proposed change
-    <p>No hearings scheduled.</p>
+    <p>{{ t.noHearingsScheduled }}</p>
🧹 Nitpick comments (7)
libs/list-types/send-daily-hearing-list/src/config.ts (1)

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

Align exported constants with SCREAMING_SNAKE_CASE.

Please rename moduleRoot, assets, and schemaPath to SCREAMING_SNAKE_CASE for guideline compliance.

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

Source: Coding guidelines

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

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

Replace as any casts with typed test fixtures.

Use a concrete artefact test type (or satisfies) so these mocks fail fast when the contract changes.

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

Also applies to: 166-166, 186-186, 223-223

Source: Coding guidelines

libs/list-types/send-daily-hearing-list/src/rendering/renderer.ts (1)

4-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Reorder exports to match the TypeScript module ordering rule.

RenderOptions and RenderedData are declared before the exported function; per the project rule, exported functions should come before interfaces/types, with interfaces/types at the bottom.

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

Also applies to: 21-34

Source: Coding guidelines

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

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

Move type exports to the bottom to match module export ordering.

Line 3 places a type export before value exports; reorder so types are last in the module.

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

Source: Coding guidelines

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

4-30: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Move the exported interfaces below the renderer.

This module puts exported types ahead of the exported function, which breaks the repo ordering rule for .ts files.

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

Source: Coding guidelines

libs/list-types/ast-daily-hearing-list/src/config.ts (1)

4-9: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use SCREAMING_SNAKE_CASE for constants.

Line 4–9 constant declarations are in lower/camel case; please align them with the project constant naming rule for TS files.

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

Source: Coding guidelines

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

5-233: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Align constant names with SCREAMING_SNAKE_CASE.

Line 5 onwards contains many const declarations in camelCase (for example test fixtures/mocks); please rename these constants to match the repository naming standard.

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

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5c4c9bb5-01af-4725-bc20-190ded3902d3

📥 Commits

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

⛔ Files ignored due to path filters (2)
  • requirements/requirements.db is excluded by !**/*.db
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (73)
  • .claude/worktrees/vibe-438
  • apps/web/package.json
  • apps/web/src/pages/(admin)/manual-upload-summary/index.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)/ast-daily-hearing-list/ast-daily-hearing-list.njk
  • apps/web/src/pages/(list-types)/ast-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/ast-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/cic-weekly-hearing-list/cic-weekly-hearing-list.njk
  • apps/web/src/pages/(list-types)/cic-weekly-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/cic-weekly-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/send-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/send-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/send-daily-hearing-list/send-daily-hearing-list.njk
  • apps/web/src/pages/(public)/summary-of-publications/index.ts
  • docs/tickets/434/plan.md
  • docs/tickets/434/tasks.md
  • docs/tickets/434/ticket.md
  • libs/list-types/ast-daily-hearing-list/package.json
  • libs/list-types/ast-daily-hearing-list/src/config.test.ts
  • libs/list-types/ast-daily-hearing-list/src/config.ts
  • libs/list-types/ast-daily-hearing-list/src/conversion/ast-config.ts
  • libs/list-types/ast-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/ast-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/ast-daily-hearing-list/src/index.ts
  • libs/list-types/ast-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/ast-daily-hearing-list/src/locales/en.ts
  • libs/list-types/ast-daily-hearing-list/src/models/types.ts
  • libs/list-types/ast-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/ast-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/ast-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/ast-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/ast-daily-hearing-list/src/schemas/ast-daily-hearing-list.json
  • libs/list-types/ast-daily-hearing-list/tsconfig.json
  • libs/list-types/cic-weekly-hearing-list/package.json
  • libs/list-types/cic-weekly-hearing-list/src/config.test.ts
  • libs/list-types/cic-weekly-hearing-list/src/config.ts
  • libs/list-types/cic-weekly-hearing-list/src/conversion/cic-config.ts
  • libs/list-types/cic-weekly-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/cic-weekly-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/cic-weekly-hearing-list/src/index.ts
  • libs/list-types/cic-weekly-hearing-list/src/locales/cy.ts
  • libs/list-types/cic-weekly-hearing-list/src/locales/en.ts
  • libs/list-types/cic-weekly-hearing-list/src/models/types.ts
  • libs/list-types/cic-weekly-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/cic-weekly-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/cic-weekly-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/cic-weekly-hearing-list/src/rendering/renderer.ts
  • libs/list-types/cic-weekly-hearing-list/src/schemas/cic-weekly-hearing-list.json
  • libs/list-types/cic-weekly-hearing-list/tsconfig.json
  • libs/list-types/send-daily-hearing-list/package.json
  • libs/list-types/send-daily-hearing-list/src/config.test.ts
  • libs/list-types/send-daily-hearing-list/src/config.ts
  • libs/list-types/send-daily-hearing-list/src/conversion/send-config.ts
  • libs/list-types/send-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/send-daily-hearing-list/src/email-summary/summary-builder.ts
  • libs/list-types/send-daily-hearing-list/src/index.ts
  • libs/list-types/send-daily-hearing-list/src/locales/cy.ts
  • libs/list-types/send-daily-hearing-list/src/locales/en.ts
  • libs/list-types/send-daily-hearing-list/src/models/types.ts
  • libs/list-types/send-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/send-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/send-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/send-daily-hearing-list/src/rendering/renderer.ts
  • libs/list-types/send-daily-hearing-list/src/schemas/send-daily-hearing-list.json
  • libs/list-types/send-daily-hearing-list/tsconfig.json
  • libs/location/src/list-type-data.ts
  • libs/location/src/location-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/src/pages/(list-types)/ast-daily-hearing-list/index.ts Outdated
Comment on lines +29 to +34
return res.status(400).render("errors/common", {
en,
cy,
errorTitle: "Bad Request",
errorMessage: "Missing artefactId parameter"
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Localise the error branches as well.

These responses send English errorTitle and errorMessage strings directly, so ?lng=cy still returns English on every failure path. Feed these from language-specific content the same way the success path uses t. As per coding guidelines, "Provide both en and cy content objects in page controllers and render both language versions in templates" and "Implement Welsh language support on all user-facing text with separate en.ts and cy.ts content files".

Also applies to: 41-46, 69-74, 97-101

Source: Coding guidelines

Comment thread apps/web/src/pages/(list-types)/ast-daily-hearing-list/index.ts Outdated
Comment thread apps/web/src/pages/(list-types)/cic-weekly-hearing-list/index.ts Outdated
Comment on lines +28 to +34
if (!artefactId) {
return res.status(400).render("errors/common", {
en,
cy,
errorTitle: "Bad Request",
errorMessage: "Missing artefactId parameter"
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Localise the error copy as well.

These failure paths always render English errorTitle/errorMessage, so Welsh requests lose language support exactly when something goes wrong.

As per coding guidelines, apps/web/src/pages/**/index.ts: Provide both en and cy content objects in page controllers and render both language versions in templates and Implement Welsh language support on all user-facing text with separate en.ts and cy.ts content files.

Also applies to: 41-46, 69-74, 97-102

Source: Coding guidelines

importantInformationParagraphs: [
"Mae cyfiawnder agored yn egwyddor sylaenol ein system gyfiawnder.",
"Wrth ystyried defnyddio technoleg ffôn a fideo, bydd y farnwriaeth yn rhoi sylw i egwyddorion cyfiawnder agored. Gall barnwyr benderfynu cynnal gwrandawiad yn breifat os oes angen hynny er mwyn sicrhau'r broses o weinyddu cyfiawnder yn briodol.",
"Bydd partïon a chynrychiolwyr y Tribiwnlys Digolledu am Anafiadau Troseddol yn cael gwybod yn uniongyrchol am y trefniadau ar gyfer gwrando achosion o bell. Dylai unrhyw un arall sydd â diddordeb mewn ymuno â'r gwrandawiad o bell gysylltu â Swyddfa'r Tribiwnlys Digolledu am Anafiadau Troseddol yn uniongyrchol, cyn dyddiad y gwrandawiad, trwy e-bostio (insert relevant office mailbox email address) fel y gellir gwneud trefniadau. Dylai'r manylion canlynol gael eu cynnwys yn llinell pwnc yr e-bost [OBSERVER/MEDIA] REQUEST – [AN Other v CICA] – [hearing date]. Os yw'r achos yn cael ei wrando yn breifat neu os yw'n destun cyfyngiad adrodd, bydd hyn yn cael ei nodi."

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Replace the mailbox placeholder in the Welsh copy.

Line 15 still contains (insert relevant office mailbox email address), so Welsh users will see a placeholder instead of the actual CIC contact route that the English copy already provides. That breaks the remote-observer instructions on the Welsh page.

Suggested fix
-    "Bydd partïon a chynrychiolwyr y Tribiwnlys Digolledu am Anafiadau Troseddol yn cael gwybod yn uniongyrchol am y trefniadau ar gyfer gwrando achosion o bell. Dylai unrhyw un arall sydd â diddordeb mewn ymuno â'r gwrandawiad o bell gysylltu â Swyddfa'r Tribiwnlys Digolledu am Anafiadau Troseddol yn uniongyrchol, cyn dyddiad y gwrandawiad, trwy e-bostio (insert relevant office mailbox email address) fel y gellir gwneud trefniadau. Dylai'r manylion canlynol gael eu cynnwys yn llinell pwnc yr e-bost [OBSERVER/MEDIA] REQUEST – [AN Other v CICA] – [hearing date]. Os yw'r achos yn cael ei wrando yn breifat neu os yw'n destun cyfyngiad adrodd, bydd hyn yn cael ei nodi."
+    "Bydd partïon a chynrychiolwyr y Tribiwnlys Digolledu am Anafiadau Troseddol yn cael gwybod yn uniongyrchol am y trefniadau ar gyfer gwrando achosion o bell. Dylai unrhyw un arall sydd â diddordeb mewn ymuno â'r gwrandawiad o bell gysylltu â Swyddfa'r Tribiwnlys Digolledu am Anafiadau Troseddol yn uniongyrchol, cyn dyddiad y gwrandawiad, trwy e-bostio CIC.enquiries@Justice.gov.uk fel y gellir gwneud trefniadau. Dylai'r manylion canlynol gael eu cynnwys yn llinell pwnc yr e-bost [OBSERVER/MEDIA] REQUEST – [AN Other v CICA] – [hearing date]. Os yw'r achos yn cael ei wrando yn breifat neu os yw'n destun cyfyngiad adrodd, bydd hyn yn cael ei nodi."
📝 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
"Bydd partïon a chynrychiolwyr y Tribiwnlys Digolledu am Anafiadau Troseddol yn cael gwybod yn uniongyrchol am y trefniadau ar gyfer gwrando achosion o bell. Dylai unrhyw un arall sydd â diddordeb mewn ymuno â'r gwrandawiad o bell gysylltu â Swyddfa'r Tribiwnlys Digolledu am Anafiadau Troseddol yn uniongyrchol, cyn dyddiad y gwrandawiad, trwy e-bostio (insert relevant office mailbox email address) fel y gellir gwneud trefniadau. Dylai'r manylion canlynol gael eu cynnwys yn llinell pwnc yr e-bost [OBSERVER/MEDIA] REQUEST – [AN Other v CICA] – [hearing date]. Os yw'r achos yn cael ei wrando yn breifat neu os yw'n destun cyfyngiad adrodd, bydd hyn yn cael ei nodi."
"Bydd partïon a chynrychiolwyr y Tribiwnlys Digolledu am Anafiadau Troseddol yn cael gwybod yn uniongyrchol am y trefniadau ar gyfer gwrando achosion o bell. Dylai unrhyw un arall sydd â diddordeb mewn ymuno â'r gwrandawiad o bell gysylltu â Swyddfa'r Tribiwnlys Digolledu am Anafiadau Troseddol yn uniongyrchol, cyn dyddiad y gwrandawiad, trwy e-bostio CIC.enquiries@Justice.gov.uk fel y gellir gwneud trefniadau. Dylai'r manylion canlynol gael eu cynnwys yn llinell pwnc yr e-bost [OBSERVER/MEDIA] REQUEST – [AN Other v CICA] – [hearing date]. Os yw'r achos yn cael ei wrando yn breifat neu os yw'n destun cyfyngiad adrodd, bydd hyn yn cael ei nodi."

Comment thread libs/list-types/cic-weekly-hearing-list/src/pdf/pdf-generator.ts Outdated
</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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Localise the empty-state text.

The hard-coded No hearings scheduled. bypasses t translations, so Welsh output stays in English for this state. Use a locale key from t here as well.

Comment on lines +8 to +40
"required": ["time", "caseReferenceNumber", "respondent", "hearingType", "venue", "timeEstimate"],
"properties": {
"time": {
"title": "Time of hearing",
"type": "string",
"pattern": "^\\d{1,2}([:.]\\d{2})?[ap]m\\s*$",
"examples": ["10am", "2:30pm"]
},
"caseReferenceNumber": {
"title": "Case reference number",
"type": "string",
"pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"
},
"respondent": {
"title": "Respondent",
"type": "string",
"pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"
},
"hearingType": {
"title": "Type of hearing",
"type": "string",
"pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"
},
"venue": {
"title": "Venue",
"type": "string",
"pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"
},
"timeEstimate": {
"title": "Time estimate",
"type": "string",
"pattern": "^(?!(.|\\r|\\n)*<[^>]+>)(.|\\r|\\n)*$"
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Required fields can still be empty strings.

required only enforces key presence. Add minLength: 1 (and ideally trim-aware validation) to required string fields to prevent blank records passing validation.

Comment on lines +13 to +14
"pattern": "^\\d{1,2}([:.]\\d{2})?[ap]m\\s*$",
"examples": ["10am", "2:30pm"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Tighten time validation to reject invalid hours/minutes.

Current regex accepts invalid values (for example 19pm). Please constrain hour/minute ranges in the schema pattern.

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

…orage

Merge master (fa9b633) bringing in:
- Azure Blob Storage for all publication uploads/retrieval (#765)
- Container-aware blob routing (#773)

Conflict resolutions:
- pdf-utilities.ts: use blob imports from master (filesystem approach removed)
- notifications/package.json: keep both @hmcts/ast-daily-hearing-list and @hmcts/azure-blob
- notification-service.ts: keep both AST import and azure-blob import

Refactor AST, CIC, SEND page controllers to match existing list type pattern:
- Replace filesystem readFile + manual handler with createSimpleListTypeHandler
- Use getPublicationJson (blob) instead of reading from temp upload directory
- Use resolveDataSource for provenance label resolution
- Update tests to mock getPublicationJson instead of readFile

🤖 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 (4)
apps/web/src/pages/(admin)/manual-upload-summary/index.ts (1)

18-20: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Restore the English fallback for Welsh list names.

Line 19 now falls back from welshFriendlyName straight to name, so partially translated list types will show the internal name instead of the friendly label. Other flows still use welshFriendlyNamefriendlyNamename, so this regresses the summary text.

Suggested fix
-  const listTypeName = listType
-    ? (locale === "cy" ? listType.welshFriendlyName : listType.shortenedFriendlyName || listType.friendlyName) || listType.name || uploadData.listType
-    : uploadData.listType;
+  const listTypeName = listType
+    ? (
+        locale === "cy"
+          ? listType.welshFriendlyName || listType.friendlyName
+          : listType.shortenedFriendlyName || listType.friendlyName
+      ) || listType.name || uploadData.listType
+    : uploadData.listType;
libs/location/src/seed-data.ts (1)

157-163: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Backfill the new locations outside the empty-DB seed path.

This write only runs during the initial seed. Existing databases return early at Line 40 and only call seedListTypes(), so the new SEND/CIC/AST virtual locations in this PR will never be inserted unless the environment starts from an empty DB. Please make location seeding idempotent as well, or add a dedicated backfill for the new location and locationReference rows.

libs/list-types/send-daily-hearing-list/src/pdf/pdf-generator.ts (1)

19-23: 🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Use the artefact timestamp here, not new Date().

Line 22 makes the PDF header depend on render time rather than the publication’s actual lastReceivedDate. The web controller already passes artefact.lastReceivedDate into the same renderer, so the same list can show different “last updated” values between HTML and PDF, and regenerated PDFs will drift over time. Please thread the artefact timestamp through the shared PDF options/registry and use that here instead.

libs/list-types/ast-daily-hearing-list/src/pdf/pdf-generator.ts (1)

19-24: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use the locale bundle for the PDF title.

renderAstDailyHearingListData is given an English listTitle before loadTranslations() runs, so Welsh PDFs still render an English heading even though the rest of the template is locale-aware.

Possible fix
-    const renderedData = renderAstDailyHearingListData(options.jsonData, {
-      locale: options.locale,
-      contentDate: options.contentDate,
-      lastReceivedDate: new Date().toISOString(),
-      listTitle: "Asylum Support Tribunal Daily Hearing List"
-    });
-
     const translations = await loadTranslations(
       options.locale,
       () => import("../locales/en.js"),
       () => import("../locales/cy.js")
     );
+
+    const renderedData = renderAstDailyHearingListData(options.jsonData, {
+      locale: options.locale,
+      contentDate: options.contentDate,
+      lastReceivedDate: new Date().toISOString(),
+      listTitle:
+        typeof translations.pageTitle === "string"
+          ? translations.pageTitle
+          : "Asylum Support Tribunal Daily Hearing List"
+    });

Also applies to: 26-30

🧹 Nitpick comments (2)
libs/list-types/common/src/index.ts (1)

32-40: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Match the barrel export order to the repo convention.

This block still places type BasePdfGenerationOptions ahead of exported functions. Please move the type exports to the end of the block so the barrel follows the repository ordering rule.

Suggested reorder
 export {
-  type BasePdfGenerationOptions,
   buildPdfFromRenderedList,
   configureNunjucks,
   createPdfErrorResult,
   loadTranslations,
   MAX_PDF_SIZE_BYTES,
-  type PdfGenerationResult,
-  savePdfToStorage
+  savePdfToStorage,
+  type BasePdfGenerationOptions,
+  type PdfGenerationResult
 } from "./pdf/pdf-utilities.js";

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

Source: Coding guidelines

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

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

Avoid as any in these artefact fixtures.

These casts switch off the type checks that would otherwise catch contract drift in the controller tests. Please type the fixture once with the publication artefact shape, or use satisfies, and reuse it across the cases. As per coding guidelines, "Enable TypeScript strict mode and avoid any type without justification".

Also applies to: 165-165, 185-185, 222-222

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 71c9a63d-1562-42e7-a6e6-e1dbf46d82ad

📥 Commits

Reviewing files that changed from the base of the PR and between c8c0a80 and 46092af.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (30)
  • apps/web/package.json
  • apps/web/src/pages/(admin)/manual-upload-summary/index.ts
  • apps/web/src/pages/(admin)/non-strategic-upload-summary/index.ts
  • apps/web/src/pages/(list-types)/ast-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/ast-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/cic-weekly-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/cic-weekly-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/send-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/send-daily-hearing-list/index.ts
  • apps/web/src/pages/(public)/summary-of-publications/index.ts
  • libs/list-types/ast-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/ast-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/ast-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/ast-daily-hearing-list/src/pdf/pdf-template.njk
  • libs/list-types/cic-weekly-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/cic-weekly-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/cic-weekly-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/common/package.json
  • libs/list-types/common/src/index.ts
  • libs/list-types/common/src/pdf/pdf-utilities.ts
  • libs/list-types/send-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/send-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/send-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/location/src/location-data.ts
  • libs/location/src/repository/model.ts
  • libs/location/src/seed-data.ts
  • libs/notifications/package.json
  • libs/notifications/src/notification/notification-service.ts
  • libs/publication/package.json
  • tsconfig.json
✅ Files skipped from review due to trivial changes (2)
  • libs/location/src/repository/model.ts
  • libs/location/src/location-data.ts
🚧 Files skipped from review as they are similar to previous changes (8)
  • libs/list-types/send-daily-hearing-list/src/email-summary/summary-builder.test.ts
  • libs/list-types/ast-daily-hearing-list/src/pdf/pdf-template.njk
  • apps/web/src/pages/(admin)/non-strategic-upload-summary/index.ts
  • apps/web/package.json
  • tsconfig.json
  • libs/notifications/package.json
  • libs/publication/package.json
  • libs/notifications/src/notification/notification-service.ts

cy,
validate,
logPrefix: "send-daily-hearing-list",
serverError: { errorTitle: "Server Error", errorMessage: "An error occurred while loading the list" },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Localise the 500 error copy.

Line 18 hardcodes English-only text, so Welsh users will still see English on this path even though the controller already carries en/cy content. Please move this message into the locale content objects and select it per locale before passing serverError. As per coding guidelines, "Provide both en and cy content objects in page controllers and render both language versions in templates" and "Implement Welsh language support on all user-facing text with separate en.ts and cy.ts content files".

Source: Coding guidelines

Comment thread apps/web/src/pages/(public)/summary-of-publications/index.ts Outdated
KianKwa and others added 2 commits June 29, 2026 17:29
…solution

The import was dropped when resolving the merge conflict in pdf-utilities.ts —
master's conflict marker only showed azure-blob imports, so the pdf-generation
import (needed by our branch's buildPdfFromRenderedList function) was lost.

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

… types

- Format single-digit days as zero-padded (e.g. "01 July 2026") in
  formatDisplayDate, formatLastUpdatedDateTime, and formatDdMmYyyyDate
- Extract shared PDF generation logic into generateListPdf<T>() in
  list-types-common, eliminating ~90 lines of duplication across
  SEND, CIC, and AST pdf-generator files
- Update all affected renderer and generator tests to reflect new date
  format and new mock boundary (generateListPdf instead of
  buildPdfFromRenderedList/loadTranslations)

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (3)
libs/list-types/cic-weekly-hearing-list/src/pdf/pdf-generator.test.ts (1)

83-91: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add a Welsh-locale assertion once the title-translation bug is fixed.

This test only checks the static English listTitle. Once generateListPdf is fixed to use translations.pageTitle for locale: "cy", add a case asserting the Welsh title is forwarded/rendered — otherwise this regression path stays uncovered.

libs/list-types/common/src/pdf/pdf-utilities.ts (1)

66-79: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Interfaces placed mid-file, not at the bottom of exports.

RenderedListData and ListPdfOptions are declared between loadTranslations and generateListPdf/buildPdfFromRenderedList. As per coding guidelines, **/*.ts exports should be ordered with "interfaces and types at the bottom". Consider moving these two interfaces to the end of the file.

Source: Coding guidelines

libs/list-types/send-daily-hearing-list/src/pdf/pdf-generator.ts (1)

12-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract shared provenanceLabel resolution into @hmcts/list-types-common.

The options.provenance ? PROVENANCE_LABELS[...] || options.provenance : "" block is duplicated verbatim in ast-daily-hearing-list/src/pdf/pdf-generator.ts (and likely other list-type packages per the PR's file list). Since generateListPdf already lives in @hmcts/list-types-common, a small resolveProvenanceLabel(provenance) helper there would remove the copy-paste and centralise fallback behaviour.

♻️ Suggested helper
// libs/list-types/common/src/pdf/pdf-utilities.ts
export function resolveProvenanceLabel(provenance?: string): string {
  if (!provenance) return "";
  return PROVENANCE_LABELS[provenance as keyof typeof PROVENANCE_LABELS] || provenance;
}
-    provenanceLabel: options.provenance ? PROVENANCE_LABELS[options.provenance as keyof typeof PROVENANCE_LABELS] || options.provenance : "",
+    provenanceLabel: resolveProvenanceLabel(options.provenance),

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 90b243d7-9033-436a-86b1-dab37cae6085

📥 Commits

Reviewing files that changed from the base of the PR and between 46092af and 259c377.

📒 Files selected for processing (18)
  • apps/web/src/pages/(list-types)/ast-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/cic-weekly-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/send-daily-hearing-list/index.test.ts
  • apps/web/src/pages/(list-types)/send-daily-hearing-list/index.ts
  • libs/list-types/ast-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/ast-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/ast-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/care-standards-tribunal-weekly-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/cic-weekly-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/cic-weekly-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/cic-weekly-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/common/src/index.ts
  • libs/list-types/common/src/pdf/pdf-utilities.ts
  • libs/list-types/common/src/rendering/date-formatting.test.ts
  • libs/list-types/common/src/rendering/date-formatting.ts
  • libs/list-types/send-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/send-daily-hearing-list/src/pdf/pdf-generator.ts
  • libs/list-types/send-daily-hearing-list/src/rendering/renderer.test.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • libs/list-types/send-daily-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/cic-weekly-hearing-list/src/rendering/renderer.test.ts
  • libs/list-types/ast-daily-hearing-list/src/rendering/renderer.test.ts
  • apps/web/src/pages/(list-types)/ast-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/cic-weekly-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/send-daily-hearing-list/index.ts
  • apps/web/src/pages/(list-types)/send-daily-hearing-list/index.test.ts

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

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

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Preview Deployment Successful 🚀

Your preview environment is ready:

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

@sonarqubecloud

sonarqubecloud Bot commented Jul 1, 2026

Copy link
Copy Markdown

@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: 1e8b1c5b-5959-4fc1-9692-4f5db386e722

📥 Commits

Reviewing files that changed from the base of the PR and between 259c377 and 4dc55b5.

📒 Files selected for processing (9)
  • apps/web/src/pages/(admin)/manual-upload-summary/index.test.ts
  • apps/web/src/pages/(admin)/non-strategic-upload-summary/index.test.ts
  • apps/web/src/pages/(public)/summary-of-publications/index.test.ts
  • apps/web/src/pages/(public)/summary-of-publications/index.ts
  • libs/list-types/ast-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/cic-weekly-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/common/src/pdf/pdf-utilities.test.ts
  • libs/list-types/send-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/publication/src/processing/service.test.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • libs/list-types/send-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/ast-daily-hearing-list/src/pdf/pdf-generator.test.ts
  • libs/list-types/cic-weekly-hearing-list/src/pdf/pdf-generator.test.ts

Comment on lines +896 to +941
it("should call extractAndStoreArtefactSearch when a JSON file is uploaded", async () => {
const jsonContent = JSON.stringify({ data: "test" });
const jsonUploadData = {
...mockUploadData,
fileName: "test-hearing-list.json",
file: Buffer.from(jsonContent)
};

vi.mocked(getManualUpload).mockResolvedValue(jsonUploadData);
vi.mocked(saveUploadedFile).mockResolvedValue(".json");
vi.mocked(processPublication).mockResolvedValue({});
vi.mocked(createArtefact).mockResolvedValue({ artefactId: "test-artefact-id-123", isUpdate: false });
vi.mocked(extractAndStoreArtefactSearch).mockResolvedValue(undefined);

const session = { save: vi.fn((callback) => callback()) };
const req = { query: { uploadId: "test-upload-id" }, session } as unknown as Request;
const res = { redirect: vi.fn(), render: vi.fn() } as unknown as Response;

await callHandler(POST, req, res);

expect(extractAndStoreArtefactSearch).toHaveBeenCalledWith("test-artefact-id-123", 6, { data: "test" });
expect(res.redirect).toHaveBeenCalledWith("/manual-upload-success");
});

it("should continue upload when extractAndStoreArtefactSearch throws", async () => {
const jsonContent = JSON.stringify({ data: "test" });
const jsonUploadData = {
...mockUploadData,
fileName: "test-hearing-list.json",
file: Buffer.from(jsonContent)
};

vi.mocked(getManualUpload).mockResolvedValue(jsonUploadData);
vi.mocked(saveUploadedFile).mockResolvedValue(".json");
vi.mocked(processPublication).mockResolvedValue({});
vi.mocked(createArtefact).mockResolvedValue({ artefactId: "test-artefact-id-123", isUpdate: false });
vi.mocked(extractAndStoreArtefactSearch).mockRejectedValue(new Error("Search extraction failed"));

const session = { save: vi.fn((callback) => callback()) };
const req = { query: { uploadId: "test-upload-id" }, session } as unknown as Request;
const res = { redirect: vi.fn(), render: vi.fn() } as unknown as Response;

await callHandler(POST, req, res);

expect(res.redirect).toHaveBeenCalledWith("/manual-upload-success");
});

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
echo "--- manual-upload-summary controller ---"
rg -n -C6 'extractAndStoreArtefactSearch|processPublication\(' 'apps/web/src/pages/(admin)/manual-upload-summary/index.ts'

Repository: hmcts/cath-service

Length of output: 1776


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "--- locate processPublication implementation ---"
fd -a 'publication' . | head -n 20
echo
rg -n -C8 'function processPublication|const processPublication|processPublication\s*=' . --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**'
echo
echo "--- locate extractAndStoreArtefactSearch implementation ---"
rg -n -C8 'extractAndStoreArtefactSearch' . --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**'

Repository: hmcts/cath-service

Length of output: 50374


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "--- publication package files ---"
git ls-files | rg '^packages/.*/.*publication.*\.(ts|tsx|js)$|^apps/.*/.*publication.*\.(ts|tsx|js)$|^libs/.*/.*publication.*\.(ts|tsx|js)$'

echo
echo "--- search for processPublication and extractAndStoreArtefactSearch usages ---"
rg -n -C6 'processPublication|extractAndStoreArtefactSearch' packages apps libs --glob '!**/node_modules/**' --glob '!**/dist/**' --glob '!**/build/**'

Repository: hmcts/cath-service

Length of output: 50375


Avoid extracting JSON search data twice. The JSON upload path calls extractAndStoreArtefactSearch(...) directly and then passes the same jsonData into processPublication(...), which already calls it internally. Remove one of those calls to avoid duplicate DB work and the extra race window.

@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
junaidiqbalmoj merged commit 78ce592 into master Jul 3, 2026
36 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>
SarahLittlejohn added a commit that referenced this pull request Aug 4, 2026
The database is derived entirely from schema.sql + seed.sql + migrations/*.sql,
which init_db.sh applies in order. The migrations describe what is in it, so the
binary adds nothing a clone cannot rebuild — and committing it means every sync
PR carries a ~2MB binary diff that no reviewer can read.

.gitignore has listed requirements/*.db since #695, but the file was already
tracked by then: it was swept into #772 (an unrelated list-types PR) the same
day, and gitignore does not apply to tracked files. Remove it from the index;
it stays on disk and is now correctly ignored.

Rebuild with: yarn requirements:build

Co-Authored-By: Claude Opus 5 (1M context) <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: SEND, CIC and Asylum Support Tribunal Hearing Lists Publishing in CaTH

2 participants