Skip to content

SPRDT-987: listing.command.move-hearing-to-past-date wrapper (MAGS via courtscheduler, CROWN listing-side)#22

Open
ozturkmenb wants to merge 7 commits into
dev/pasthearingssnapshotfrom
dev/SPRDT-987-pasthearings
Open

SPRDT-987: listing.command.move-hearing-to-past-date wrapper (MAGS via courtscheduler, CROWN listing-side)#22
ozturkmenb wants to merge 7 commits into
dev/pasthearingssnapshotfrom
dev/SPRDT-987-pasthearings

Conversation

@ozturkmenb

@ozturkmenb ozturkmenb commented Jul 2, 2026

Copy link
Copy Markdown

Jira link

See https://tools.hmcts.net/jira/browse/SPRDT-987

Change description

Re-lands the move-hearing-to-past-date wrapper cleanly for shipment ahead of Crown Phase 2. Ported from archived-repo PR #909 — only its three real commits (fbe4e705a, 168d669a0, bf047bd35); the rest of that branch was team/ccsph2n contamination.

  • New content-type action listing.command.move-hearing-to-past-date on the existing POST /hearings/{hearingId} resource. Request: hearingId, courtCentreId, startDate (single-day).
  • Own permission "Change hearing to past date"/"Link" (createChangeHearingToPastDatePermission()) — the first hasPermission-based DRL rule in listing command-api.
  • Hearing-existence pre-check → 422 HEARING_ID_NOT_FOUND, no event sent (was in the original ACs but never implemented in PR #909).
  • MAGISTRATES: synchronous courtscheduler call (courtscheduler.move-hearing-to-past-date); on 2xx the enriched command re-issues the hearing day on the past date (changeStartDate + assignHearingDaysV2) carrying courtScheduleId/room/times — the court-schedule event alone cannot re-date a day (its projection matches days by date). On courtscheduler 422/404 the error is surfaced and no event is sent.
  • CROWN: listing-side-only date move — courtscheduler is never called (no CROWN courtschedule before Phase 2); past-only enforced in listing (422 FUTURE_DATE_NOT_ALLOWED). The hearing day re-dates too (follow-up f7c325ec/675ed2de): command-api rebuilds the day from the hearing's own current first day (same room, time-of-day and duration re-anchored onto the past date) and the handler applies changeStartDate + assignHearingDaysV2, mirroring the MAGS composition minus the courtschedule. endTime is always computed (startTime + duration) — the hearing-days-changed-for-hearing item schema requires it.
  • New plumbing this branch lacked: ListingCommandCommonProviders (@Specializes DefaultCommonProviders) + MoveHearingToPastDateExceptionMapper (422/404 rendering), purpose-built MoveHearingToPastDateResult DTO (replaces the ccsph2n-only CrownFallbackResult).

Stacked on #21 (dev/pasthearingssnapshot); retarget to team/pasthearings once #21 merges. Courtscheduler counterpart: hmcts/cpp-context-listing-courtscheduler#849.

Testing done

  • mvn clean install green (new: api 37, handler 83, adapter/mapper/permission/lookup suites).
  • ./runIntegrationTests.sh green: 230/230 (3 pre-existing skips) including new MoveHearingToPastDateIT 8/8 — MAGS happy path stores the moved day's courtScheduleId, re-move releases prior allocation, courtscheduler 422/404 propagated with no event, unknown hearingId 422, missing field 400, CROWN moved listing-side with the courtscheduler stub verifiably never called, CROWN future-date 422.
  • SonarQube quality gate: OK.

CVE Suppression: Are there any CVEs present in the codebase (either newly introduced or pre-existing) that are being intentionally suppressed or ignored by this commit?

  • Yes
  • No

…eduler, CROWN listing-side, past-only)

Adds listing.command.move-hearing-to-past-date as a new content-type action on the
existing POST /hearings/{hearingId} resource. ListingCommandApi resolves the hearing
from the listing viewstore (new HearingLookupService, mirroring the existing
command.service.HearingService query-view lookup pattern) and rejects unknown
hearingIds with 422 HEARING_ID_NOT_FOUND before anything is sent.

MAGISTRATES hearings call courtscheduler synchronously via
CourtSchedulerServiceAdapter.moveHearingToPastDate (new HearingSlotsService POST to
/hearings/{hearingId}, application/vnd.courtscheduler.move-hearing-to-past-date+json);
a 2xx response enriches the command with a purpose-built MoveHearingToPastDateResult
and the enriched handler applies it via the existing
raiseHearingDayCourtSchedulesUpdated/HearingDayCourtScheduleUpdated event. A non-2xx
response raises MoveHearingToPastDateException, rendered as 422/404 by the new
MoveHearingToPastDateExceptionMapper (registered via the new
ListingCommandCommonProviders @specializes DefaultCommonProviders) - no event is sent.

CROWN hearings never call courtscheduler (Baris decision D1): the command-api
validates past-only (422 FUTURE_DATE_NOT_ALLOWED) and the enriched handler re-dates
the hearing purely listing-side by reusing the existing Hearing.changeStartDate
aggregate method (StartDateChangedForHearing event) - no new domain event needed.

Permission: PermissionConstants.createChangeHearingToPastDatePermission() (object
"Change hearing to past date", action "Link") plus a DRL rule using
userAndGroupProvider.hasPermission(...).

Adds MoveHearingToPastDateIT plus CourtSchedulerServiceStub/WireMockStubUtils
extensions and MAGS/CROWN test-data fixtures.
…(changeStartDate + assignHearingDaysV2) - the court-schedule event alone cannot re-date a day
…s (S3776), reuse adapter constants (S1192), transient responseBody (S1948)
@ozturkmenb ozturkmenb requested a review from a team as a code owner July 2, 2026 19:56
@cpp-github-management

Copy link
Copy Markdown

Passed

…t from the hearing's own room/time on the past date
… requires it); carry existing endTime for CROWN
@cpp-github-management

Copy link
Copy Markdown

Passed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant