Skip to content

New: [AEA-6543] - Create new unattended release dispensing endpoint#4523

Open
wildjames wants to merge 19 commits intomasterfrom
aea-6453-new-unattended-download-endpoint
Open

New: [AEA-6543] - Create new unattended release dispensing endpoint#4523
wildjames wants to merge 19 commits intomasterfrom
aea-6453-new-unattended-download-endpoint

Conversation

@wildjames
Copy link
Copy Markdown
Contributor

Summary

  • ✨ New Feature

Details

The release endpoint supporting two distinct modes will be confusing - application restricted access does not require the practitioner details, but user-restricted does.

I'm breaking it up into two endpoints. I've refactored the handler function to take a boolean argument that enables or disables the check for practitioner details, and I'm updating the OAS spec to host both endpoints.

The copy is subject to change. Currently, I've mostly copy-pasted, and added in the $release-unattended wherever $release is referenced.

…h it between application restricted or user restricted. Then, update the OAS spec to host the two endpoints.
Copilot AI review requested due to automatic review settings April 1, 2026 14:58
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

This PR is linked to a ticket in an NHS Digital JIRA Project. Here's a handy link to the ticket:

AEA-6543

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR splits the dispensing release interaction into two endpoints to reduce confusion between user-restricted vs application-restricted access, and updates the coordinator validation plus API specifications accordingly.

Changes:

  • Added a new POST /Task/$release-unattended endpoint alongside the existing POST /Task/$release.
  • Refactored coordinator release routing/validation to optionally allow application-restricted scope checks for nominated (no group-identifier) downloads.
  • Updated OAS/spec docs (and Postman collection) to include and describe the new endpoint.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
postman/dispensing_collection.json Updates nominated release request to call $release-unattended.
packages/specification/fhir-dispensing.yaml Adds $release-unattended path and references it across error tables/publication metadata.
packages/specification/electronic-prescription-service-api.yaml Documents application-restricted access mode and adds $release-unattended path entry.
packages/specification/electronic-prescription-service-api.template.yaml Template doc updates to reflect $release-unattended and access-mode wording.
packages/coordinator/tests/services/validation/parameters-validator.spec.ts Updates/extends scope validation tests for nominated release + application-restricted option.
packages/coordinator/src/services/validation/parameters-validator.ts Adds options object to verifyParameters and gates scope validation based on allowApplicationRestricted.
packages/coordinator/src/routes/dispense/release.ts Introduces shared handler factory and registers new $release-unattended route.

Comment on lines +32 to +35
const prescriptionIdParameter = getIdentifierParameterOrNullByName(parameters.parameter, "group-identifier")
const permissionErrors = prescriptionIdParameter
? validatePermittedAttendedDispenseMessage(scope)
: validatePermittedUnattendedDispenseMessage(scope)
const permissionErrors = !prescriptionIdParameter && allowApplicationRestricted
? validatePermittedUnattendedDispenseMessage(scope)
: validatePermittedAttendedDispenseMessage(scope)
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

allowApplicationRestricted changes which scope validator runs, but the rest of verifyParameters still enforces the attended/user-restricted agent requirements (e.g. it always reads the agent parameter and requires PractitionerRole.telecom). If application-restricted release is meant to work without practitioner details (per PR description), this function needs to skip/relax agent/practitioner validation when application-restricted access is being used (or when allowApplicationRestricted + app scope is detected).

Copilot uses AI. Check for mistakes.
Comment on lines +71 to 80
{
method: "POST" as RouteDefMethods,
path: `${BASE_PATH}/Task/$release`,
handler: createReleaseHandler(false)
},
{
method: "POST" as RouteDefMethods,
path: `${BASE_PATH}/Task/$release-unattended`,
handler: createReleaseHandler(true)
}
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The new /Task/$release-unattended route introduces new behavior (separate endpoint + application-restricted support), but there are no route-level tests covering that this path is registered and behaves as expected (e.g. scope handling and audit hash logging). Please add coverage similar to existing /Task/$release route tests so regressions are caught.

Copilot generated this review using guidance from repository custom instructions.
Comment on lines 192 to 200
test("accepts nominated release when unattended application-restricted access is enabled", () => {
const result = verifyParameters(
validAttendedNominatedParameters,
DISPENSING_APP_SCOPE,
"test_sds_user_id",
"test_sds_role_id",
{allowApplicationRestricted: true, checkAccessTokenSDSRoleID: false}
)
expect(result).toEqual([])
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The new tests exercise application-restricted scope handling, but they don't cover the key contract change described in the PR (that application-restricted requests can omit practitioner details). Consider adding a test case where the release-unattended/application-restricted flow succeeds without PractitionerRole.practitioner and/or telecom (and ensure the validator implements that behavior).

Copilot generated this review using guidance from repository custom instructions.
Comment thread packages/specification/fhir-dispensing.yaml Outdated
Comment thread packages/specification/electronic-prescription-service-api.yaml
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 20 out of 20 changed files in this pull request and generated 8 comments.

Comment thread packages/specification/schemas/requests/dispensing/Release.yaml
Comment thread packages/specification/fhir-dispensing.yaml
Comment thread postman/dispensing_collection.json Outdated
Comment thread azure/templates/run_tests.yml
Comment thread .github/workflows/run_regression_tests.yml
Comment thread packages/specification/schemas/requests/dispensing/Release.yaml
…lease endpoints. These are the cases I think are useful but I'm not convinced how necessary they are. Better safe than sorry though
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 7, 2026

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.

2 participants