From aaaf1088f7026cb75552627caec5ab107f5a7621 Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Sun, 26 Jul 2026 05:16:05 +0000 Subject: [PATCH 1/2] chore(requirements): sync github 2026-07-26 Reconcile requirements baseline with CaTH Kanban board state: - 3 new requirements (REQ-0157..REQ-0159): #593, #699, #859 - 1 status+impl change: REQ-0099 (#343) implemented -> verified Co-Authored-By: Claude Opus 4.6 --- .../migrations/010_sync_github_2026_07_26.sql | 379 ++++++++++++++++++ 1 file changed, 379 insertions(+) create mode 100644 requirements/migrations/010_sync_github_2026_07_26.sql diff --git a/requirements/migrations/010_sync_github_2026_07_26.sql b/requirements/migrations/010_sync_github_2026_07_26.sql new file mode 100644 index 000000000..eb97555f7 --- /dev/null +++ b/requirements/migrations/010_sync_github_2026_07_26.sql @@ -0,0 +1,379 @@ +-- 010: sync github 2026-07-26 +-- +-- Reconciles the requirements baseline with the live state of GitHub Project #43 +-- (CaTH Kanban) as of 2026-07-26. Generated by the nightly requirements-sync job. +-- +-- NOTE: The GitHub App token used by this job does not have read:project permission, +-- so board column status cannot be read directly from ProjectV2. Instead, closure +-- of the GitHub issue + presence of a merged closing PR is used as a proxy for +-- Done=verified. A human reviewer should confirm the board position before merging. +-- +-- Delta captured (gate = "Refined Tickets" and beyond): +-- * 3 NEW requirements (REQ-0157..REQ-0159): +-- #593, #699, #859 +-- * 1 status change: +-- REQ-0099 (#343): implemented -> verified +-- * 1 impl change (combined with status change above): +-- REQ-0099 (#343): impl_commit_sha and impl_paths populated +-- +-- HUMAN REVIEW REQUIRED: Board access unavailable; verify the 3 new issues are +-- actually past "Refined Tickets" on the CaTH Kanban before merging. + +BEGIN TRANSACTION; + +-- ============================================================================ +-- NEW REQUIREMENTS (3 issues, all closed with merged closing PRs) +-- ============================================================================ + +INSERT INTO requirement + (id, ref, title, statement, kind, status, priority, granularity, + issue_number, issue_url, impl_commit_sha, impl_paths, + created_at, updated_at, created_by, updated_by) +VALUES + (157, 'REQ-0157', 'Implement Employment Tribunal Lists style guide', '## User Story + +As a user, I want to view Employment Tribunal Lists in an accessible and well-formatted style, so that I can see scheduled hearings with all relevant case details. + +## Background + +Two Employment Tribunal list types are implemented together: +- `et-daily-list` (`ET_DAILY_LIST`) +- `et-fortnightly-list` (`ET_FORTNIGHTLY_PRESS_LIST`) + +Each has its own separate JSON schema. They follow the same module pattern as the existing `civil-and-family-daily-cause-list` implementation. + +> **Sources of truth** (verified against upstream): +> - List type metadata: [`listLookup.json`](https://github.com/hmcts/pip-frontend/blob/master/src/main/resources/listLookup.json) +> - Style guide / language: [`locales/en/et-daily-list.json`](https://github.com/hmcts/pip-frontend/blob/master/src/main/resources/locales/en/et-daily-list.json), [`locales/en/et-fortnightly-list.json`](https://github.com/hmcts/pip-frontend/blob/master/src/main/resources/locales/en/et-fortnightly-list.json) (and `cy/` equivalents) +> - Schemas: [`et_daily_list.json`](https://github.com/hmcts/pip-data-management/blob/master/src/main/resources/schemas/et_daily_list.json), [`et_fortnightly_press_list.json`](https://github.com/hmcts/pip-data-management/blob/master/src/main/resources/schemas/et_fortnightly_press_list.json) + +## List type metadata (from `listLookup.json`) + +| Key | `ET_DAILY_LIST` | `ET_FORTNIGHTLY_PRESS_LIST` | +|-----|-----------------|-----------------------------| +| `friendlyName` (EN) | Employment Tribunals Daily List | Employment Tribunals Fortnightly Press List | +| `welshFriendlyName` (CY) | Rhestr Ddyddiol y Tribiwnlysoedd Cyflogaeth | Rhestr y Wasg Pob Pythefnos y Tribiwnlysoedd Cyflogaeth | +| `shortenedFriendlyName` | ET Daily List | ET Fortnightly List | +| `url` | `et-daily-list` | `et-fortnightly-list` | +| `jurisdictionTypes` | Employment Tribunal | Employment Tribunal | + +> ⚠️ The friendly names use the **plural** "Employment **Tribunals**" and the fortnightly name includes "**Press**". Use these `listLookup.json` values for the venue/title display — they are the source of truth. An earlier draft of this ticket used singular "Tribunal" and dropped "Press"; those were incorrect. + +## Acceptance Criteria + +**Venue / list name displayed in the front end:** +- Employment Tribunals Daily List +- Employment Tribunals Fortnightly Press List + +**Data fields for both lists:** +Start time, Duration, Case number, Claimant, Respondent, Hearing Type, and Hearing Platform + +> Note on data provenance — these display fields do **not** map 1:1 to schema fields: +> - **Start time** ← `courtLists[].courtHouse.courtRoom[].session[].sittings[].sittingStart` +> - **Duration** ← derived from `sittingStart` → `sittingEnd` +> - **Case number** ← `...hearing[].case[].caseNumber` +> - **Claimant / Respondent** ← `...case[].party[]`, split by `partyRole` (see schema `enum` differences below) +> - **Hearing Type** ← `...hearing[].hearingType` +> - **Hearing Platform** ← `...sittings[].channel[]` (the `channel` string array) + +**Open Justice — full text for the ''Important information'' accordion** (from locale, keys `openJustice1`–`openJustice6`): + +1. Open justice is a fundamental principle in our courts and tribunals system, and will continue to be as we increase the use of audio and video technology. +2. When considering the use of telephone and video technology, the judiciary will have regard to the principles of open justice. Judges may determine that a hearing should be held in private if this is necessary to secure the proper administration of justice. +3. The inclusion of a case in the Press List is no guarantee that it is not subject to a restricted reporting order. Members of the Press should ensure that no order exists on an individual case before submitting material for publication. +4. Requests from the media and members of the public to observe a hearing remotely should be made in advance to: _(venue contact — from `venue.venueContact`)_ +5. The naming convention in the subject heading of an email request should read: +6. "MEDIA OR PUBLIC ACCESS REQUEST - AN Other v AN Other - Hearing Date." + +## Schema notes (`et_daily_list.json` vs `et_fortnightly_press_list.json`) + +Both schemas are `type: object`, `required: ["document", "venue", "courtLists"]`, and are **structurally near-identical**. Key structure: + +``` +document.publicationDate (required, ISO datetime) +venue.venueName (required) +venue.venueContact.{venueTelephone, venueEmail} +courtLists[].courtHouse (required) + courtHouseName (required) + courtHouseAddress.{line[], town, county, postCode} + courtRoom[].session[].sittings[] (session, sittings required) + sittingStart, sittingEnd (required) + hearing[] (required) + hearingType (required) + case[].caseNumber (required) + case[].caseSequenceIndicator + case[].party[].partyRole (required) + case[].party[].individualDetails.{title, individualForenames, individualSurname} + case[].party[].organisationDetails.organisationName + channel[] (string array — hearing platform) +``` + +**The only meaningful difference between the two schemas** is the `party[].partyRole` enum: +- `et_daily_list.json`: `["APPLICANT_PETITIONER", "RESPONDENT"]` +- `et_fortnightly_press_list.json`: `["APPLICANT_PETITIONER", "APPLICANT_PETITIONER_REPRESENTATIVE", "RESPONDENT", "RESPONDENT_REPRESENTATIVE"]` (adds representative roles) + +The fortnightly list therefore also renders representative parties — see the `rep` / `noRep` locale keys below. Copy both schema files verbatim from pip-data-management; do not share a single schema. + +## Module structure +- [ ] Two new libs created: + - `libs/list-types/et-daily-list/` + - `libs/list-types/et-fortnightly-list/` +- [ ] Each lib contains: + - `src/models/types.ts` — TypeScript interfaces matching the respective JSON schema + - `src/validation/json-validator.ts` — validates against the respective schema (+ `json-validator.test.ts`, per CLAUDE.md list-type rules) + - `src/schemas/{list-type}.json` — copied from pip-data-management (`et_daily_list.json`, `et_fortnightly_press_list.json`) + - `src/rendering/renderer.ts` and `renderer.test.ts` + - `src/pages/index.ts`, `index.test.ts`, `en.ts`, `cy.ts`, `{list-type}.njk` + - `src/pdf/pdf-generator.ts`, `pdf-template.njk`, `pdf-generator.test.ts` + - `src/index.ts`, `src/config.ts`, `package.json`, `tsconfig.json` + +## Page content (EN) — from `locales/en/et-daily-list.json` / `et-fortnightly-list.json` + +Both ET lists share the same locale keys. Values below are taken verbatim from pip-frontend. + +| Key | English | +|-----|---------| +| `title` (et-daily-list) | Employment Tribunals Daily List | +| `title` (et-fortnightly-list) | Employment Tribunals Fortnightly Press List | +| `listFor` | List for | +| `listUpdated` | Last updated DATE at | +| `importantInformation` | Important information | +| `venue` | Venue: | +| `courtRoom` | Courtroom | +| `backButton` | Back | +| `dataSource` | Data Source | +| `hearingDurationHour` / `hearingDurationHours` | hour / hours | +| `hearingDurationMinute` / `hearingDurationMinutes` | min / mins | +| `rep` (fortnightly only) | Rep | +| `noRep` (fortnightly only) | No Representative | + +> Note: the upstream `locales/en/et-fortnightly-list.json` `title` value reads "Employment Tribunals Fortnightly **List**" (missing "Press"), which conflicts with the `listLookup.json` friendly name. Use the `listLookup.json` value ("Employment Tribunals Fortnightly Press List") for the page title. + +## Page content (CY) — from `locales/cy/et-daily-list.json` / `et-fortnightly-list.json` + +| Key | Welsh | +|-----|-------| +| `title` (et-daily-list) | Rhestr Ddyddiol y Tribiwnlysoedd Cyflogaeth | +| `title` (et-fortnightly-list) | Rhestr y Wasg Pob Pythefnos y Tribiwnlysoedd Cyflogaeth | +| `listFor` | Rhestr ar gyfer | +| `listUpdated` | Diweddarwyd ddiwethaf DATE am | +| `importantInformation` | Gwybodaeth bwysig | +| `venue` | Lleoliad: | +| `courtRoom` | Ystafell llys | +| `backButton` | Yn ôl | +| `dataSource` | Ffynhonnell y Data | +| `hearingDurationHour` / `hearingDurationHours` | awr / awr | +| `hearingDurationMinute` / `hearingDurationMinutes` | munud / munud | +| `rep` (fortnightly only) | Cynrychiolydd | +| `noRep` (fortnightly only) | Dim Cynrychiolydd | + +> ⚠️ The upstream `locales/cy/et-fortnightly-list.json` `title` is a copy-paste bug — it reads "Tribiwnlysoedd Cyflogaeth Rhestr Ddyddiol" (Daily). Use the `welshFriendlyName` from `listLookup.json` instead (shown above). Also note the CY Open Justice text differs slightly in whitespace from EN — copy it verbatim from the CY locale file. + +## Hearings table columns + +Both ET lists use the same `tableHeaders` array from locale: + +| # | EN (from locale) | CY (from locale) | +|---|------------------|------------------| +| 1 | Start Time | Amser Cychwyn | +| 2 | Duration | Hyd | +| 3 | Case Number | Cyfeirnod yr Achos | +| 4 | Claimant | Hawlydd | +| 5 | Respondent | Atebydd | +| 6 | Hearing Type | Math o wrandawiad | +| 7 | Hearing Platform | Sianel y Gwrandawiad | + +> ⚠️ Column 7 Welsh in the upstream locale is "**Sianel y Gwrandawiad**" (Hearing *Channel*), not "Platfform Gwrandawiad". Match the locale file. The `channel[]` schema field backs this column. + +## Pages +- [ ] Pages accessible at: + - `GET /et-daily-list?artefactId=` + - `GET /et-fortnightly-list?artefactId=` +- [ ] Each displays venue name, address, content date, last updated timestamp +- [ ] Hearings table shows the 7 columns defined above +- [ ] Open Justice collapsible section present (full `openJustice1`–`openJustice6` text) +- [ ] Case search input present +- [ ] Data source attribution shown at bottom + +## Validation and access control +- [ ] Returns 400 if `artefactId` is missing +- [ ] Returns 404 if artefact not found +- [ ] Returns 403 if user does not have access +- [ ] Returns 400 if JSON fails schema validation + +## PDF generation +- [ ] PDF generated for each list type matching the HTML view structure +- [ ] PDF saved to storage correctly + +## Welsh language +- [ ] All page content available in Welsh via `?lng=cy` +- [ ] PDF generated in correct language based on locale + +## Registration +- [ ] Both modules registered in `apps/web/src/app.ts` +- [ ] Path aliases added to root `tsconfig.json` +- [ ] Packages added as dependencies in `apps/web/package.json` +- [ ] PDF generators registered by `listTypeName` in `PDF_GENERATOR_REGISTRY` (`libs/publication/src/processing/service.ts`) +- [ ] Excel/JSON converters registered by name (`registerConverterByName`) + +## Tests +- [ ] Unit tests pass for both modules (including `json-validator.test.ts` with one `it` per required field at every nesting level) +- [ ] `yarn test` passes across the workspace + +## TODO + +- [ ] Add email summary (`src/email-summary/summary-builder.ts`) for each list once email summary requirements are confirmed + +## Technical Notes + +- Schema sources: `et_daily_list.json`, `et_fortnightly_press_list.json` from pip-data-management `src/main/resources/schemas/` +- Follow the `civil-and-family-daily-cause-list` module as the reference implementation +- **Never use numeric `listTypeId`** — route/guard on `listTypeName` (`ET_DAILY_LIST`, `ET_FORTNIGHTLY_PRESS_LIST`) per CLAUDE.md list-type rules +', 'functional', 'verified', NULL, 'story', 593, 'https://github.com/hmcts/cath-service/issues/593', '735da3a9e0f81018c3f2dd20b6f8024b0ad0e53f', '["apps/postgres/package.json", "apps/postgres/prisma/scripts/001_insert_missing_list_types.sql", "apps/postgres/prisma/scripts/002_update_list_type_provenances.sql", "apps/postgres/prisma/scripts/003_upsert_sub_jurisdictions_and_list_type_links.sql", "apps/postgres/prisma/scripts/004_soft_delete_crime_daily_list.sql", "apps/postgres/prisma/seed-deploy.ts", "apps/postgres/prisma/seed.sql", "apps/postgres/prisma/seed.test.ts", "apps/postgres/prisma/seed.ts", "apps/postgres/start.sh", "apps/web/package.json", "apps/web/src/app.ts", "apps/web/src/assets/css/list-types/et-lists.scss", "apps/web/src/assets/css/web.scss", "apps/web/src/pages/(list-types)/et-daily-list/et-daily-list.njk", "apps/web/src/pages/(list-types)/et-daily-list/index.test.ts", "apps/web/src/pages/(list-types)/et-daily-list/index.ts", "apps/web/src/pages/(list-types)/et-fortnightly-list/et-fortnightly-list.njk", "apps/web/src/pages/(list-types)/et-fortnightly-list/index.test.ts", "apps/web/src/pages/(list-types)/et-fortnightly-list/index.ts", "libs/list-types/common/src/index.ts", "libs/list-types/common/src/list-type-data.ts", "libs/list-types/common/src/models/cause-list-types.ts", "libs/list-types/common/src/pdf/pdf-styles.ts", "libs/list-types/common/src/rendering/crown-utilities.ts", "libs/list-types/common/src/validation/list-type-validator.ts", "libs/list-types/daily-cause-list-common/src/models/types.ts", "libs/list-types/daily-cause-list-common/src/rendering/renderer.test.ts", "libs/list-types/daily-cause-list-common/src/rendering/renderer.ts", "libs/list-types/et-daily-list/package.json", "libs/list-types/et-daily-list/src/config.test.ts", "libs/list-types/et-daily-list/src/config.ts", "libs/list-types/et-daily-list/src/email-summary/summary-builder.test.ts", "libs/list-types/et-daily-list/src/email-summary/summary-builder.ts", "libs/list-types/et-daily-list/src/index.test.ts", "libs/list-types/et-daily-list/src/index.ts", "libs/list-types/et-daily-list/src/locales/cy.ts", "libs/list-types/et-daily-list/src/locales/en.ts", "libs/list-types/et-daily-list/src/models/types.ts", "libs/list-types/et-daily-list/src/pdf/pdf-generator.test.ts", "libs/list-types/et-daily-list/src/pdf/pdf-generator.ts", "libs/list-types/et-daily-list/src/pdf/pdf-template.njk", "libs/list-types/et-daily-list/src/rendering/renderer.test.ts", "libs/list-types/et-daily-list/src/rendering/renderer.ts", "libs/list-types/et-daily-list/src/schemas/et-daily-list.json", "libs/list-types/et-daily-list/src/validation/json-validator.test.ts", "libs/list-types/et-daily-list/src/validation/json-validator.ts", "libs/list-types/et-daily-list/tsconfig.json", "libs/list-types/et-fortnightly-list/package.json", "libs/list-types/et-fortnightly-list/src/config.test.ts", "libs/list-types/et-fortnightly-list/src/config.ts", "libs/list-types/et-fortnightly-list/src/email-summary/summary-builder.test.ts", "libs/list-types/et-fortnightly-list/src/email-summary/summary-builder.ts", "libs/list-types/et-fortnightly-list/src/index.test.ts", "libs/list-types/et-fortnightly-list/src/index.ts", "libs/list-types/et-fortnightly-list/src/locales/cy.ts", "libs/list-types/et-fortnightly-list/src/locales/en.ts", "libs/list-types/et-fortnightly-list/src/models/types.ts", "libs/list-types/et-fortnightly-list/src/pdf/pdf-generator.test.ts", "libs/list-types/et-fortnightly-list/src/pdf/pdf-generator.ts", "libs/list-types/et-fortnightly-list/src/pdf/pdf-template.njk", "libs/list-types/et-fortnightly-list/src/rendering/renderer.test.ts", "libs/list-types/et-fortnightly-list/src/rendering/renderer.ts", "libs/list-types/et-fortnightly-list/src/schemas/et-fortnightly-press-list.json", "libs/list-types/et-fortnightly-list/src/validation/json-validator.test.ts", "libs/list-types/et-fortnightly-list/src/validation/json-validator.ts", "libs/list-types/et-fortnightly-list/tsconfig.json", "libs/list-types/et-list-common/package.json", "libs/list-types/et-list-common/src/email-summary/et-summary-builder.test.ts", "libs/list-types/et-list-common/src/email-summary/et-summary-builder.ts", "libs/list-types/et-list-common/src/hearing-formatting.test.ts", "libs/list-types/et-list-common/src/hearing-formatting.ts", "libs/list-types/et-list-common/src/index.ts", "libs/list-types/et-list-common/src/party-formatting.test.ts", "libs/list-types/et-list-common/src/party-formatting.ts", "libs/list-types/et-list-common/src/region-resolver.test.ts", "libs/list-types/et-list-common/src/region-resolver.ts", "libs/list-types/et-list-common/tsconfig.json", "libs/location/src/seed-list-types.test.ts", "libs/location/src/seed-list-types.ts", "libs/notifications/package.json", "libs/notifications/src/notification/notification-service.ts", "libs/publication/package.json", "libs/publication/src/processing/service.ts", "tsconfig.json"]', '2026-05-13T08:51:59Z', '2026-05-13T08:51:59Z', 'junaidiqbalmoj', 'junaidiqbalmoj'), + (158, 'REQ-0158', 'Manage List Type Screens (Screens for adding jurisdictions and regions)', '**PROBLEM STATEMENT** +This ticket is raised to make changes to the System Admin Dashboard. + +**AS A** Service +**I WANT** to update the System Admin Dashboard +**SO THAT** the list configuration process is consolidated + +**ACCEPTANCE CRITERIA** +Merge the ''Manage List Types'' and ''Configure List Types'' tiles and re-name the merged/single tile to ''Manage List Types'' + +**Process Flow:** + +**''Manage list type'' process:** +Step 1: Log into the System Admin Dashboard and click on the ‘Manage List Types’ tile which proceeds to the ‘Select list type’ screen. +Step 2: Click on the ‘Manage’ link which proceeds to the ‘Manage list type’ screen. + +**''Edit list type'' process:** +Step 1: On the ‘Manage List Type’ screen, click on the ‘Edit List Type’ button which proceeds to the ‘Edit List Type’ screen. +Step 2: Populate the form (Data fields: Name, Friendly name, Welsh friendly name, Shortened friendly name, URL, Case number JSON field name, Case name JSON field name, Default sensitivity, Allowed provenance and ''Is non-strategic?) and click ‘Continue’ button which proceeds to the ‘Select sub-jurisdiction and region’ screen. +Step 3: On the ‘Select Sub-Jurisdiction and region’ screen, check the boxes for the sub-jurisdictions to be linked to the list type (Type of criminal court, Type of civil court, Type of family court and Type of tribunal sub-jurisdiction options provided as check boxes under each jurisdiction title in an accordion) and the region. Accordions are open by default. Click ‘Continue’ button to proceed to the summary screen. +Step 4: On the Summary screen titled ''Check list type details'', check the details and click ‘Change’ link beside any detail to be updated (takes user back to ‘Edit List Type’ screen) or ‘Confirm’ to proceed if the details are correct. ‘Confirm’ button takes user to the final confirmation screen titled ‘List type updated’. + +**''Delete list type'' process:** +Step 1: On the ‘Manage List Type’ screen, click on the ‘Delete List Type’ button which proceeds to the ‘Are you sure you want to delete list type’ screen. +Step 2: Click on the ‘Confirm’ to proceed if the details are correct. ‘Confirm’ button takes user to the final confirmation screen titled ‘list type deleted’. + +**''Add new list type'' process:** +Step 1: On the ‘Select List Type’ screen, click on the ‘Add New List Type’ button which proceeds to the ‘Enter List Type’ screen. +Step 2: Populate the form (Data fields: Name, Friendly name, Welsh friendly name, Shortened friendly name, URL, Case number JSON field name, Case name JSON field name, Default sensitivity, Allowed provenance and ''Is non-strategic?) and click ‘Continue’ button which proceeds to the ‘Select sub-jurisdiction and region’ screen. +Step 3: On the ‘Select sub-jurisdiction and region’ screen, check the boxes for the sub-jurisdictions to be linked to the list type (Type of criminal court, Type of civil court, Type of family court and Type of tribunal sub-jurisdiction options provided as check boxes under each jurisdiction title in an accordion) and the region. Accordions are open by default. Click ‘Continue’ button to proceed to the ‘Summary’ screen. +Step 3: On the Summary screen titled ''Check list details'', check the details and click ‘Change’ link beside any detail to be updated (takes user back to ‘Add List Configuration’ screen) or ‘Confirm’ to proceed if the details are correct. ‘Confirm’ button takes user to the final confirmation screen titled ‘List type updated’. + + +[manage list type configuration.docx](https://github.com/user-attachments/files/29131160/manage.list.type.configuration.docx)', 'functional', 'verified', NULL, 'story', 699, 'https://github.com/hmcts/cath-service/issues/699', '7ead600db7a75368f8d04d1e2dc36baf2a7fc6cf', '["apps/postgres/prisma/migrations/20260714112456_add_list_type_json_fields/migration.sql", "apps/web/src/pages/(system-admin)/add-list-type/cy.ts", "apps/web/src/pages/(system-admin)/add-list-type/en.ts", "apps/web/src/pages/(system-admin)/add-list-type/index.njk", "apps/web/src/pages/(system-admin)/add-list-type/index.test.ts", "apps/web/src/pages/(system-admin)/add-list-type/index.ts", "apps/web/src/pages/(system-admin)/configure-list-type-enter-details/index.test.ts", "apps/web/src/pages/(system-admin)/configure-list-type-enter-details/index.ts", "apps/web/src/pages/(system-admin)/configure-list-type-preview/cy.ts", "apps/web/src/pages/(system-admin)/configure-list-type-preview/en.ts", "apps/web/src/pages/(system-admin)/configure-list-type-preview/index.njk", "apps/web/src/pages/(system-admin)/configure-list-type-preview/index.njk.test.ts", "apps/web/src/pages/(system-admin)/configure-list-type-preview/index.test.ts", "apps/web/src/pages/(system-admin)/configure-list-type-preview/index.ts", "apps/web/src/pages/(system-admin)/configure-list-type-select-sub-jurisdictions/index.njk", "apps/web/src/pages/(system-admin)/configure-list-type-select-sub-jurisdictions/index.test.ts", "apps/web/src/pages/(system-admin)/configure-list-type-select-sub-jurisdictions/index.ts", "apps/web/src/pages/(system-admin)/configure-list-type-success/cy.ts", "apps/web/src/pages/(system-admin)/configure-list-type-success/en.ts", "apps/web/src/pages/(system-admin)/configure-list-type-success/index.njk", "apps/web/src/pages/(system-admin)/delete-list-type-success/index.njk", "apps/web/src/pages/(system-admin)/delete-list-type-success/index.njk.test.ts", "apps/web/src/pages/(system-admin)/delete-list-type/cy.ts", "apps/web/src/pages/(system-admin)/delete-list-type/en.ts", "apps/web/src/pages/(system-admin)/delete-list-type/index.njk", "apps/web/src/pages/(system-admin)/delete-list-type/index.njk.test.ts", "apps/web/src/pages/(system-admin)/delete-list-type/index.test.ts", "apps/web/src/pages/(system-admin)/delete-list-type/index.ts", "apps/web/src/pages/(system-admin)/edit-list-type/cy.ts", "apps/web/src/pages/(system-admin)/edit-list-type/en.ts", "apps/web/src/pages/(system-admin)/edit-list-type/index.njk", "apps/web/src/pages/(system-admin)/edit-list-type/index.test.ts", "apps/web/src/pages/(system-admin)/edit-list-type/index.ts", "apps/web/src/pages/(system-admin)/manage-list-type/cy.ts", "apps/web/src/pages/(system-admin)/manage-list-type/en.ts", "apps/web/src/pages/(system-admin)/manage-list-type/index.njk", "apps/web/src/pages/(system-admin)/manage-list-type/index.test.ts", "apps/web/src/pages/(system-admin)/manage-list-type/index.ts", "apps/web/src/pages/(system-admin)/manage-list-types/cy.ts", "apps/web/src/pages/(system-admin)/manage-list-types/en.ts", "apps/web/src/pages/(system-admin)/manage-list-types/index.njk", "apps/web/src/pages/(system-admin)/manage-list-types/index.test.ts", "apps/web/src/pages/(system-admin)/manage-list-types/index.ts", "apps/web/src/pages/(system-admin)/system-admin-dashboard/cy.ts", "apps/web/src/pages/(system-admin)/system-admin-dashboard/en.ts", "apps/web/src/pages/(system-admin)/view-list-types/index.test.ts", "apps/web/src/pages/(system-admin)/view-list-types/index.ts", "e2e-tests/tests/system-admin/configure-list-type.spec.ts", "e2e-tests/tests/system-admin/manage-list-types.spec.ts", "e2e-tests/tests/system-admin/system-admin-dashboard.spec.ts", "libs/postgres-prisma/prisma/schema/location.prisma", "libs/system-admin-pages/src/list-type/queries.test.ts", "libs/system-admin-pages/src/list-type/queries.ts", "libs/system-admin-pages/src/list-type/service.test.ts", "libs/system-admin-pages/src/list-type/service.ts", "libs/system-admin-pages/src/list-type/types.ts", "libs/system-admin-pages/src/list-type/validation.test.ts", "libs/system-admin-pages/src/list-type/validation.ts"]', '2026-06-10T13:46:48Z', '2026-06-10T13:46:48Z', 'OgechiOkelu', 'OgechiOkelu'), + (159, 'REQ-0159', 'Style Guide: Implement High Court manual-upload daily cause lists (Business & Property, Circuit Commercial, HC Civil, HC Family)', '## User Story + +As a user, I want to view the following High Court daily cause lists that have been manually uploaded as flat files, so that I can access scheduled hearing information. + +## Background + +Four **manual-upload flat-file** list types need to be registered. + +**These are flat-file lists. They have NO JSON schema.** They are uploaded as flat files (PDF / CSV / DOC / HTML) through the admin manual-upload journey and served/downloaded verbatim through the existing generic flat-file path. There is **no** JSON validation, no Excel-to-JSON conversion, no bespoke HTML renderer, and no bespoke PDF generator for these list types. + +> The earlier version of this ticket incorrectly described these as JSON-schema list types with per-list-type `libs/list-types/*` packages. That is wrong — those steps do not apply. See "How flat-file lists actually work" below. + +Reference: [`listLookup.json` in pip-frontend](https://github.com/hmcts/pip-frontend/blob/master/src/main/resources/listLookup.json). + +| List type (enum) | url path | Jurisdiction | +|---|---|---| +| `BUSINESS_AND_PROPERTY_DAILY_CAUSE_LIST` | `business-and-property-daily-list` | High Court | +| `CIRCUIT_COMMERCIAL_COURT_DAILY_CAUSE_LIST` | `circuit-commercial-court-daily-list` | High Court | +| `HIGH_COURT_CIVIL_DAILY_CAUSE_LIST` | `high-court-civil-daily-list` | High Court | +| `HIGH_COURT_FAMILY_DAILY_CAUSE_LIST` | `high-court-family-daily-list` | High Court of the Family Division | + +All four have `isNonStrategic: false`, `provenance: "CFT_IDAM"`, and `defaultSensitivity: "Public"`. + +## Page titles + +| List | EN title | CY title | +|------|----------|----------| +| business-and-property-daily-list | Business & Property Daily Cause List | Rhestr Achosion Dyddiol Busnes ac Eiddo | +| circuit-commercial-court-daily-list | Circuit Commercial Court Daily Cause List | Rhestr Achosion Dyddiol Llys Masnachol Cylchdaith | +| high-court-civil-daily-list | High Court Civil Daily Cause List | Rhestr Achosion Dyddiol Sifil yr Uchel Lys | +| high-court-family-daily-list | High Court Family Daily Cause List | Rhestr Achosion Dyddiol Teulu yr Uchel Lys | + +## How flat-file lists actually work (context) + +- **`isNonStrategic`** is a per-**list-type** property (set in `libs/list-types/common/src/list-type-data.ts`). +- **`isFlatFile`** is a per-**artefact** (per-upload) property. It is set at upload time, **not** in the list-type catalogue. `apps/web/src/pages/(admin)/manual-upload-summary/index.ts` sets `isFlatFile = !fileName.endsWith(".json")` — i.e. any non-JSON file uploaded through the manual-upload journey becomes a flat-file artefact. +- Flat-file artefacts are stored as-is and displayed/downloaded verbatim via `libs/public-pages/src/flat-file/flat-file-service.ts`. `processPublication` does no schema validation, no PDF generation, and no search extraction for a flat file. +- The manual-upload form (`libs/admin-pages/src/manual-upload/validation.ts`, `validateManualUploadForm`) already accepts `.csv|.doc|.docx|.htm|.html|.json|.pdf`. Only `.json` files are schema-validated; the other formats are treated as flat files. +- Consequently, **no `libs/list-types//` package, schema, validator, renderer, or PDF generator is required** for these four list types. + +## Acceptance Criteria + +### List type data registration +- [ ] Add all four list type entries to `libs/list-types/common/src/list-type-data.ts` with the correct `name` (enum), `englishFriendlyName`, `welshFriendlyName`, `urlPath`, `provenance: "CFT_IDAM"`, `isNonStrategic: false`, `defaultSensitivity: "Public"`, and `subJurisdictionIds` +- [ ] Enum `name` values match CaTH ORG exactly (see #846) so data sync works + +### Manual upload journey (flat file) +- [ ] Each list type is selectable in the admin manual-upload journey +- [ ] A flat file (e.g. PDF) can be uploaded and committed against each list type, producing an artefact with `isFlatFile: true` +- [ ] No JSON schema validation is applied to the flat-file upload (only `.json` uploads are validated) + +### Viewing the flat file +- [ ] Uploaded flat file is viewable/downloadable via the existing generic flat-file path (`libs/public-pages/src/flat-file/`) +- [ ] Correct English and Welsh friendly names / page titles are shown, driven by the catalogue entry (see page-titles table above) +- [ ] Access control behaves as for other flat-file lists (403 when the user does not have access) + +### Welsh language +- [ ] Welsh friendly names present in the catalogue entry and used when `?lng=cy` + +### Tests +- [ ] Unit tests updated/added for the `list-type-data.ts` additions +- [ ] `yarn test` passes across the workspace + +## Out of scope (explicitly NOT required — these apply only to JSON list types) + +- ❌ New `libs/list-types//` package per list type +- ❌ `src/schemas/*.json`, `src/validation/json-validator.ts` + tests +- ❌ `src/rendering/renderer.ts`, bespoke HTML page under `apps/web/src/pages/` +- ❌ `src/pdf/pdf-generator.ts` + PDF template, and registration in `PDF_GENERATOR_REGISTRY` +- ❌ Excel converter registration +- ❌ Path aliases in root `tsconfig.json` / dependencies in `apps/web/package.json` +- ❌ The `libs/list-types/common` CI schema-guard test (only applies to packages shipping a schema) + +## Notes / corrections to the original ticket + +- The list-type catalogue lives at **`libs/list-types/common/src/list-type-data.ts`**, not `libs/location/src/list-type-data.ts` (which does not exist). +- The referenced `pht-weekly-hearing-list` (#645) reference implementation does not exist in this repo; the nearest JSON reference is `care-standards-tribunal-weekly-hearing-list` — but that is a JSON/Excel list and is **not** the model for these flat-file lists. +', 'functional', 'verified', NULL, 'story', 859, 'https://github.com/hmcts/cath-service/issues/859', 'c74ad165fc754ea590a19d844d162381cec3cf9d', '["apps/postgres/prisma/scripts/001_insert_missing_list_types.sql", "apps/postgres/prisma/scripts/003_upsert_sub_jurisdictions_and_list_type_links.sql", "libs/list-types/common/src/list-type-data.test.ts", "libs/list-types/common/src/list-type-data.ts"]', '2026-07-15T08:49:48Z', '2026-07-15T08:49:48Z', 'junaidiqbalmoj', 'junaidiqbalmoj'); + +-- ============================================================================ +-- STATUS + IMPL CHANGE: REQ-0099 (#343) implemented -> verified +-- ============================================================================ + +UPDATE requirement +SET status = 'verified', + impl_commit_sha = 'daaf5f49099710810ace858ae70a170f0c41f27c', + impl_paths = '["e2e-tests/tests/api/subscription-notifications.spec.ts", "e2e-tests/utils/test-support-api.ts", "libs/notifications/src/govnotify/govnotify-client.test.ts", "libs/notifications/src/govnotify/govnotify-client.ts", "libs/notifications/src/govnotify/template-config.test.ts", "libs/notifications/src/govnotify/template-config.ts", "libs/notifications/src/notification/notification-service.test.ts", "libs/notifications/src/notification/notification-service.ts"]', + version = version + 1, + updated_at = '2026-07-26T00:00:00Z', + updated_by = 'github-actions[bot]' +WHERE id = 99; + +-- ============================================================================ +-- CHANGE LOG +-- ============================================================================ + +-- One 'created' change row per new requirement (version 1). +INSERT INTO requirement_change + (requirement_id, version, change_type, change_summary, changed_by, changed_at) +VALUES + (157, 1, 'created', 'imported from GitHub issue', 'github-actions[bot]', '2026-05-13T08:51:59Z'), + (158, 1, 'created', 'imported from GitHub issue', 'github-actions[bot]', '2026-06-10T13:46:48Z'), + (159, 1, 'created', 'imported from GitHub issue', 'github-actions[bot]', '2026-07-15T08:49:48Z'); + +-- Status + impl change entries for REQ-0099 (#343). +INSERT INTO requirement_change + (requirement_id, version, field, old_value, new_value, change_type, change_summary, changed_by, changed_at) +VALUES + (99, 2, 'status', 'implemented', 'verified', 'status_changed', 'board status moved', 'github-actions[bot]', '2026-07-26T00:00:00Z'), + (99, 2, 'impl_commit_sha', NULL, 'daaf5f49099710810ace858ae70a170f0c41f27c', 'modified', 'merged PR(s) changed', 'github-actions[bot]', '2026-07-26T00:00:00Z'), + (99, 2, 'impl_paths', NULL, '["e2e-tests/tests/api/subscription-notifications.spec.ts", "e2e-tests/utils/test-support-api.ts", "libs/notifications/src/govnotify/govnotify-client.test.ts", "libs/notifications/src/govnotify/govnotify-client.ts", "libs/notifications/src/govnotify/template-config.test.ts", "libs/notifications/src/govnotify/template-config.ts", "libs/notifications/src/notification/notification-service.test.ts", "libs/notifications/src/notification/notification-service.ts"]', 'modified', 'merged PR(s) changed', 'github-actions[bot]', '2026-07-26T00:00:00Z'); + +COMMIT; \ No newline at end of file From 6fef0735c6a5c13040d5b2198db2c1da53a48525 Mon Sep 17 00:00:00 2001 From: Sarah Littlejohn Date: Mon, 27 Jul 2026 09:58:39 +0000 Subject: [PATCH 2/2] chore(requirements): fold in REQ-0098 approved -> verified The 2026-07-26 sync run dropped the REQ-0098 (#342) approved -> verified status change that the prior 2026-07-25 run (PR #877) had captured. Fold it into this migration so #881 fully supersedes #877, then #877 can be closed. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../migrations/010_sync_github_2026_07_26.sql | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/requirements/migrations/010_sync_github_2026_07_26.sql b/requirements/migrations/010_sync_github_2026_07_26.sql index eb97555f7..9b1d618fb 100644 --- a/requirements/migrations/010_sync_github_2026_07_26.sql +++ b/requirements/migrations/010_sync_github_2026_07_26.sql @@ -11,13 +11,15 @@ -- Delta captured (gate = "Refined Tickets" and beyond): -- * 3 NEW requirements (REQ-0157..REQ-0159): -- #593, #699, #859 --- * 1 status change: +-- * 2 status changes: +-- REQ-0098 (#342): approved -> verified -- REQ-0099 (#343): implemented -> verified -- * 1 impl change (combined with status change above): -- REQ-0099 (#343): impl_commit_sha and impl_paths populated -- --- HUMAN REVIEW REQUIRED: Board access unavailable; verify the 3 new issues are --- actually past "Refined Tickets" on the CaTH Kanban before merging. +-- HUMAN REVIEW REQUIRED: Board access unavailable; verify the 3 new issues and +-- 2 status changes are actually past "Refined Tickets" on the CaTH Kanban before +-- merging. BEGIN TRANSACTION; @@ -343,6 +345,18 @@ All four have `isNonStrategic: false`, `provenance: "CFT_IDAM"`, and `defaultSen - The referenced `pht-weekly-hearing-list` (#645) reference implementation does not exist in this repo; the nearest JSON reference is `care-standards-tribunal-weekly-hearing-list` — but that is a JSON/Excel list and is **not** the model for these flat-file lists. ', 'functional', 'verified', NULL, 'story', 859, 'https://github.com/hmcts/cath-service/issues/859', 'c74ad165fc754ea590a19d844d162381cec3cf9d', '["apps/postgres/prisma/scripts/001_insert_missing_list_types.sql", "apps/postgres/prisma/scripts/003_upsert_sub_jurisdictions_and_list_type_links.sql", "libs/list-types/common/src/list-type-data.test.ts", "libs/list-types/common/src/list-type-data.ts"]', '2026-07-15T08:49:48Z', '2026-07-15T08:49:48Z', 'junaidiqbalmoj', 'junaidiqbalmoj'); +-- ============================================================================ +-- STATUS CHANGE: REQ-0098 (#342) approved -> verified +-- ============================================================================ + +-- Issue closed as COMPLETED on 2026-07-22 (no merged PR — administrative close). +UPDATE requirement +SET status = 'verified', + version = version + 1, + updated_at = '2026-07-26T00:00:00Z', + updated_by = 'github-actions[bot]' +WHERE id = 98; + -- ============================================================================ -- STATUS + IMPL CHANGE: REQ-0099 (#343) implemented -> verified -- ============================================================================ @@ -368,6 +382,12 @@ VALUES (158, 1, 'created', 'imported from GitHub issue', 'github-actions[bot]', '2026-06-10T13:46:48Z'), (159, 1, 'created', 'imported from GitHub issue', 'github-actions[bot]', '2026-07-15T08:49:48Z'); +-- Status change entry for REQ-0098 (#342). +INSERT INTO requirement_change + (requirement_id, version, field, old_value, new_value, change_type, change_summary, changed_by, changed_at) +VALUES + (98, 2, 'status', 'approved', 'verified', 'status_changed', 'board status moved', 'github-actions[bot]', '2026-07-26T00:00:00Z'); + -- Status + impl change entries for REQ-0099 (#343). INSERT INTO requirement_change (requirement_id, version, field, old_value, new_value, change_type, change_summary, changed_by, changed_at)