From a40a4c020109ea7911db37d8ab7d0057b7f93b7b Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Thu, 15 Aug 2024 15:33:12 +0000 Subject: [PATCH 1/4] PI-2374 Migrate OpenAPI yaml to annotations --- .github/workflows/generate-api-docs.yml | 33 + .../workflows/generate-plantuml-diagrams.yml | 2 +- Makefile | 11 +- README.md | 13 +- build.gradle.kts | 1 + docs/adr/0011-openapi-revision.md | 29 + openapi.yml | 3230 ----------------- .../config/OpenAPIConfig.kt | 111 + .../controllers/v1/ConfigController.kt | 4 +- .../v1/EPFPersonDetailController.kt | 20 + .../controllers/v1/HmppsIdController.kt | 7 +- .../controllers/v1/ImageController.kt | 14 + .../v1/RiskManagementController.kt | 28 +- .../v1/person/AddressController.kt | 23 +- .../v1/person/AdjudicationsController.kt | 24 +- .../controllers/v1/person/AlertsController.kt | 39 +- .../v1/person/CaseNotesController.kt | 21 +- .../v1/person/CellLocationController.kt | 11 +- .../v1/person/DynamicRisksController.kt | 25 +- .../v1/person/LicenceConditionController.kt | 23 +- .../v1/person/MappaDetailController.kt | 23 +- .../controllers/v1/person/NeedsController.kt | 28 +- .../v1/person/OffencesController.kt | 75 +- .../controllers/v1/person/PersonController.kt | 79 +- .../PersonResponsibleOfficerController.kt | 23 +- .../ProtectedCharacteristicsController.kt | 23 +- .../v1/person/RiskCategoriesController.kt | 23 +- .../person/RiskPredictorScoresController.kt | 24 +- .../v1/person/RiskSeriousHarmController.kt | 23 +- .../v1/person/SentencesController.kt | 39 +- .../v1/person/StatusInformationController.kt | 25 +- .../ConsumerNameExtractionFilter.kt | 15 + .../models/hmpps/Address.kt | 16 + .../hmppsintegrationapi/models/hmpps/Alert.kt | 11 + .../hmppsintegrationapi/models/hmpps/Alias.kt | 7 + .../models/hmpps/CaseDetail.kt | 3 + .../models/hmpps/CaseNote.kt | 12 + .../models/hmpps/CaseNoteAmendment.kt | 4 + .../hmpps/ContactDetailsWithEmailAndPhone.kt | 3 + .../models/hmpps/Disability.kt | 2 + .../models/hmpps/DynamicRisk.kt | 7 + .../models/hmpps/GeneralPredictor.kt | 14 + .../models/hmpps/GroupReconviction.kt | 14 + .../models/hmpps/Identifiers.kt | 6 + .../models/hmpps/ImageMetadata.kt | 61 + .../LatestSentenceKeyDatesAndAdjustments.kt | 6 + .../models/hmpps/MappaDetail.kt | 9 + .../hmppsintegrationapi/models/hmpps/Need.kt | 6 + .../hmppsintegrationapi/models/hmpps/Needs.kt | 2 + .../models/hmpps/NonDtoDate.kt | 13 + .../models/hmpps/OtherRisks.kt | 46 + .../models/hmpps/Person.kt | 9 + .../models/hmpps/PersonLicences.kt | 136 + .../hmpps/PersonProtectedCharacteristics.kt | 9 + .../models/hmpps/PhoneNumber.kt | 4 + .../models/hmpps/Prison.kt | 3 + .../models/hmpps/ReasonableAdjustment.kt | 6 + .../models/hmpps/ReleaseDate.kt | 13 + .../hmppsintegrationapi/models/hmpps/Risk.kt | 43 + .../models/hmpps/RiskAssessment.kt | 11 + .../models/hmpps/RiskManagementPlan.kt | 16 + .../models/hmpps/RiskOfSeriousRecidivism.kt | 14 + .../models/hmpps/RiskPredictorScore.kt | 11 + .../models/hmpps/RiskSummary.kt | 32 + .../hmppsintegrationapi/models/hmpps/Risks.kt | 2 + .../models/hmpps/Sentence.kt | 24 + .../models/hmpps/SentenceAdjustment.kt | 12 + .../models/hmpps/SentenceDate.kt | 6 + .../models/hmpps/SentenceKeyDate.kt | 4 + .../SentenceKeyDateWithCalculatedDate.kt | 4 + .../models/hmpps/SentenceLength.kt | 15 + .../models/hmpps/SentenceTerm.kt | 28 + .../models/hmpps/SexualPredictor.kt | 26 + .../models/hmpps/StatusInformation.kt | 7 + .../models/hmpps/TopupSupervision.kt | 5 + .../models/hmpps/ViolencePredictor.kt | 14 + .../util/PaginatedResponse.kt | 16 +- src/main/resources/application.yml | 3 + 78 files changed, 1463 insertions(+), 3321 deletions(-) create mode 100644 .github/workflows/generate-api-docs.yml create mode 100644 docs/adr/0011-openapi-revision.md delete mode 100644 openapi.yml create mode 100644 src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/config/OpenAPIConfig.kt diff --git a/.github/workflows/generate-api-docs.yml b/.github/workflows/generate-api-docs.yml new file mode 100644 index 000000000..602d253c3 --- /dev/null +++ b/.github/workflows/generate-api-docs.yml @@ -0,0 +1,33 @@ +name: Generate OpenAPI spec + +on: + workflow_dispatch: + push: + branches: + - main + +jobs: + generate-openapi-spec: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'temurin' + - uses: gradle/actions/setup-gradle@v4 + - name: Serve dependencies + run: make serve-dependencies + - name: Start service + run: | + ./gradlew bootRun & + timeout 300 sh -c 'until curl -s localhost:8080/v3/api-docs; do sleep 5; done' + env: + SPRING_PROFILES_ACTIVE: local + - name: Fetch API docs + run: mkdir -p openapi && curl -f localhost:8080/v3/api-docs -o openapi/api-docs.json + - name: Publish API docs + uses: JamesIves/github-pages-deploy-action@94f3c658273cf92fb48ef99e5fbc02bd2dc642b2 # v4.6.3 + with: + folder: openapi + target-folder: openapi diff --git a/.github/workflows/generate-plantuml-diagrams.yml b/.github/workflows/generate-plantuml-diagrams.yml index d50a13b68..59004d80a 100644 --- a/.github/workflows/generate-plantuml-diagrams.yml +++ b/.github/workflows/generate-plantuml-diagrams.yml @@ -13,7 +13,7 @@ jobs: env: BRANCH_NAME: ${{ github.head_ref || github.ref_name }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Install Graphviz Dependency run: | sudo apt-get install graphviz diff --git a/Makefile b/Makefile index 443aedb2a..460e8669a 100644 --- a/Makefile +++ b/Makefile @@ -2,20 +2,23 @@ authenticate-docker: ./scripts/authenticate_docker.sh build-dev: - docker-compose pull hmpps-auth - docker-compose build --no-cache + docker compose pull hmpps-auth + docker compose build build: docker build -t hmpps-integration-api . +serve-dependencies: + docker compose up hmpps-auth prism local-stack-aws --build -d + serve: build-dev - docker-compose up -d + docker compose up -d publish: ./scripts/publish.sh stop: - docker-compose down + docker compose down unit-test: ./gradlew unitTest diff --git a/README.md b/README.md index 33286f4ac..a15fbcfa4 100644 --- a/README.md +++ b/README.md @@ -88,20 +88,21 @@ minutes. ## Usage -### Running the application +### Running the application locally To run the application using IntelliJ: -1. Select the `HmppsIntegrationApi` run configuration file. -2. Click the run button. +1. Start dependencies using `make serve-dependencies` +2. Select the `HmppsIntegrationApi` run configuration file. +3. Click the run button. -To run the application using the command line: +Or, to run the application using the command line: ```bash -./gradlew bootRun +SPRING_PROFILES_ACTIVE=local ./gradlew bootRun ``` -Then visit [http://localhost:8080](http://localhost:8080). +Then visit [http://localhost:8080/swagger-ui/index.html](http://localhost:8080/swagger-ui/index.html). #### With dependent services diff --git a/build.gradle.kts b/build.gradle.kts index 77d84a8a7..4d8c63bd5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -20,6 +20,7 @@ dependencies { exclude("org.springframework.security", "spring-security-crypto") exclude("org.springframework.security", "spring-security-web") } + implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.6.0") testImplementation("io.kotest:kotest-assertions-json-jvm:5.8.0") testImplementation("io.kotest:kotest-runner-junit5-jvm:5.8.0") testImplementation("io.kotest:kotest-assertions-core-jvm:5.8.0") diff --git a/docs/adr/0011-openapi-revision.md b/docs/adr/0011-openapi-revision.md new file mode 100644 index 000000000..acddf5d9a --- /dev/null +++ b/docs/adr/0011-openapi-revision.md @@ -0,0 +1,29 @@ +# 0011 - Revert decision 0003 and auto-generate OpenAPI specification + +2024-08-16 + +## Status + +Proposed + +## Context + +In [#0003](./0003-manually-manage-openapi-file.md), the team decided to manually manage the OpenAPI specification file, as opposed to generating them from code. +This had the benefit of allowing the team to write documentation for endpoints before they have been built. +However, in practice this has resulted in an out-of-date specification due to code changes not being reflected. + +## Decision + +Revert decision 0003 and auto-generate OpenAPI specification using the [Springdoc OpenAPI library](https://springdoc.org). +When the code or annotations change, the OpenAPI specification will be generated and published automatically. +Additional documentation can be added for endpoints that have not yet been implemented, by adding a separate "draft" OpenAPI specification file. + +### Rationale +* Auto-generating OpenAPI specifications from annotations in code is consistent with the wider HMPPS approach +* Keeping documentation as close to the relevant code as possible ensures it is kept up-to-date +* Pre-existing documentation is maintained +* Additional documentation that doesn't correspond to code can be drafted separately + +## Consequences +* The existing OpenAPI yaml file will be converted into code annotations, and will be published automatically via GitHub pages. +* The tech-docs pages will be updated to reference the new location. diff --git a/openapi.yml b/openapi.yml deleted file mode 100644 index 05591d53c..000000000 --- a/openapi.yml +++ /dev/null @@ -1,3230 +0,0 @@ -openapi: 3.0.0 -info: - title: HMPPS Integration API - description: - A long-lived API that exposes data from HMPPS systems such as the National Offender Management Information - System (NOMIS), nDelius (probation system) and Offender Assessment System (OASys), providing a single point - of entry for consumers. - version: 0.0.1 - -paths: - /v1/persons: - get: - tags: - - persons - summary: Returns person(s) by search criteria, sorted by date of birth (newest first). At least one query parameter must be specified. - parameters: - - in: query - name: first_name - schema: - type: string - required: false - description: The first name of the person - - in: query - name: last_name - schema: - type: string - required: false - description: The last name of the person - - in: query - name: pnc_number - schema: - type: string - required: false - description: A URL-encoded pnc identifier - - in: query - name: date_of_birth - schema: - type: string - required: false - description: The date of birth of the person - - in: query - name: search_within_aliases - schema: - type: boolean - default: false - required: false - description: Whether to return results that match the search criteria within the aliases of a person. - - $ref: "#/components/parameters/page" - - $ref: "#/components/parameters/perPage" - responses: - "200": - description: Successfully performed the query on upstream APIs. An empty list is returned when no results are found. - content: - application/json: - schema: - type: object - properties: - data: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Person" - pagination: - $ref: "#/components/schemas/Pagination" - "400": - description: There were no query parameters passed in. At least one must be specified. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/NoQueryParametersBadRequestError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}: - get: - tags: - - persons - summary: Returns a person. - parameters: - - $ref: "#/components/parameters/hmppsId" - responses: - "200": - description: Successfully found a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: object - properties: - prisonerOffenderSearch: - $ref: "#/components/schemas/Person" - probationOffenderSearch: - $ref: "#/components/schemas/Person" - "404": - description: Failed to find a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/images: - get: - tags: - - persons - summary: Returns metadata of images associated with a person sorted by captureDateTime (newest first). - parameters: - - $ref: "#/components/parameters/hmppsId" - - $ref: "#/components/parameters/page" - - $ref: "#/components/parameters/perPage" - responses: - "200": - description: > - Successfully found a person with the provided HMPPS ID. - If a person doesn't have any images, then an empty list (`[]`) is - returned in the `data` property. - content: - application/json: - schema: - type: object - properties: - data: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Image" - pagination: - $ref: "#/components/schemas/Pagination" - "404": - description: Failed to find a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/images/{id}: - get: - tags: - - images - summary: Returns an image in bytes as a JPEG. - parameters: - - name: id - in: path - required: true - schema: - type: string - responses: - "200": - description: Successfully found an image with the provided ID. - content: - image/jpeg: - schema: - type: string - format: byte - "404": - description: Failed to find an image with the provided ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - ImageNotFoundError: - $ref: "#/components/examples/ImageNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/addresses: - get: - tags: - - persons - summary: Returns addresses associated with a person, ordered by startDate. - parameters: - - $ref: "#/components/parameters/hmppsId" - - $ref: "#/components/parameters/page" - - $ref: "#/components/parameters/perPage" - responses: - "200": - description: Successfully found a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Address" - pagination: - $ref: "#/components/schemas/Pagination" - "404": - description: Failed to find a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/offences: - get: - tags: - - persons - summary: > - Returns offences associated with a person, ordered by startDate (newest first). - > - Note: This API does not contain the complete list of offences for a person. - Offences are retrieved from Prison and Probation systems exclusively. - Prison systems record only custodial sentences, while Probation systems record only the main offence and some additional offences for case management purposes. Other offences recorded by HMCTS and police may not be included. - parameters: - - $ref: "#/components/parameters/hmppsId" - - $ref: "#/components/parameters/page" - - $ref: "#/components/parameters/perPage" - responses: - "200": - description: Successfully found offences for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Offence" - examples: - successfulResponse: - summary: Example response with all properties and possible enum values - value: - data: - - serviceSource: NOMIS - systemSource: PRISON_SYSTEMS - cjsCode: RR84170 - courtDates: - - "2018-02-10" - - "2019-02-10" - courtName: "London Magistrates Court" - description: "Commit an act / series of acts with intent to pervert the course of public justice" - endDate: "2018-03-10" - hoCode: 06601 - startDate: "1965-12-01" - statuteCode: RR84 - - serviceSource: NDELIUS - systemSource: PROBATION_SYSTEMS - cjsCode: RR12345 - courtDates: - - "2020-05-15" - - "2021-05-15" - courtName: "Manchester Crown Court" - description: "Assault causing grievous bodily harm" - endDate: "2020-06-20" - hoCode: 06602 - startDate: "2020-05-10" - statuteCode: RR85 - pagination: - $ref: "#/components/schemas/Pagination" - "404": - description: Failed to find offences a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/alerts: - get: - tags: - - persons - - alerts - summary: Returns alerts associated with a person, sorted by dateCreated (newest first). - parameters: - - $ref: "#/components/parameters/hmppsId" - - $ref: "#/components/parameters/page" - - $ref: "#/components/parameters/perPage" - responses: - "200": - description: Successfully found alerts for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Alert" - pagination: - $ref: "#/components/schemas/Pagination" - "404": - description: Failed to find alerts a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/alerts/pnd: - get: - tags: - - persons - - alerts - summary: Returns alerts associated with a person, sorted by dateCreated (newest first). - parameters: - - $ref: "#/components/parameters/hmppsId" - - $ref: "#/components/parameters/page" - - $ref: "#/components/parameters/perPage" - responses: - "200": - description: Successfully found alerts for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Alert" - pagination: - $ref: "#/components/schemas/Pagination" - "404": - description: Failed to find alerts a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/sentences: - get: - tags: - - persons - summary: Returns sentences associated with a person, sorted by dateOfSentencing (newest first). - parameters: - - $ref: "#/components/parameters/hmppsId" - - $ref: "#/components/parameters/page" - - $ref: "#/components/parameters/perPage" - responses: - "200": - description: Successfully found sentences for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Sentence" - pagination: - $ref: "#/components/schemas/Pagination" - "404": - description: Failed to find sentences a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/sentences/latest-key-dates-and-adjustments: - get: - tags: - - persons - summary: Returns the key dates and adjustments about a person's release from prison for their latest sentence. - parameters: - - $ref: "#/components/parameters/hmppsId" - responses: - "200": - description: Successfully found latest sentence key dates and adjustments for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - $ref: "#/components/schemas/LatestSentenceKeyDatesAndAdjustments" - "404": - description: Failed to find sentences a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/risks/scores: - get: - tags: - - risks - summary: Returns risk scores from the last year associated with a person, sorted by completedDate (newest first). This endpoint does not serve LAO (Limited Access Offender) data. - parameters: - - $ref: "#/components/parameters/hmppsId" - - $ref: "#/components/parameters/page" - - $ref: "#/components/parameters/perPage" - responses: - "200": - description: Successfully found risk scores for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/RiskScore" - pagination: - $ref: "#/components/schemas/Pagination" - "404": - description: Failed to find risk scores for a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/risks/categories: - get: - tags: - - persons - summary: Returns the categories related to an offender. - parameters: - - $ref: "#/components/parameters/hmppsId" - responses: - "200": - description: Successfully found risk categories for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: object - properties: - offenderNo: - type: string - assessments: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/RiskAssessment" - category: - type: string - categoryCode: - type: string - "404": - description: Failed to find risk categories a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/risks/mappadetail: - get: - tags: - - persons - summary: Returns the mappa detail related to a person. - parameters: - - $ref: "#/components/parameters/hmppsId" - responses: - "200": - description: Successfully found mappa detail for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: object - properties: - level: - type: number - example: 1 - levelDescription: - type: string - example: Description of M1 - category: - type: number - example: 2 - categoryDescription: - type: string - example: Description of M2 - startDate: - type: string - format: date - example: 2024-02-07 - reviewDate: - type: string - format: date - example: 2024-02-07 - notes: - type: string - example: "Mappa Detail for X00001" - "404": - description: Failed to find risk-related mappa detail a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/needs: - get: - tags: - - needs - summary: > - Returns criminogenic needs associated with a person. This endpoint does not serve LAO (Limited Access Offender) data. - - Note: Criminogenic needs are dynamic factors that are directly linked to criminal behaviour. Eight criminogenic needs are measured in OASys: Accommodation, Employability, Relationships, Lifestyle and Associates, Drug Misuse, Alcohol Misuse, Thinking & Behaviour and Attitudes. These are scored according to whether there is “no need”, “some need” or “severe need”, and a need is identified in a specific section based on calculations around these scores. - However, the process by which needs are assessed is changing as early as next year (2024), specifically moving to a strength-based model that seeks to identify and develop the strengths of people with convictions. As a consequence of this, the information provided by this endpoint will also change. - parameters: - - $ref: "#/components/parameters/hmppsId" - responses: - "200": - description: Successfully found criminogenic needs for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - $ref: "#/components/schemas/Needs" - "404": - description: Failed to find criminogenic needs for a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/risks/serious-harm: - get: - tags: - - risks - summary: Returns Risk of Serious Harm (ROSH) risks associated with a person. Returns only assessments completed in the last year. This endpoint does not serve LAO (Limited Access Offender) data. - parameters: - - $ref: "#/components/parameters/hmppsId" - responses: - "200": - description: Successfully found risks for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - $ref: "#/components/schemas/Risks" - "404": - description: Failed to find risks for a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/risks/dynamic: - get: - tags: - - persons - - alerts - summary: Returns dynamic risks associated with a person. - parameters: - - $ref: "#/components/parameters/hmppsId" - - $ref: "#/components/parameters/page" - - $ref: "#/components/parameters/perPage" - responses: - "200": - description: Successfully found dynamic risks for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/DynamicRisk" - pagination: - $ref: "#/components/schemas/Pagination" - "404": - description: Failed to find dynamic risks for a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/risk-management-plan: - get: - tags: - - risks - summary: Returns a list of Risk Management Plans created for the person with the provided HMPPS ID. - parameters: - - $ref: "#/components/parameters/hmppsId" - responses: - "200": - description: Successfully found risk management plans for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - $ref: "#/components/schemas/RiskManagementPlan" - "404": - description: Failed to find risk management plans for a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/epf/person-details/{hmppsId}/{eventNumber}: - get: - summary: Probation case information for the Effective Proposals Framework service - description: "

Accepts a Hmpps Id (hmppsId) and Delius Event number\n\ - \ and returns a data structure giving background information on\ - \ the probation case\n for use in the Effective Proposals Framework\ - \ system. The information is used to\n reduce the need for the\ - \ EPF user to re-key information already held in Delius.

" - parameters: - - name: hmppsId - in: path - required: true - schema: - type: string - - name: eventNumber - in: path - required: true - schema: - type: integer - format: int32 - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/CaseDetails' - "404": - description: "Failed to find a person detail with the provided hmppsId and event number in Delius." - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/adjudications: - get: - summary: Returns adjudications associated with a person, sorted by dateTimeOfIncident (newest first). - parameters: - - name: hmppsId - in: path - required: true - schema: - type: string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/Adjudication' - "404": - description: "Failed to find adjudications for the person with the provided hmppsId." - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/person-responsible-officer: - get: - summary: Returns the person responsible officer associated with a person. - parameters: - - $ref: "#/components/parameters/hmppsId" - responses: - "200": - description: Successfully found the person responsible officer for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - $ref: "#/components/schemas/PersonResponsibleOfficer" - "404": - description: Failed to find licenses for a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/licences/conditions: - get: - summary: Returns license conditions associated with a person, sorted by createdDateTime (newest first). - parameters: - - $ref: "#/components/parameters/hmppsId" - responses: - "200": - description: Successfully found licenses for a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/PersonLicencesData" - examples: - successfulResponse: - summary: Example response with all properties and possible enum values - value: - data: - hmppsId: "2008/0545166T" - offenderNumber: "Z1234ZZ" - licences: - - status: "IN_PROGRESS" - typeCode: "AP" - createdDate: "2015-09-23" - approvedDate: "2015-09-24" - updatedDate: "2015-10-23" - conditions: - - type: "Standard" - code: "5a105297-dce1-4d18-b9ea-4195b46b7594" - category: "Residence at a specific place" - condition: "You must reside at an approved address" - - type: "Custom" - code: "b457e9c3-68c6-4f5e-9bd8-c36c5b7e70fb" - category: "Contact Restrictions" - condition: "You must not contact the victim" - - status: "SUBMITTED" - typeCode: "PSS" - createdDate: "2016-01-15" - approvedDate: "2016-01-16" - updatedDate: "2016-02-15" - conditions: - - type: "Standard" - code: "5a105297-dce1-4d18-b9ea-4195b46b7594" - category: "Residence at a specific place" - condition: "You must reside at an approved address" - - status: "APPROVED" - typeCode: "AP_PSS" - createdDate: "2017-03-10" - approvedDate: "2017-03-11" - updatedDate: "2017-04-10" - conditions: - - type: "Standard" - code: "5a105297-dce1-4d18-b9ea-4195b46b7594" - category: "Residence at a specific place" - condition: "You must reside at an approved address" - - status: "ACTIVE" - typeCode: "AP" - createdDate: "2018-05-20" - approvedDate: "2018-05-21" - updatedDate: "2018-06-20" - conditions: - - type: "Custom" - code: "c97f33e3-1e50-4b28-8f71-5de3e2fbbf79" - category: "Travel Restrictions" - condition: "You must not leave the country without permission" - - status: "VARIATION_IN_PROGRESS" - typeCode: "PSS" - createdDate: "2019-07-01" - approvedDate: "2019-07-02" - updatedDate: "2019-08-01" - conditions: - - type: "Rehabilitation" - code: "a5371dd7-7f54-42b9-9c3b-35f9e8f6f1e9" - category: "Rehabilitation Program" - condition: "You must participate in a rehabilitation program" - - status: "VARIATION_SUBMITTED" - typeCode: "AP_PSS" - createdDate: "2020-09-12" - approvedDate: "2020-09-13" - updatedDate: "2020-10-12" - conditions: - - type: "Monitoring" - code: "e4a8b9cf-4a50-44a2-8a0c-5f38d2fae6f9" - category: "Electronic Monitoring" - condition: "You must comply with electronic monitoring" - - status: "VARIATION_APPROVED" - typeCode: "AP" - createdDate: "2021-11-23" - approvedDate: "2021-11-24" - updatedDate: "2021-12-23" - conditions: - - type: "Substance Abuse" - code: "d4b8b1e8-9e4e-4f6a-a2df-b41e8f8e8e8e" - category: "Alcohol Restrictions" - condition: "You must not consume alcohol" - - status: "VARIATION_REJECTED" - typeCode: "PSS" - createdDate: "2022-01-01" - approvedDate: "2022-01-02" - updatedDate: "2022-02-01" - conditions: - - type: "Association" - code: "f9e8f1c8-2f4a-4a6a-a1de-5e7e9f7d9e8f" - category: "Contact Restrictions" - condition: "You must not associate with known criminals" - "404": - description: Failed to find licenses for a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/case-notes: - get: - summary: Returns case notes associated with a person. - parameters: - - in: query - name: startDate - schema: - type: string - required: false - description: Filter case notes from this date - - in: query - name: endDate - schema: - type: string - required: false - description: Filter case notes up to this date - - in: query - name: locationId - schema: - type: string - required: false - description: Filter by the location. example MDI - - $ref: "#/components/parameters/hmppsId" - responses: - "200": - description: Successfully found case notes for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/CaseNote" - pagination: - $ref: "#/components/schemas/Pagination" - "404": - description: Failed to find case notes for a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/protected-characteristics: - get: - summary: Returns protected characteristics of a person. - parameters: - - $ref: "#/components/parameters/hmppsId" - responses: - "200": - description: Successfully found licenses for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - $ref: "#/components/schemas/PersonProtectedCharacteristics" - "404": - description: Failed to find licenses for a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" - - /v1/persons/{hmppsId}/status-information: - get: - tags: - - persons - - alerts - summary: Returns the status information associated with a person. - parameters: - - $ref: "#/components/parameters/hmppsId" - - $ref: "#/components/parameters/page" - - $ref: "#/components/parameters/perPage" - responses: - "200": - description: Successfully found status information for a person with the provided HMPPS ID. - content: - application/json: - schema: - type: object - properties: - data: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/StatusInformation" - pagination: - $ref: "#/components/schemas/Pagination" - "404": - description: Failed to find status information for a person with the provided HMPPS ID. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - PersonNotFoundError: - $ref: "#/components/examples/PersonNotFoundError" - "500": - description: An upstream service was not responding, so we cannot verify the accuracy of any data we did get. - content: - application/json: - schema: - $ref: "#/components/schemas/Error" - examples: - NoQueryParametersBadRequestError: - $ref: "#/components/examples/InternalServerError" -components: - parameters: - hmppsId: - name: hmppsId - description: A URL-encoded HMPPS identifier - example: 2008%2F0545166T - in: path - required: true - schema: - type: string - id: - name: id - description: An numeric Id - example: 2461788 - in: path - required: true - schema: - type: number - page: - name: page - in: query - schema: - type: number - minimum: 0 - default: 1 - required: false - description: The page number (starting from 1) - perPage: - name: perPage - in: query - schema: - type: number - minimum: 1 - default: 10 - required: false - description: The maximum number of results for a page - schemas: - Address: - type: object - properties: - country: - type: string - example: England - county: - type: string - example: Greater London - endDate: - type: string - example: 20 May 2023 - format: date - locality: - type: string - example: London Bridge - name: - type: string - description: Name of the building of residence - noFixedAddress: - type: boolean - example: true - description: Indicates whether the person has a permanent place of residence - number: - type: string - example: 1 - postcode: - type: string - example: SE1 1TE - startDate: - type: string - example: 1 January 2023 - format: date - street: - type: string - example: O'Meara Street - town: - type: string - example: London - types: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/AddressType" - description: < - Type or usage of address, for example `Business Address`, `Home Address`, `Work Address`. - notes: - type: string - example: This is their partner's address. - AddressType: - type: object - properties: - code: - type: string - example: BUS - description: > - Address type code, for example: `BUS`, `HOME`, `WORK`. - description: - type: string - example: Business Address - description: > - Description of address type, for example `Business Address`. - Adjudication: - type: object - properties: - incidentDetails: - $ref: '#/components/schemas/IncidentDetails' - isYouthOffender: - type: boolean - incidentRole: - $ref: '#/components/schemas/IncidentRole' - offenceDetails: - $ref: '#/components/schemas/OffenceDetail' - hearings: - type: array - items: - $ref: '#/components/schemas/Hearing' - outcomes: - type: array - items: - $ref: '#/components/schemas/Outcome' - punishments: - type: array - items: - $ref: '#/components/schemas/Punishment' - punishmentComments: - type: array - items: - $ref: '#/components/schemas/PunishmentComment' - Alert: - type: object - properties: - offenderNo: - type: string - example: Z1234ZZ - description: Offender unique reference - type: - type: string - example: X - description: Alert type - typeDescription: - type: string - example: Security - description: Alert type description - code: - type: string - example: PO - description: Alert code - codeDescription: - type: string - example: MAPPA Nominal - description: Alert code description - comment: - type: string - example: Professional lock pick - description: Alert comment - dateCreated: - type: string - format: date - example: 2014-09-23 - description: Date of the alert, which might differ from the date it was created - dateExpired: - type: string - format: date - example: 2015-09-23 - description: Date that the alert expires - expired: - type: boolean - example: true - description: Whether the alert has expired - active: - type: boolean - example: false - description: Whether the alert is active - Alias: - type: object - properties: - firstName: - type: string - example: John - description: first name - middleName: - type: string - example: Michael - nullable: true - description: middle name - lastName: - type: string - example: Marston - description: last name - dateOfBirth: - type: string - format: date - example: 1965-12-01 - description: date of birth - gender: - type: string - example: Male - description: gender - ethnicity: - type: string - example: Prefer not to say - description: ethnicity - CaseDetails: - required: - - age - - dateOfBirth - - gender - - name - type: object - properties: - nomsId: - type: string - name: - $ref: '#/components/schemas/Name' - dateOfBirth: - type: string - format: date - gender: - type: string - courtAppearance: - $ref: '#/components/schemas/CourtAppearance' - sentence: - $ref: '#/components/schemas/CaseSentence' - responsibleProvider: - $ref: '#/components/schemas/ResponsibleProvider' - ogrsScore: - type: integer - format: int64 - age: - type: integer - format: int64 - ageAtRelease: - type: integer - format: int64 - CaseNote: - type: object - properties: - caseNoteId: - type: string - example: 1234 - offenderIdentifier: - type: string - example: A1234AA - type: - type: string - example: KA - typeDescription: - type: string - example: Key Worker - subType: - type: string - example: KS - subTypeDescription: - type: string - example: Key Worker Session - CreatDateTime: - type: string - format: date - example: 2023-09-05T10:15:41 - description: Date and Time of Case Note creation - occurrenceDateTime: - type: string - format: date - example: 2023-09-05T10:15:41 - description: Date and Time of when case note contact with offender was made - text: - type: string - example: This is some text - locationId: - type: string - example: MDI - amendments: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/CaseNoteAmendment" - description: List of amendments to the case note - CaseNoteAmendment: - type: object - properties: - caseNoteAmendmentId: - type: integer - example: 123232 - format: int64 - creationDateTime: - type: string - format: date - example: 2023-09-05T10:15:41 - description: Date and Time of Case Note creation - addtionalNoteText: - type: string - example: Some Additional Text - CaseSentence: - type: object - properties: - date: - type: string - format: date - description: This field is depreciated and will be removed from the response soon. - sentencingCourt: - $ref: '#/components/schemas/Court' - releaseDate: - type: string - format: date - description: This field is depreciated and will be removed from the response soon. - expectedReleaseDate: - type: string - format: date - CourtAppearance: - required: - - date - - court - type: object - properties: - date: - type: string - format: date - court: - $ref: "#/components/schemas/CourtDetails" - CommunityOffenderManager: - type: object - properties: - name: - $ref: "#/components/schemas/PersonResponsibleOfficerName" - email: - type: string - nullable: true - telephoneNumber: - type: string - nullable: true - team: - $ref: "#/components/schemas/PersonResponsibleOfficerTeam" - ContactDetails: - properties: - phoneNumbers: - $ref: "#/components/schemas/PhoneNumbers" - emails: - type: array - items: - type: string - example: "leslie.knope@pawnee.gov" - description: A list of email addresses - Court: - type: object - properties: - name: - type: string - description: This field is depreciated and will be removed from the response soon. - Disability: - type: object - properties: - notes: - type: string - nullable: true - example: Walking issue - startDate: - type: string - format: date-time - nullable: true - example: 2013-04-11 - endDate: - type: string - format: date-time - nullable: true - example: 2023-04-11 - disabilityType: - $ref: "#/components/schemas/KeyValue" - condition: - $ref: "#/components/schemas/KeyValue" - DynamicRisk: - type: object - properties: - code: - type: string - nullable: true - example: RCCO - description: - type: string - nullable: true - example: Child Concerns - Safeguarding concerns where a child is at risk from the offender - startDate: - type: string - nullable: true - example: 2022-01-01 - reviewDate: - type: string - nullable: true - example: 2025-01-01 - notes: - type: string - nullable: true - example: This is a note - Error: - type: object - properties: - status: - type: integer - enum: - - 400 - - 404 - - 500 - errorCode: - type: integer - nullable: true - example: null - userMessage: - type: string - developerMessage: - type: string - moreInfo: - type: string - nullable: true - example: null - Hearing: - type: object - properties: - dateTimeOfHearing: - type: string - format: date-time - nullable: true - oicHearingType: - type: string - nullable: true - outcome: - nullable: true - HearingOutcome: - type: object - properties: - code: - type: string - nullable: true - details: - type: string - nullable: true - reason: - type: string - nullable: true - quashedReason: - type: string - nullable: true - canRemove: - type: boolean - nullable: true - Identifiers: - type: object - description: Other unique identifiers for a person. - properties: - nomisNumber: - type: string - example: A1234AA - description: A prisoner identifier from NOMIS. - croNumber: - type: string - example: SF80/655108T - description: A Criminal Records Office identifier from National Identification Service (NIS) or National Automated Fingerprint Identification System (NAFIS). - deliusCrn: - type: string - example: X00001 - description: A Case Reference Number from Delius. - Image: - type: object - properties: - id: - type: integer - minimum: 1 - format: int64 - example: 2461788 - description: The Image ID, in reference to a unique identifier. - active: - type: boolean - example: true - description: A flag to indicate whether an image is in active use. It is no guarantee that the latest uploaded image will be the active one. - captureDateTime: - type: string - format: date-time - example: 2015-05-27T17:13:59 - description: The Date and Time of when the image was captured. - view: - type: string - example: FACE - enum: - - FACE - - TAT - - OTH - - SCAR - - MARK - - OIC - description: > - View is the subject focus; describing the inner focus or subject of the image, normally referring to a marking, tattoo or deeper level focus of the orientation. In practise this is the interior foci of what is captured in the 'orientation' field. - Possible values are: - `FACE` - Facing, - `TAT` - Tattoo, - `OTH` - Other, - `SCAR` - Scar, - `MARK` - Mark, - `OIC` - Offence in Custody - orientation: - type: string - example: FRONT - enum: - - ANKLE - - ARM - - DAMAGE - - EAR - - ELBOW - - FACE - - FIGHT - - FINGER - - FOOT - - FRONT - - HAND - - HEAD - - INCIDENT - - INJURY - - KNEE - - LEG - - LIP - - NECK - - NOSE - - SHOULDER - - THIGH - - TOE - - TORSO - description: > - Orientation is the scope focus; describing the scope or outer focus of the image, normally referring to the highest level object of interest within the bounds of the photo itself. This is normally a body part or an angle of photography, such as a photo of someone’s facial view (`FRONT`) or arm (`ARM`). - Possible values are: - `ANKLE` - Ankle, - `ARM` - Arm, - `DAMAGE` - Damage, - `EAR` - Ear, - `ELBOW` - Elbow, - `FACE` - Face, - `FIGHT` - Fight, - `FINGER` - Finger, - `FOOT` - Foot, - `FRONT` - Front Facial View, - `HAND` - Hand, - `HEAD` - Head, - `INCIDENT` - Incident, - `INJURY` - Injury, - `KNEE` - Knee, - `LEG` - Leg, - `LIP` - Lip, - `NECK` - Neck, - `NOSE` - Nose, - `SHOULDER` - Shoulder, - `THIGH` - Thigh, - `TOE` - Toe, - `TORSO` - Torso - type: - type: string - example: OFF_BKG - enum: - - OFF_BKG - - OFF_IDM - - OIC - - PPTY - description: > - Type is the contextual focus; describing the context or scenario the image was taken within. It could be for a particular purpose or capturing the results of a particular type of incident. - Possible values are: - `OFF_BKG` - Offender Booking, - `OFF_IDM` - Offender Identification Marks, - `OIC` - Offence In Custody, - `PPTY` - Property Image - IncidentDetails: - type: object - properties: - dateTimeOfIncident: - type: string - format: date-time - nullable: true - IncidentRole: - type: object - properties: - roleCode: - type: string - nullable: true - offenceRule: - nullable: true - KeyValue: - type: object - properties: - code: - type: string - nullable: true - example: Code - description: - type: string - nullable: true - example: Description - LatestSentenceKeyDatesAndAdjustments: - type: object - properties: - adjustments: - $ref: "#/components/schemas/SentenceAdjustments" - automaticRelease: - $ref: "#/components/schemas/SentenceKeyDate" - conditionalRelease: - $ref: "#/components/schemas/SentenceKeyDate" - dtoPostRecallRelease: - $ref: "#/components/schemas/SentenceKeyDate" - earlyTerm: - $ref: "#/components/schemas/SentenceKeyDateWithCalculatedDate" - homeDetentionCurfew: - $ref: "#/components/schemas/HomeDetentionCurfewDate" - lateTerm: - $ref: "#/components/schemas/SentenceKeyDateWithCalculatedDate" - licenceExpiry: - $ref: "#/components/schemas/SentenceKeyDateWithCalculatedDate" - midTerm: - $ref: "#/components/schemas/SentenceKeyDateWithCalculatedDate" - nonDto: - $ref: "#/components/schemas/NonDtoDate" - nonParole: - $ref: "#/components/schemas/SentenceKeyDate" - paroleEligibility: - $ref: "#/components/schemas/SentenceKeyDateWithCalculatedDate" - postRecallRelease: - $ref: "#/components/schemas/SentenceKeyDate" - release: - $ref: "#/components/schemas/ReleaseDate" - sentence: - $ref: "#/components/schemas/SentenceDate" - topupSupervision: - $ref: "#/components/schemas/TopupSupervision" - actualParoleDate: - type: string - format: date - example: 2023-03-01 - description: the offender's actual parole date - earlyRemovalSchemeEligibilityDate: - type: string - format: date - example: 2023-03-01 - description: the date on which offender will be eligible for early removal (under the Early Removal Scheme for foreign nationals). - releaseOnTemporaryLicenceDate: - type: string - format: date - example: 2023-03-01 - description: the date on which offender will be released on temporary licence. - tariffDate: - type: string - format: date - example: 2023-03-01 - description: date on which minimum term is reached for parole (indeterminate/life sentences). - tariffEarlyRemovalSchemeEligibilityDate: - type: string - format: date - example: 2023-03-01 - description: tariffEarlyRemovalSchemeEligibilityDate. - Licence: - type: object - properties: - status: - type: string - enum: - - IN_PROGRESS - - SUBMITTED - - APPROVED - - ACTIVE - - VARIATION_IN_PROGRESS - - VARIATION_SUBMITTED - - VARIATION_APPROVED - - VARIATION_REJECTED - example: IN_PROGRESS - description: > - Licence status. Possible values are: - `IN_PROGRESS`, - `SUBMITTED`, - `APPROVED`, - `ACTIVE`, - `VARIATION_IN_PROGRESS`, - `VARIATION_SUBMITTED`, - `VARIATION_APPROVED`, - `VARIATION_REJECTED` - typeCode: - type: string - example: AP - enum: - - AP - - PSS - - AP_PSS - description: > - The type of licence. Possible values are: - `AP`, - `PSS`, - `AP_PSS` - createdDate: - type: string - format: date - example: 2015-09-23 - description: The date and time when the version/variation of the licence was created at - approvedDate: - type: string - format: date - example: 2015-09-24 - description: The date and time that the prison approved the licence, where licences approved before 01/04/2023 will not have an approved time - updatedDate: - type: string - format: date - example: 2015-10-23 - description: The date and time that the licence was last updated - conditions: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/LicenceCondition" - description: list of conditions. The type of conditions on a licence which can be AP (All Purpose) and/or PSS (Post Sentence Supervision) - LicenceCondition: - type: object - properties: - type: - type: string - example: Standard - nullable: true - description: Condition type - code: - type: string - example: 5a105297-dce1-4d18-b9ea-4195b46b7594 - nullable: true - description: The code shared by all instances of this condition - category: - type: string - example: Residence at a specific place - nullable: true - description: The category to which the condition belongs - condition: - type: string - example: You must not enter the location X - nullable: true - description: The condition of a licence, this can be a standard condition, a combination of inputted text and template text including any user input or the input for the bespoke condition - Name: - required: - - forename - - surname - type: object - properties: - forename: - type: string - middleName: - type: string - surname: - type: string - Offence: - type: object - properties: - serviceSource: - type: string - enum: - - NOMIS - - NDELIUS - example: NOMIS - description: > - Which upstream API service the sentence originates from. Possible values are: - `NOMIS`, - `NDELIUS` - systemSource: - type: string - enum: - - PRISON_SYSTEMS - - PROBATION_SYSTEMS - example: PROBATION_SYSTEMS - description: > - Which upstream API system the sentence originates from. Possible values are: - `PRISON_SYSTEMS`, - `PROBATION_SYSTEMS` - cjsCode: - type: string - example: RR84170 - description: Criminal Justice System offence code - # Court dates has been documented as single string, however it's actually a list of strings. This has been done - # in order to temporarily fix a rendering issue in our API docs whilst we look for a longer term solution for it. - courtDates: - type: string - format: date - description: Court dates associated with offences - example: - - "2018-02-10" - - "2019-02-10" - courtName: - type: string - description: The court name - example: "London Magistrates Court" - description: - type: string - example: Commit an act / series of acts with intent to pervert the course of public justice - description: Description associated with the CJS offence code - endDate: - type: string - format: date - example: 2018-03-10 - description: End date of range over which the offence was believed to have taken place - hoCode: - type: string - example: 06601 - description: Home Office code (HO Code) - startDate: - type: string - format: date - example: 1965-12-01 - description: Date the offence took place or start date if the offence occurred over a period of time - statuteCode: - type: string - example: RR84 - description: Statute code - OffenceDetail: - type: object - properties: - offenceCode: - type: number - nullable: true - offenceRule: - nullable: true - OffenceRuleDetails: - type: object - properties: - paragraphNumber: - type: string - nullable: true - paragraphDescription: - type: string - nullable: true - Outcome: - type: object - properties: - code: - type: string - nullable: true - details: - type: string - nullable: true - reason: - type: string - nullable: true - quashedReason: - type: string - nullable: true - canRemove: - type: boolean - nullable: true - Pagination: - type: object - properties: - isLastPage: - type: boolean - example: true - description: Is the current page the last one? - count: - type: integer - example: 1 - description: The number of results in `data` for the current page - page: - type: integer - example: 1 - description: The current page number - perPage: - type: integer - example: 10 - description: The maximum number of results in `data` for a page - totalCount: - type: integer - example: 1 - description: The total number of results in `data` across all pages - totalPages: - type: integer - example: 1 - description: The total number of pages - Person: - type: object - properties: - firstName: - type: string - example: Arthur - description: First name - middleName: - type: string - example: John - nullable: true - description: Middle name - lastName: - type: string - example: Morgan - description: Last name - dateOfBirth: - type: string - format: date - example: 1965-12-01 - description: Date of birth - gender: - type: string - example: Male - description: Gender - ethnicity: - type: string - example: "White: Eng./Welsh/Scot./N.Irish/British" - nullable: true - description: Ethnicity - aliases: - type: array - items: - $ref: "#/components/schemas/Alias" - description: List of aliases - identifiers: - $ref: "#/components/schemas/Identifiers" - pncId: - type: string - description: An identifier from the Police National Computer (PNC) - hmppsId: - type: string - example: 2008/0545166T - description: Hmpps identifier - contactDetails: - $ref: "#/components/schemas/ContactDetails" - PersonResponsibleOfficerName: - type: object - properties: - forename: - type: string - nullable: true - surname: - type: string - nullable: true - CourtDetails: - required: - - name - type: object - properties: - name: - type: string - example: "Manchester Crown Court" - description: The name of the court. - PersonResponsibleOfficerTeam: - type: object - properties: - code: - type: string - nullable: true - description: - type: string - nullable: true - email: - type: string - nullable: true - telephoneNumber: - type: string - nullable: true - PhoneNumbers: - type: array - items: - type: object - properties: - number: - type: string - example: "079123456789" - description: "A phone number" - type: - type: string - example: "TELEPHONE" - description: "The type of number" - PersonResponsibleOfficer: - type: object - properties: - prisonOffenderManager: - $ref: "#/components/schemas/PrisonOffenderManager" - communityOffenderManager: - $ref: "#/components/schemas/CommunityOffenderManager" - PersonLicencesData: - type: object - properties: - data: - $ref: "#/components/schemas/PersonLicences" - PersonLicences: - type: object - properties: - hmppsId: - type: string - example: 2008/0545166T - description: A CRN identifier - offenderNumber: - type: string - example: Z1234ZZ - nullable: true - description: The prison identifier for the person on the licence. Also known as the NOMIS ID - licences: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Licence" - description: list of licences - PersonProtectedCharacteristics: - type: object - properties: - age: - type: number - nullable: false - example: 35 - description: Age of the person - gender: - type: string - nullable: true - example: Female - description: Gender of the person - sexualOrientation: - type: string - nullable: true - example: Unknown - description: Sexual orientation of the person - ethnicity: - type: string - nullable: true - example: "White: Eng./Welsh/Scot./N.Irish/British" - description: Ethnicity of the person - nationality: - type: string - nullable: true - example: "Egyptian" - description: Nationality of the person - religion: - type: string - nullable: true - example: "Church of England (Anglican)" - description: Religion of the person - maritalStatus: - type: string - nullable: true - example: "Widowed" - description: Marital status of the person - disabilities: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Disability" - reasonableAdjustments: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/ReasonableAdjustment" - Prison: - type: object - properties: - code: - type: string - nullable: true - description: The prison code, which is usually short for the prison name. - PrisonOffenderManager: - type: object - properties: - forename: - type: string - nullable: true - surname: - type: string - nullable: true - prison: - $ref: "#/components/schemas/Prison" - Punishment: - type: object - properties: - type: - type: string - nullable: true - privilegeType: - type: string - nullable: true - otherPrivilege: - type: string - nullable: true - schedule: - nullable: true - PunishmentComment: - type: object - properties: - comment: - type: string - nullable: true - reasonForChange: - type: string - nullable: true - dateTime: - type: string - format: date-time - nullable: true - PunishmentSchedule: - type: object - properties: - days: - type: number - nullable: true - startDate: - type: string - format: date - nullable: true - endDate: - type: string - format: date - nullable: true - suspendedUntil: - type: string - format: date - nullable: true - ResponsibleProvider: - required: - - code - - name - type: object - properties: - code: - type: string - name: - type: string - Sentence: - type: object - properties: - serviceSource: - type: string - enum: - - NOMIS - - NDELIUS - example: NOMIS - description: > - Which upstream API service the sentence originates from. Possible values are: - `NOMIS`, - `NDELIUS` - systemSource: - type: string - enum: - - PRISON_SYSTEMS - - PROBATION_SYSTEMS - example: PROBATION_SYSTEMS - description: > - Which upstream API system the sentence originates from. Possible values are: - `PRISON_SYSTEMS`, - `PROBATION_SYSTEMS` - dateOfSentencing: - type: string - format: date - example: 2009-09-09 - description: Date of sentencing - description: - type: string - example: Young Offender Inst - >=12 mths - description: Description of the sentence - isActive: - type: boolean - example: true - description: Whether the sentence is active - isCustodial: - type: boolean - example: true - description: Whether the sentence is a custodial sentence - fineAmount: - type: number - example: 480.59 - description: The amount of fine related to the sentence and offence - length: - $ref: "#/components/schemas/SentenceLength" - SentenceAdjustments: - type: object - properties: - additionalDaysAwarded: - type: integer - example: 10 - description: Number of additional days awarded - unlawfullyAtLarge: - type: integer - example: 16 - description: Number unlawfully at large days - lawfullyAtLarge: - type: integer - example: 11 - description: Number of lawfully at large days - restoredAdditionalDaysAwarded: - type: integer - example: 20 - description: Number of restored additional days awarded - specialRemission: - type: integer - example: 14 - description: Number of special remission days - recallSentenceRemand: - type: integer - example: 7 - description: Number of recall sentence remand days - recallSentenceTaggedBail: - type: integer - example: 19 - description: Number of recall sentence tagged bail days - remand: - type: integer - example: 3 - description: Number of remand days - taggedBail: - type: integer - example: 13 - description: Number of tagged bail days - unusedRemand: - type: integer - example: 13 - description: Number of tagged bail days - SentenceKeyDateWithCalculatedDate: - type: object - properties: - date: - type: string - format: date - example: 2023-03-01 - description: release date for offender - overrideDate: - type: string - format: date - example: 2023-03-01 - description: release override date for offender - calculatedDate: - type: string - format: date - example: 2023-03-01 - description: release calculated date for offender - SentenceKeyDate: - type: object - properties: - date: - type: string - format: date - example: 2023-03-01 - description: release date for offender - overrideDate: - type: string - format: date - example: 2023-03-01 - description: release override date for offender - HomeDetentionCurfewDate: - type: object - properties: - actualDate: - type: string - format: date - example: 2023-03-01 - description: the offender's actual home detention curfew date. - eligibilityCalculatedDate: - type: string - format: date - example: 2023-03-01 - description: date on which offender will be eligible for home detention curfew (calculated). - eligibilityDate: - type: string - format: date - example: 2023-03-01 - description: date on which offender will be eligible for home detention curfew. - eligibilityOverrideDate: - type: string - format: date - example: 2023-03-01 - description: date on which offender will be eligible for home detention curfew (override). - endDate: - type: string - format: date - example: 2023-03-01 - description: Offender's home detention curfew end date - calculated as one day before the releaseDate. - NonDtoDate: - type: object - properties: - date: - type: string - format: date - example: 2023-03-01 - description: > - Release date for non-DTO sentence (if applicable). This will be based on one of ARD, CRD, NPD or PRRD. - NonDto stands for Non-Detention training order. - releaseDateType: - type: string - enum: - - ARD - - CRD - - NPD - - PRRD - example: ARD - description: > - Indicates which type of non-DTO release date is the effective release date. One of 'ARD', 'CRD', 'NPD' or 'PRRD'. Possible values are: - `ARD`, - `CRD`, - `NPD`, - `PRRD` - ReasonableAdjustment: - type: object - properties: - treatmentCode: - type: string - nullable: true - example: "WHEELCHR_ACC" - description: MTreatment Code - commentText: - type: string - nullable: true - example: "abcd" - description: Comment Text - startDate: - type: string - format: date-time - nullable: true - example: 2013-04-11 - endDate: - type: string - format: date-time - nullable: true - example: 2023-04-11 - treatmentDescription: - type: string - nullable: true - example: "Wheelchair accessibility" - description: Treatment Description - ReleaseDate: - type: object - properties: - date: - type: string - format: date - example: 2023-03-01 - description: > - Confirmed, actual, approved, provisional or calculated release date for offender, according to offender release date algorithm. - - Algorithm - If there is a confirmed release date, the offender release date is the confirmed release date. - If there is no confirmed release date for the offender, the offender release date is either the actual parole date or the home detention curfew actual date. - If there is no confirmed release date, actual parole date or home detention curfew actual date for the offender, the release date is the later of the nonDtoReleaseDate or midTermDate value (if either or both are present) - confirmedDate: - type: string - format: date - example: 2023-03-01 - description: Confirmed release date for offender. - SentenceDate: - type: object - properties: - effectiveEndDate: - type: string - format: date - example: 2023-03-01 - description: Effective sentence end date. - expiryCalculatedDate: - type: string - format: date - example: 2023-03-01 - description: date on which sentence expired (as calculated by NOMIS). - expiryDate: - type: string - format: date - example: 2023-03-01 - description: date on which sentence expires. - expiryOverrideDate: - type: string - format: date - example: 2023-03-01 - description: date on which sentence expires (override). - startDate: - type: string - format: date - example: 2023-03-01 - description: Sentence start date. - TopupSupervision: - type: object - properties: - expiryCalculatedDate: - type: string - format: date - example: 2023-03-01 - description: (calculated) - top-up supervision expiry date for offender. - expiryDate: - type: string - format: date - example: 2023-03-01 - description: top-up supervision expiry date for offender. - expiryOverrideDate: - type: string - format: date - example: 2023-03-01 - description: (override) - top-up supervision expiry date for offender. - startDate: - type: string - format: date - example: 2023-03-01 - description: Top-up supervision start date for offender - calculated as licence end date + 1 day or releaseDate if licence end date not set. - SentenceLength: - type: object - properties: - duration: - type: integer - example: 10 - description: Duration of the sentence - units: - type: string - enum: - - Hours - - Days - - Weeks - - Months - - Years - example: Hours - description: > - Time unit that is used in combination with the duration field. Possible values are: - `Hours`, - `Days`, - `Weeks`, - `Months`, - `Years` - terms: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/SentenceTerm" - SentenceTerm: - type: object - properties: - years: - type: integer - example: 5 - description: Number of years in the term - months: - type: integer - example: 4 - description: Number of months in the term - weeks: - type: integer - example: 3 - description: Number of weeks in the term - days: - type: integer - example: 2 - description: Number of days in the term - prisonTermCode: - type: string - enum: - - CUR - - DEF - - DET - - HOURS - - IMP - - LIC - - PSYCH - - SCUS - - SEC104 - - SEC105 - - SEC86 - - SUP - - SUSP - example: IMP - description: > - The sentence term code - Possible values are: - `CUR` - Curfew Period, - `DEF` - Deferment Period, - `DET` - Detention, - `HOURS` - Hours Ordered, - `IMP` - Imprisonment, - `LIC` - Licence, - `PSYCH` - Psychiatric Hospital, - `SCUS` - Custodial Period, - `SEC104` - Breach of supervision requirements, - `SEC105` - Breach due to imprisonable offence, - `SEC86` - Section 86 of 2000 Act, - `SUP` - Sentence Length, - `SUSP` - Suspension Period - StatusInformation: - type: object - properties: - code: - type: string - nullable: true - example: ASFO - description: - type: string - nullable: true - example: Serious Further Offence - Subject to SFO review/investigation - startDate: - type: string - nullable: true - example: 2022-01-01 - reviewDate: - type: string - nullable: true - example: 2025-01-01 - notes: - type: string - nullable: true - example: This is a note - RiskAssessment: - type: object - properties: - classificationCode: - type: string - example: C - description: The classification code of the risk - classification: - type: string - example: Cat C - description: The classification of the code - assessmentCode: - type: string - example: CATEGORY - description: The assessment code - assessmentDescription: - type: string - example: Categorisation - description: The description of the assessment - assessmentDate: - type: string - example: 2018-02-11 - description: The date of the assessment - nextReviewDate: - type: string - example: 2018-02-11 - description: Next review date - assessmentAgencyId: - type: string - example: MDI - description: Agency ID of the assessment - assessmentStatus: - type: string - example: P - description: The status of the assessment - assessmentComment: - type: string - example: Comment details - description: Comments regarding the assessment - RiskScore: - type: object - properties: - completedDate: - type: string - format: date - example: 2023-09-05T10:15:41 - description: Risk scores calculation completion date - assessmentStatus: - type: string - enum: - - COMPLETE - - LOCKED_INCOMPLETE - example: COMPLETE - description: > - Whether the risk score calculation is complete. Possible values are: - `COMPLETE`, - `LOCKED_INCOMPLETE` - groupReconviction: - $ref: "#/components/schemas/GroupReconviction" - violencePredictor: - $ref: "#/components/schemas/ViolencePredictor" - generalPredictor: - $ref: "#/components/schemas/GeneralPredictor" - riskOfSeriousRecidivism: - $ref: "#/components/schemas/RiskOfSeriousRecidivism" - sexualPredictor: - $ref: "#/components/schemas/SexualPredictor" - GroupReconviction: - type: object - properties: - scoreLevel: - type: string - enum: - - LOW - - MEDIUM - - HIGH - - VERY_HIGH - - NOT_APPLICABLE - example: LOW - description: > - Indicator for risk of group reconviction. Possible values are: - `LOW`, - `MEDIUM`, - `HIGH`, - `VERY_HIGH`, - `NOT_APPLICABLE` - - ViolencePredictor: - type: object - properties: - scoreLevel: - type: string - enum: - - LOW - - MEDIUM - - HIGH - - VERY_HIGH - - NOT_APPLICABLE - example: MEDIUM - description: > - Indicator for risk of violence. Possible values are: - `LOW`, - `MEDIUM`, - `HIGH`, - `VERY_HIGH`, - `NOT_APPLICABLE` - - GeneralPredictor: - type: object - properties: - scoreLevel: - type: string - enum: - - LOW - - MEDIUM - - HIGH - - VERY_HIGH - - NOT_APPLICABLE - example: VERY_HIGH - description: > - Indicator for general prediction. Possible values are: - `LOW`, - `MEDIUM`, - `HIGH`, - `VERY_HIGH`, - `NOT_APPLICABLE` - - RiskOfSeriousRecidivism: - type: object - properties: - scoreLevel: - type: string - enum: - - LOW - - MEDIUM - - HIGH - - VERY_HIGH - - NOT_APPLICABLE - example: MEDIUM - description: > - Indicator for risk of serious recidivism. Possible values are: - `LOW`, - `MEDIUM`, - `HIGH`, - `VERY_HIGH`, - `NOT_APPLICABLE` - - SexualPredictor: - type: object - properties: - indecentScoreLevel: - type: string - enum: - - LOW - - MEDIUM - - HIGH - - VERY_HIGH - - NOT_APPLICABLE - example: HIGH - description: > - Indicator for risk of sexual indecency. Possible values are: - `LOW`, - `MEDIUM`, - `HIGH`, - `VERY_HIGH`, - `NOT_APPLICABLE`, - contactScoreLevel: - type: string - enum: - - LOW - - MEDIUM - - HIGH - - VERY_HIGH - - NOT_APPLICABLE - example: MEDIUM - description: > - Indicator for risk of sexual contact. Possible values are: - `LOW`, - `MEDIUM`, - `HIGH`, - `VERY_HIGH`, - `NOT_APPLICABLE`, - - Risks: - type: object - properties: - assessedOn: - type: string - format: date - example: 2023-09-05T10:15:41 - description: Date of risk assessment - riskToSelf: - $ref: "#/components/schemas/RiskToSelf" - otherRisks: - $ref: "#/components/schemas/OtherRisks" - summary: - $ref: "#/components/schemas/Summary" - RiskToSelf: - type: object - properties: - suicide: - $ref: "#/components/schemas/Risk" - selfHarm: - $ref: "#/components/schemas/Risk" - custody: - $ref: "#/components/schemas/Risk" - hostelSetting: - $ref: "#/components/schemas/Risk" - vulnerability: - $ref: "#/components/schemas/Risk" - Risk: - type: object - properties: - risk: - type: string - example: "YES" - enum: - - YES - - NO - - DK - - NA - description: > - Presence of risk. Possible values are: - `YES`, - `NO`, - `DK`, - `NA` - previous: - type: string - example: "NO" - enum: - - YES - - NO - - DK - - NA - description: > - Previous concerns. Possible values are: - `YES`, - `NO`, - `DK`, - `NA` - previousConcernsText: - type: string - example: "Risk of self harm concerns due to ..." - description: Supporting comments for any previous concerns. - current: - type: string - example: "YES" - enum: - - YES - - NO - - DK - - NA - description: > - Current concerns. Possible values are: - `YES`, - `NO`, - `DK`, - `NA` - currentConcernsText: - type: string - example: "Risk of self harm concerns due to ..." - description: Supporting comments for any current concerns - RiskManagementPlan: - type: object - properties: - assessmentId: - type: string - example: "123456" - description: The unique ID of the risk management plan - dateCompleted: - type: string - example: "2024-05-04T01:04:20" - description: The date that the risk management plan was completed - initiationDate: - type: string - example: "2024-05-04T01:04:20" - description: The date of plan initiation - assessmentStatus: - type: string - example: "COMPLETE" - description: The status of the plan - assessmentType: - type: string - example: "string" - description: The type of assessment - keyInformationCurrentSituation: - type: string - example: "string" - description: Key information about the current situation of the subject being assessed - furtherConsiderationsCurrentSituation: - type: string - example: "string" - description: Further considerations about the situation of the subject being assessed - supervision: - type: string - example: "string" - description: Who they see, when and why, any support they get from their community, family and friends, and how well they're desisting from problematic behaviour - monitoringAndControl: - type: string - example: "string" - description: Information on restrictions in place to prevent reoffending, what steps have been taken to monitor potential reoffending, including license conditions, community order requirements, PPM restrictions and such. - interventionsAndTreatment: - type: string - example: "string" - description: Interventions delivered to develop controls and protective factors to reduce risk of reoffending, including practical support, requirements to support interventions and details of who and where these interventions will be administered. - victimSafetyPlanning: - type: string - example: "string" - description: Restrictions in place to specifically protect victims of, adults known to, and children potentially at risk from the offender. - contingencyPlans: - type: string - example: "string" - description: Future plans in the form "If X happens, we will do Y...." for if parts of the risk management plan break down or requirements or restrictions are breached by the offender. - latestSignLockDate: - type: string - example: "2024-05-04T01:04:20" - description: An assessment is considered 'Signed and locked' once it is signed by the assessor, making the plan read-only. This is the date the plan has been signed by the assessor. - latestCompleteDate: - type: string - example: "2024-05-04T01:04:20" - description: Once a countersignature has been applied to the plan, the plan is considered complete. This is the date the plan has been countersigned. - OtherRisks: - type: object - properties: - escapeOrAbscond: - type: string - example: "YES" - enum: - - YES - - NO - - DK - - NA - description: > - Risk of escape/abscond. Possible values are: - `YES`, - `NO`, - `DK`, - `NA` - controlIssuesDisruptiveBehaviour: - type: string - example: "DK" - enum: - - YES - - NO - - DK - - NA - description: > - Risk control issues/disruptive behaviour. Possible values are: - `YES`, - `NO`, - `DK`, - `NA` - breachOfTrust: - type: string - example: "NO" - enum: - - YES - - NO - - DK - - NA - description: > - Risk of breach of trust. Possible values are: - `YES`, - `NO`, - `DK`, - `NA` - riskToOtherPrisoners: - type: string - example: "YES" - enum: - - YES - - NO - - DK - - NA - description: > - Risk to other prisoners. Possible values are: - `YES`, - `NO`, - `DK`, - `NA` - Summary: - type: object - properties: - whoIsAtRisk: - type: string - example: "X, Y and Z are at risk" - description: Who is at risk - natureOfRisk: - type: string - example: "The nature of the risk is X" - description: What is the nature of the risk - riskImminence: - type: string - example: The risk is imminent and more probable in X situation - description: When is the risk likely to be greatest. Consider the timescale and indicate whether risk is immediate or not. Consider the risks in custody as well as on release. - riskIncreaseFactors: - type: string - example: If offender is in situation X the risk can be higher - description: What circumstances are likely to increase risk. Describe factors, actions, events which might increase level of risk, now and in the future. - riskMitigationFactors: - type: string - example: Giving offender therapy in X will reduce the risk - description: What factors are likely to reduce the risk. Describe factors, actions, and events which may reduce or contain the level of risk. What has previously stopped them? - overallRiskLevel: - type: string - example: HIGH - enum: - - VERY_HIGH - - HIGH - - MEDIUM - - LOW - description: The overall risk level - riskInCommunity: - type: object - description: > - Assess the risk of serious harm the offender poses on the basis that they could be released imminently back into the community. This field is a map which can return all or some of the properties given. - properties: - children: - type: string - example: HIGH - enum: - - VERY_HIGH - - HIGH - - MEDIUM - - LOW - public: - type: string - example: Medium - enum: - - VERY_HIGH - - HIGH - - MEDIUM - - LOW - knownAdult: - type: string - example: VERY_HIGH - enum: - - VERY_HIGH - - HIGH - - MEDIUM - - LOW - staff: - type: string - example: HIGH - enum: - - VERY_HIGH - - HIGH - - MEDIUM - - LOW - prisoners: - type: string - example: LOW - enum: - - VERY_HIGH - - HIGH - - MEDIUM - - LOW - riskInCustody: - type: object - description: > - Assess both the risk of serious harm the offender presents now, in custody, and the risk they could present to others whilst in a custodial setting. This field is a map which can return all or some of the properties given. - properties: - children: - type: string - example: HIGH - enum: - - VERY_HIGH - - HIGH - - MEDIUM - - LOW - public: - type: string - example: Medium - enum: - - VERY_HIGH - - HIGH - - MEDIUM - - LOW - knownAdult: - type: string - example: VERY_HIGH - enum: - - VERY_HIGH - - HIGH - - MEDIUM - - LOW - staff: - type: string - example: HIGH - enum: - - VERY_HIGH - - HIGH - - MEDIUM - - LOW - prisoners: - type: string - example: LOW - enum: - - VERY_HIGH - - HIGH - - MEDIUM - - LOW - Needs: - type: object - properties: - assessedOn: - type: string - format: date - example: 2023-09-05T10:15:41 - description: Needs assessment completion date - identifiedNeeds: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Need" - notIdentifiedNeeds: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Need" - unansweredNeeds: - type: array - minItems: 0 - items: - $ref: "#/components/schemas/Need" - Need: - type: object - properties: - type: - type: string - example: DRUG_MISUSE - description: The type of need - riskOfHarm: - type: boolean - example: true - description: Risk of harm - riskOfReoffending: - type: boolean - example: true - description: Risk of reoffending - severity: - type: string - example: "NO_NEED" - description: Severity of need - - examples: - PersonNotFoundError: - value: - status: 404 - errorCode: null - userMessage: "404 Not found error: Could not find person with HMPPS id: 2003/0011991D" - developerMessage: "Could not find person with HMPPS id: 2003/0011991D" - moreInfo: null - ImageNotFoundError: - value: - status: 404 - errorCode: null - userMessage: "404 Not found error: Could not find an image with id: 123456" - developerMessage: "Could not find an image with id: 123456" - moreInfo: null - NoQueryParametersBadRequestError: - value: - status: 400, - errorCode: null, - userMessage: "Validation failure: No query parameters specified." - developerMessage: "No query parameters specified." - moreInfo: null - InternalServerError: - value: - status: 500 - errorCode: null, - userMessage: "Internal Server Error" - developerMessage: "Unable to complete request as an upstream service is not responding." - moreInfo: null diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/config/OpenAPIConfig.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/config/OpenAPIConfig.kt new file mode 100644 index 000000000..3dea47a14 --- /dev/null +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/config/OpenAPIConfig.kt @@ -0,0 +1,111 @@ +package uk.gov.justice.digital.hmpps.hmppsintegrationapi.config + +import io.swagger.v3.oas.annotations.OpenAPIDefinition +import io.swagger.v3.oas.annotations.enums.SecuritySchemeIn +import io.swagger.v3.oas.annotations.enums.SecuritySchemeType +import io.swagger.v3.oas.annotations.info.Info +import io.swagger.v3.oas.annotations.info.License +import io.swagger.v3.oas.annotations.security.SecurityRequirement +import io.swagger.v3.oas.annotations.security.SecurityScheme +import io.swagger.v3.oas.annotations.servers.Server +import io.swagger.v3.oas.models.OpenAPI +import io.swagger.v3.oas.models.media.Schema +import io.swagger.v3.oas.models.parameters.Parameter +import org.springdoc.core.customizers.GlobalOpenApiCustomizer +import org.springdoc.core.customizers.OpenApiCustomizer +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import java.math.BigDecimal + +@OpenAPIDefinition( + info = + Info( + title = "HMPPS Integration API", + description = "A long-lived API that exposes data from HMPPS systems such as the National Offender Management Information System (NOMIS), nDelius (probation system) and Offender Assessment System (OASys), providing a single point of entry for consumers.", + license = + License( + name = "MIT", + url = "https://github.com/ministryofjustice/hmpps-integration-api/blob/main/LICENSE", + ), + version = "1.0", + ), + servers = [ + Server(url = "https://hmpps-integration-api-dev.apps.live.cloud-platform.service.justice.gov.uk", description = "Development server"), + Server(url = "https://hmpps-integration-api-preprod.apps.live.cloud-platform.service.justice.gov.uk", description = "Pre-production server, containing live data"), + Server(url = "https://hmpps-integration-api-prod.apps.live.cloud-platform.service.justice.gov.uk", description = "Production"), + ], + security = [ + SecurityRequirement(name = "mutual-tls"), + SecurityRequirement(name = "api-key"), + ], +) +@SecurityScheme( + name = "mutual-tls", + type = SecuritySchemeType.MUTUALTLS, +) +@SecurityScheme( + name = "api-key", + type = SecuritySchemeType.APIKEY, + `in` = SecuritySchemeIn.HEADER, + paramName = "x-api-key", +) +@Configuration +class OpenAPIConfig { + companion object { + const val HMPPS_ID = "#components/parameters/hmppsId" + const val PAGE = "#components/parameters/page" + const val PER_PAGE = "#components/parameters/perPage" + } + + @Bean + fun openApiCustomizer(): OpenApiCustomizer = + object : GlobalOpenApiCustomizer { + override fun customise(openApi: OpenAPI) { + openApi.components + .addParameters( + "hmppsId", + Parameter() + .name("hmppsId") + .description("A URL-encoded HMPPS identifier") + .example("2008%2F0545166T") + .schema(Schema().type("string")) + .`in`("path") + .required(true), + ) + .addParameters( + "page", + Parameter() + .name("page") + .description("The page number (starting from 1)") + .schema(Schema().type("number").minimum(BigDecimal.ONE)._default(1)) + .`in`("query") + .required(false), + ) + .addParameters( + "perPage", + Parameter().name("perPage") + .description("The maximum number of results for a page") + .schema(Schema().type("number").minimum(BigDecimal.ONE)._default(10)) + .`in`("query") + .required(false), + ) + .addSchemas( + "BadRequest", + Schema() + .example(ErrorResponse(400, userMessage = "Validation failure: No query parameters specified.", developerMessage = "No query parameters specified.")), + ) + .addSchemas( + "PersonNotFound", + Schema() + .description("Failed to find a person with the provided HMPPS ID.") + .example(ErrorResponse(404, userMessage = "404 Not found error: Could not find person with HMPPS id: 2003/0011991D.", developerMessage = "Could not find person with HMPPS id: 2003/0011991D.")), + ) + .addSchemas( + "InternalServerError", + Schema() + .description("An upstream service was not responding, so we cannot verify the accuracy of any data we did get.") + .example(ErrorResponse(500, userMessage = "Internal Server Error", developerMessage = "Unable to complete request as an upstream service is not responding.")), + ) + } + } +} diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/ConfigController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/ConfigController.kt index d1ba61ee3..2216b6ff2 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/ConfigController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/ConfigController.kt @@ -1,11 +1,13 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1 +import io.swagger.v3.oas.annotations.Hidden import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.AuthorisationConfig +@Hidden @RestController @EnableConfigurationProperties(AuthorisationConfig::class) @RequestMapping("/v1/config") @@ -13,7 +15,7 @@ class ConfigController( var authorisationConfig: AuthorisationConfig, ) { @GetMapping("authorisation") - fun getImage(): Map> { + fun getAuthorisation(): Map> { return authorisationConfig.consumers } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/EPFPersonDetailController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/EPFPersonDetailController.kt index 155bf5360..cf648f0e2 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/EPFPersonDetailController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/EPFPersonDetailController.kt @@ -1,5 +1,10 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1 +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable @@ -14,11 +19,26 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditS @RestController @RequestMapping("/v1/epf/person-details") +@Tag(name = "default") class EPFPersonDetailController( @Autowired val getEPFPersonDetailService: GetEPFPersonDetailService, @Autowired val auditService: AuditService, ) { @GetMapping("{hmppsId}/{eventNumber}") + @Operation( + summary = "Probation case information for the Effective Proposals Framework service", + description = """ +

Accepts a Hmpps Id (hmppsId) and Delius Event number + and returns a data structure giving background information on the probation case + for use in the Effective Proposals Framework system. The information is used to + reduce the need for the EPF user to re-key information already held in Delius.

+ """, + responses = [ + ApiResponse(responseCode = "200"), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getCaseDetail( @PathVariable hmppsId: String, @PathVariable eventNumber: Int, diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/HmppsIdController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/HmppsIdController.kt index 428876119..3a5cf47c8 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/HmppsIdController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/HmppsIdController.kt @@ -1,5 +1,6 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1 +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable @@ -8,12 +9,14 @@ import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.HmppsId +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetHmppsIdService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @RestController @RequestMapping("/v1/hmpps-id") +@Tag(name = "default") class HmppsIdController( @Autowired val getHmppsIdService: GetHmppsIdService, @Autowired val auditService: AuditService, @@ -21,7 +24,7 @@ class HmppsIdController( @GetMapping("nomis-number/{encodedNomisNumber}") fun getHmppsIdByNomisNumber( @PathVariable encodedNomisNumber: String, - ): Map { + ): Response { val nomisNumber = encodedNomisNumber.decodeUrlCharacters() val response = getHmppsIdService.execute(nomisNumber) @@ -32,6 +35,6 @@ class HmppsIdController( auditService.createEvent("GET_HMPPS_ID_BY_NOMIS_NUMBER", mapOf("nomisNumber" to nomisNumber)) - return mapOf("data" to response.data) + return Response(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/ImageController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/ImageController.kt index 3aa55b8b6..d4c303c81 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/ImageController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/ImageController.kt @@ -1,5 +1,10 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1 +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.GetMapping @@ -13,11 +18,20 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditS @RestController @RequestMapping("/v1/images") +@Tag(name = "images") class ImageController( @Autowired val getImageService: GetImageService, @Autowired val auditService: AuditService, ) { @GetMapping("{id}") + @Operation( + summary = "Returns an image in bytes as a JPEG.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found an image with the provided ID."), + ApiResponse(responseCode = "404", description = "Failed to find an image with the provided ID.", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getImage( @PathVariable id: Int, ): ResponseEntity { diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/RiskManagementController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/RiskManagementController.kt index 985e00680..5f1fa28f2 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/RiskManagementController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/RiskManagementController.kt @@ -1,12 +1,21 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1 +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.context.properties.EnableConfigurationProperties +import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.AuthorisationConfig +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.RiskManagementPlan @@ -19,15 +28,24 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.paginateWith @RestController @EnableConfigurationProperties(AuthorisationConfig::class) +@Tag(name = "risks") class RiskManagementController( @Autowired val getRiskManagementPlansForCrnService: GetRiskManagementPlansForCrnService, @Autowired val auditService: AuditService, ) { - @RequestMapping("/v1/persons/{encodedHmppsId}/risk-management-plan") + @GetMapping("/v1/persons/{encodedHmppsId}/risk-management-plan") + @Operation( + summary = "Returns a list of Risk Management Plans created for the person with the provided HMPPS ID.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found risk management plans for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getRiskManagementPlans( - @PathVariable encodedHmppsId: String, - @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getRiskManagementPlansForCrnService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt index 433e0d274..1c719e190 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt @@ -1,13 +1,21 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Address +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetAddressesForPersonService @@ -15,14 +23,23 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditS @RestController @RequestMapping("/v1/persons") +@Tag(name = "persons") class AddressController( @Autowired val auditService: AuditService, @Autowired val getAddressesForPersonService: GetAddressesForPersonService, ) { @GetMapping("{encodedHmppsId}/addresses") + @Operation( + summary = "Returns addresses associated with a person, ordered by startDate.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonAddresses( - @PathVariable encodedHmppsId: String, - ): Map> { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response> { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getAddressesForPersonService.execute(hmppsId) @@ -33,6 +50,6 @@ class AddressController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_ADDRESS", mapOf("hmppsId" to hmppsId)) - return mapOf("data" to response.data) + return Response(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AdjudicationsController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AdjudicationsController.kt index 62c30590d..83b69d7b3 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AdjudicationsController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AdjudicationsController.kt @@ -1,11 +1,20 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Adjudication @@ -17,15 +26,24 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.paginateWith @RestController @RequestMapping("/v1/persons") +@Tag(name = "default") class AdjudicationsController( @Autowired val auditService: AuditService, @Autowired val getAdjudicationsForPersonService: GetAdjudicationsForPersonService, ) { @GetMapping("{encodedHmppsId}/reported-adjudications") + @Operation( + summary = "Returns adjudications associated with a person, sorted by dateTimeOfIncident (newest first).", + responses = [ + ApiResponse(responseCode = "200", description = "OK"), + ApiResponse(responseCode = "404", description = "Failed to find adjudications for the person with the provided hmppsId.", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonAdjudications( - @PathVariable encodedHmppsId: String, - @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @RequestParam(required = false, defaultValue = "8", name = "perPage") perPage: Int, + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "8", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getAdjudicationsForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AlertsController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AlertsController.kt index 23dcb4b6e..8f43f49e0 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AlertsController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AlertsController.kt @@ -1,11 +1,21 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag +import io.swagger.v3.oas.annotations.tags.Tags import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Alert @@ -17,15 +27,24 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.paginateWith @RestController @RequestMapping("/v1/persons") +@Tags(Tag(name = "persons"), Tag(name = "alerts")) class AlertsController( @Autowired val getAlertsForPersonService: GetAlertsForPersonService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/alerts") + @Operation( + summary = "Returns alerts associated with a person, sorted by dateCreated (newest first).", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found alerts for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonAlerts( - @PathVariable encodedHmppsId: String, - @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getAlertsForPersonService.execute(hmppsId) @@ -38,10 +57,18 @@ class AlertsController( } @GetMapping("{encodedHmppsId}/alerts/pnd") + @Operation( + summary = "Returns alerts associated with a person, sorted by dateCreated (newest first).", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found alerts for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonAlertsPND( - @PathVariable encodedHmppsId: String, - @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getAlertsForPersonService.getAlertsForPnd(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt index 709610beb..1bd446bdc 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt @@ -1,5 +1,11 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.format.annotation.DateTimeFormat import org.springframework.web.bind.annotation.GetMapping @@ -7,6 +13,7 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.filters.CaseNoteFilter @@ -21,19 +28,31 @@ import java.time.LocalDateTime @RestController @RequestMapping("/v1/persons") +@Tag(name = "default") class CaseNotesController( @Autowired val getCaseNoteForPersonService: GetCaseNotesForPersonService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/case-notes") + @Operation( + summary = "Returns case notes associated with a person.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found case notes for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getCaseNotesForPerson( - @PathVariable encodedHmppsId: String, + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "Filter case notes from this date") @RequestParam(required = false, name = "startDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) startDate: LocalDateTime?, + @Parameter(description = "Filter case notes up to this date") @RequestParam(required = false, name = "endDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) endDate: LocalDateTime?, + @Parameter(description = "Filter by the location. example MDI", example = "MDI") @RequestParam(required = false, name = "locationId") locationId: String?, @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt index b56dbf119..222dd2414 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt @@ -1,27 +1,32 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CellLocation +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCellLocationForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @RestController @RequestMapping("/v1/persons") +@Tag(name = "persons") class CellLocationController( @Autowired val auditService: AuditService, @Autowired val getCellLocationForPersonService: GetCellLocationForPersonService, ) { @GetMapping("{encodedHmppsId}/cell-location") fun getPersonCellLocation( - @PathVariable encodedHmppsId: String, - ): Map { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getCellLocationForPersonService.execute(hmppsId) @@ -32,6 +37,6 @@ class CellLocationController( auditService.createEvent("GET_PERSON_CELL_LOCATION", mapOf("hmppsId" to hmppsId)) - return mapOf("data" to response.data) + return Response(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/DynamicRisksController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/DynamicRisksController.kt index 60aadde13..b6fca85a7 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/DynamicRisksController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/DynamicRisksController.kt @@ -1,11 +1,21 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag +import io.swagger.v3.oas.annotations.tags.Tags import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DynamicRisk @@ -17,15 +27,24 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.paginateWith @RestController @RequestMapping("/v1/persons") +@Tags(Tag(name = "persons"), Tag(name = "alerts")) class DynamicRisksController( @Autowired val getDynamicRisksForPersonService: GetDynamicRisksForPersonService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/risks/dynamic") + @Operation( + summary = "Returns dynamic risks associated with a person.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found dynamic risks for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getDynamicRisks( - @PathVariable encodedHmppsId: String, - @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getDynamicRisksForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt index 6151b4646..230e322b7 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt @@ -1,27 +1,44 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PersonLicences +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetLicenceConditionService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @RestController @RequestMapping("/v1/persons") +@Tag(name = "default") class LicenceConditionController( @Autowired val auditService: AuditService, @Autowired val getLicenceConditionService: GetLicenceConditionService, ) { @GetMapping("{encodedHmppsId}/licences/conditions") + @Operation( + summary = "Returns license conditions associated with a person, sorted by createdDateTime (newest first).", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found licenses for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getLicenceConditions( - @PathVariable encodedHmppsId: String, - ): Map { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getLicenceConditionService.execute(hmppsId) @@ -29,6 +46,6 @@ class LicenceConditionController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_LICENCE_CONDITION", mapOf("hmppsId" to hmppsId)) - return mapOf("data" to response.data) + return Response(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt index b4e41eaca..8c47e5265 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt @@ -1,27 +1,44 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.MappaDetail +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetMappaDetailForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @RestController @RequestMapping("/v1/persons") +@Tag(name = "persons") class MappaDetailController( @Autowired val getMappaDetailForPersonService: GetMappaDetailForPersonService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/risks/mappadetail") + @Operation( + summary = "Returns the mappa detail related to a person.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found mappa detail for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getMappaDetail( - @PathVariable encodedHmppsId: String, - ): Map { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getMappaDetailForPersonService.execute(hmppsId) @@ -29,6 +46,6 @@ class MappaDetailController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_MAPPA_DETAIL", mapOf("hmppsId" to hmppsId)) - return mapOf("data" to response.data) + return Response(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt index 7da4ce9f1..edd68a1cc 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt @@ -1,27 +1,49 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Needs +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetNeedsForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @RestController @RequestMapping("/v1/persons") +@Tag(name = "needs") class NeedsController( @Autowired val getNeedsForPersonService: GetNeedsForPersonService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/needs") + @Operation( + summary = """ + Returns criminogenic needs associated with a person. This endpoint does not serve LAO (Limited Access Offender) data. + + Note: Criminogenic needs are dynamic factors that are directly linked to criminal behaviour. Eight criminogenic needs are measured in OASys: Accommodation, Employability, Relationships, Lifestyle and Associates, Drug Misuse, Alcohol Misuse, Thinking & Behaviour and Attitudes. These are scored according to whether there is “no need”, “some need” or “severe need”, and a need is identified in a specific section based on calculations around these scores. + However, the process by which needs are assessed is changing as early as next year (2024), specifically moving to a strength-based model that seeks to identify and develop the strengths of people with convictions. As a consequence of this, the information provided by this endpoint will also change. + """, + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found criminogenic needs for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonNeeds( - @PathVariable encodedHmppsId: String, - ): Map { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getNeedsForPersonService.execute(hmppsId) @@ -29,6 +51,6 @@ class NeedsController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_NEED", mapOf("hmppsId" to hmppsId)) - return mapOf("data" to response.data) + return Response(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/OffencesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/OffencesController.kt index c9457c550..1bb876dc9 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/OffencesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/OffencesController.kt @@ -1,11 +1,21 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.ExampleObject +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Offence @@ -17,15 +27,74 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.paginateWith @RestController @RequestMapping("/v1/persons") +@Tag(name = "persons") class OffencesController( @Autowired val auditService: AuditService, @Autowired val getOffencesForPersonService: GetOffencesForPersonService, ) { @GetMapping("{encodedHmppsId}/offences") + @Operation( + summary = """ + Returns offences associated with a person, ordered by startDate (newest first). + > Note: This API does not contain the complete list of offences for a person. + > Offences are retrieved from Prison and Probation systems exclusively. + > Prison systems record only custodial sentences, while Probation systems record only the main offence and some additional offences for case management purposes. Other offences recorded by HMCTS and police may not be included. + """, + responses = [ + ApiResponse( + responseCode = "200", + description = "Successfully found offences for a person with the provided HMPPS ID.", + content = [ + Content( + examples = [ + ExampleObject( + """{ + "data": [ + { + "serviceSource": "NOMIS", + "systemSource": "PRISON_SYSTEMS", + "cjsCode": "RR84170", + "courtDates": [ + "2018-02-10", + "2019-02-10" + ], + "courtName": "London Magistrates Court", + "description": "Commit an act / series of acts with intent to pervert the course of public justice", + "endDate": "2018-03-10", + "hoCode": 3457, + "startDate": "1965-12-01", + "statuteCode": "RR84" + }, + { + "serviceSource": "NDELIUS", + "systemSource": "PROBATION_SYSTEMS", + "cjsCode": "RR12345", + "courtDates": [ + "2020-05-15", + "2021-05-15" + ], + "courtName": "Manchester Crown Court", + "description": "Assault causing grievous bodily harm", + "endDate": "2020-06-20", + "hoCode": 3458, + "startDate": "2020-05-10", + "statuteCode": "RR85" + } + ] + }""", + ), + ], + ), + ], + ), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonOffences( - @PathVariable encodedHmppsId: String, - @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getOffencesForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt index ffbd5340a..80ad0a3b7 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt @@ -1,5 +1,11 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import jakarta.validation.ValidationException import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping @@ -7,11 +13,15 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.ImageMetadata import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Person import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PersonName +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError.Type.ENTITY_NOT_FOUND @@ -27,6 +37,7 @@ import java.time.format.DateTimeFormatter @RestController @RequestMapping("/v1/persons") +@Tag(name = "persons") class PersonController( @Autowired val getPersonService: GetPersonService, @Autowired val getPersonsService: GetPersonsService, @@ -35,14 +46,26 @@ class PersonController( @Autowired val auditService: AuditService, ) { @GetMapping + @Operation( + summary = "Returns person(s) by search criteria, sorted by date of birth (newest first). At least one query parameter must be specified.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully performed the query on upstream APIs. An empty list is returned when no results are found."), + ApiResponse( + responseCode = "400", + description = "There were no query parameters passed in. At least one must be specified.", + content = [Content(schema = Schema(ref = "#/components/schemas/BadRequest"))], + ), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersons( - @RequestParam(required = false, name = "first_name") firstName: String?, - @RequestParam(required = false, name = "last_name") lastName: String?, - @RequestParam(required = false, name = "pnc_number") pncNumber: String?, - @RequestParam(required = false, name = "date_of_birth") dateOfBirth: String?, - @RequestParam(required = false, defaultValue = "false", name = "search_within_aliases") searchWithinAliases: Boolean, - @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(description = "The first name of the person") @RequestParam(required = false, name = "first_name") firstName: String?, + @Parameter(description = "The last name of the person") @RequestParam(required = false, name = "last_name") lastName: String?, + @Parameter(description = "A URL-encoded pnc identifier") @RequestParam(required = false, name = "pnc_number") pncNumber: String?, + @Parameter(description = "The date of birth of the person") @RequestParam(required = false, name = "date_of_birth") dateOfBirth: String?, + @Parameter(description = "Whether to return results that match the search criteria within the aliases of a person.") @RequestParam(required = false, defaultValue = "false", name = "search_within_aliases") searchWithinAliases: Boolean, + @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { if (firstName == null && lastName == null && pncNumber == null && dateOfBirth == null) { throw ValidationException("No query parameters specified.") @@ -62,9 +85,17 @@ class PersonController( } @GetMapping("{encodedHmppsId}") + @Operation( + summary = "Returns a person.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPerson( - @PathVariable encodedHmppsId: String, - ): Map> { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response> { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getPersonService.getCombinedDataForPerson(hmppsId) @@ -74,14 +105,22 @@ class PersonController( auditService.createEvent("GET_PERSON_DETAILS", mapOf("hmppsId" to hmppsId)) val data = response.data.mapValues { it.value } - return mapOf("data" to data) + return Response(data) } @GetMapping("{encodedHmppsId}/images") + @Operation( + summary = "Returns metadata of images associated with a person sorted by captureDateTime (newest first).", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found a person with the provided HMPPS ID. If a person doesn't have any images, then an empty list (`[]`) is returned in the `data` property."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonImages( - @PathVariable encodedHmppsId: String, - @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() @@ -96,9 +135,17 @@ class PersonController( } @GetMapping("{encodedHmppsId}/name") + @Operation( + summary = "Returns a person's name", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonName( - @PathVariable encodedHmppsId: String, - ): Map { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getNameForPersonService.execute(hmppsId) @@ -109,7 +156,7 @@ class PersonController( auditService.createEvent("GET_PERSON_NAME", mapOf("hmppsId" to hmppsId)) - return mapOf("data" to response.data) + return Response(response.data) } private fun isValidISODateFormat(dateString: String): Boolean { diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt index 63481e357..f7b237013 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt @@ -1,13 +1,21 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PersonResponsibleOfficer +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCommunityOffenderManagerForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetPrisonOffenderManagerForPersonService @@ -15,15 +23,24 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditS @RestController @RequestMapping("/v1/persons") +@Tag(name = "default") class PersonResponsibleOfficerController( @Autowired val auditService: AuditService, @Autowired val getPrisonOffenderManagerForPersonService: GetPrisonOffenderManagerForPersonService, @Autowired val getCommunityOffenderManagerForPersonService: GetCommunityOffenderManagerForPersonService, ) { @GetMapping("{encodedHmppsId}/person-responsible-officer") + @Operation( + summary = "Returns the person responsible officer associated with a person.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found the person responsible officer for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonResponsibleOfficer( - @PathVariable encodedHmppsId: String, - ): Map { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response { val hmppsId = encodedHmppsId.decodeUrlCharacters() val prisonOffenderManager = getPrisonOffenderManagerForPersonService.execute(hmppsId) val communityOffenderManager = getCommunityOffenderManagerForPersonService.execute(hmppsId) @@ -43,6 +60,6 @@ class PersonResponsibleOfficerController( ) auditService.createEvent("GET_PERSON_RESPONSIBLE_OFFICER", mapOf("hmppsId" to hmppsId)) - return mapOf("data" to mergedData) + return Response(mergedData) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt index eacc4b66d..b0f54ae60 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt @@ -1,27 +1,44 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PersonProtectedCharacteristics +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetProtectedCharacteristicsService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @RestController @RequestMapping("/v1/persons") +@Tag(name = "default") class ProtectedCharacteristicsController( @Autowired val getProtectedCharacteristicsService: GetProtectedCharacteristicsService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/protected-characteristics") + @Operation( + summary = "Returns protected characteristics of a person.", + responses = [ + ApiResponse(responseCode = "200"), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonAddresses( - @PathVariable encodedHmppsId: String, - ): Map { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getProtectedCharacteristicsService.execute(hmppsId) @@ -29,6 +46,6 @@ class ProtectedCharacteristicsController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_PROTECTED_CHARACTERISTICS", mapOf("hmppsId" to hmppsId)) - return mapOf("data" to response.data) + return Response(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt index a9882c3d0..1e0ae1f1d 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt @@ -1,12 +1,20 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.RiskCategory import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetRiskCategoriesForPersonService @@ -14,14 +22,23 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditS @RestController @RequestMapping("/v1/persons") +@Tag(name = "persons") class RiskCategoriesController( @Autowired val getRiskCategoriesForPersonService: GetRiskCategoriesForPersonService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/risks/categories") + @Operation( + summary = "Returns the categories related to an offender.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found risk categories for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonRiskCategories( - @PathVariable encodedHmppsId: String, - ): Map { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getRiskCategoriesForPersonService.execute(hmppsId) @@ -29,6 +46,6 @@ class RiskCategoriesController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_RISK_CATEGORIES", mapOf("hmppsId" to hmppsId)) - return mapOf("data" to response.data) + return Response(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskPredictorScoresController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskPredictorScoresController.kt index 08b22fd73..d7bb1134d 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskPredictorScoresController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskPredictorScoresController.kt @@ -1,11 +1,20 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.RiskPredictorScore @@ -17,15 +26,24 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.paginateWith @RestController @RequestMapping("/v1/persons") +@Tag(name = "risks") class RiskPredictorScoresController( @Autowired val getRiskPredictorScoresForPersonService: GetRiskPredictorScoresForPersonService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/risks/scores") + @Operation( + summary = "Returns risk scores from the last year associated with a person, sorted by completedDate (newest first). This endpoint does not serve LAO (Limited Access Offender) data.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found risk scores for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonRiskPredictorScores( - @PathVariable encodedHmppsId: String, - @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getRiskPredictorScoresForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt index 9f672bed6..cd3bfc3f7 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt @@ -1,12 +1,20 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Risks import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetRiskSeriousHarmForPersonService @@ -14,14 +22,23 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditS @RestController @RequestMapping("/v1/persons") +@Tag(name = "risks") class RiskSeriousHarmController( @Autowired val getRiskSeriousHarmForPersonService: GetRiskSeriousHarmForPersonService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/risks/serious-harm") + @Operation( + summary = "Returns Risk of Serious Harm (ROSH) risks associated with a person. Returns only assessments completed in the last year. This endpoint does not serve LAO (Limited Access Offender) data.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found risks for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonRiskSeriousHarm( - @PathVariable encodedHmppsId: String, - ): Map { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getRiskSeriousHarmForPersonService.execute(hmppsId) @@ -29,6 +46,6 @@ class RiskSeriousHarmController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_RISK", mapOf("hmppsId" to hmppsId)) - return mapOf("data" to response.data) + return Response(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt index 858eb7e0e..9be9abd70 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt @@ -1,14 +1,24 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.LatestSentenceKeyDatesAndAdjustments +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Sentence import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError @@ -20,16 +30,25 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.paginateWith @RestController @RequestMapping("/v1/persons") +@Tag(name = "persons") class SentencesController( @Autowired val getSentencesForPersonService: GetSentencesForPersonService, @Autowired val getLatestSentenceKeyDatesAndAdjustmentsForPersonService: GetLatestSentenceKeyDatesAndAdjustmentsForPersonService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/sentences") + @Operation( + summary = "Returns sentences associated with a person, sorted by dateOfSentencing (newest first).", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found sentences for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonSentences( - @PathVariable encodedHmppsId: String, - @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getSentencesForPersonService.execute(hmppsId) @@ -42,9 +61,17 @@ class SentencesController( } @GetMapping("{encodedHmppsId}/sentences/latest-key-dates-and-adjustments") + @Operation( + summary = "Returns the key dates and adjustments about a person's release from prison for their latest sentence.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found latest sentence key dates and adjustments for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getPersonLatestSentenceKeyDatesAndAdjustments( - @PathVariable encodedHmppsId: String, - ): Map { + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + ): Response { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getLatestSentenceKeyDatesAndAdjustmentsForPersonService.execute(hmppsId) @@ -55,6 +82,6 @@ class SentencesController( "GET_PERSON_SENTENCES_LATEST_KEY_DATES_AND_ADJUSTMENTS", mapOf("hmppsId" to hmppsId), ) - return mapOf("data" to response.data) + return Response(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/StatusInformationController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/StatusInformationController.kt index 2d874f0b1..f186319d4 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/StatusInformationController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/StatusInformationController.kt @@ -1,11 +1,21 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.controllers.v1.person +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.media.Content +import io.swagger.v3.oas.annotations.media.Schema +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.tags.Tag +import io.swagger.v3.oas.annotations.tags.Tags import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.StatusInformation @@ -17,15 +27,24 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.util.paginateWith @RestController @RequestMapping("/v1/persons") +@Tags(Tag(name = "persons"), Tag(name = "alerts")) class StatusInformationController( @Autowired val getStatusInformationForPersonService: GetStatusInformationForPersonService, @Autowired val auditService: AuditService, ) { @GetMapping("{encodedHmppsId}/status-information") + @Operation( + summary = "Returns the status information associated with a person.", + responses = [ + ApiResponse(responseCode = "200", description = "Successfully found status information for a person with the provided HMPPS ID."), + ApiResponse(responseCode = "404", content = [Content(schema = Schema(ref = "#/components/schemas/PersonNotFound"))]), + ApiResponse(responseCode = "500", content = [Content(schema = Schema(ref = "#/components/schemas/InternalServerError"))]), + ], + ) fun getStatusInformation( - @PathVariable encodedHmppsId: String, - @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getStatusInformationForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/extensions/ConsumerNameExtractionFilter.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/extensions/ConsumerNameExtractionFilter.kt index e4c222def..63b2ad6a7 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/extensions/ConsumerNameExtractionFilter.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/extensions/ConsumerNameExtractionFilter.kt @@ -7,12 +7,14 @@ import jakarta.servlet.ServletRequest import jakarta.servlet.ServletResponse import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse +import org.springframework.context.annotation.Profile import org.springframework.core.annotation.Order import org.springframework.stereotype.Component import java.io.IOException @Component @Order(0) +@Profile("!local") class ConsumerNameExtractionFilter : Filter { @Throws(IOException::class, ServletException::class) override fun doFilter( @@ -42,3 +44,16 @@ class ConsumerNameExtractionFilter : Filter { return match.groupValues[1] } } + +@Component +@Order(0) +@Profile("local") +class LocalConsumerNameExtractionFilter : Filter { + override fun doFilter( + request: ServletRequest, + response: ServletResponse?, + chain: FilterChain, + ) { + chain.doFilter(request.apply { setAttribute("clientName", "all-access") }, response) + } +} diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Address.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Address.kt index 29096a65d..567feaa2b 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Address.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Address.kt @@ -1,24 +1,40 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class Address( + @Schema(example = "England") val country: String?, + @Schema(example = "Greater London") val county: String?, + @Schema(example = "20 May 2023") val endDate: LocalDate?, + @Schema(example = "London Bridge") val locality: String?, + @Schema(example = "Name of the building of residence") val name: String?, + @Schema(description = "Indicates whether the person has a permanent place of residence", example = "true") val noFixedAddress: Boolean, + @Schema(example = "1") val number: String?, + @Schema(example = "SE1 1TE") val postcode: String?, + @Schema(example = "1 January 2023") val startDate: LocalDate?, + @Schema(example = "O'Meara Street") val street: String?, + @Schema(example = "London") val town: String?, val types: List = emptyList(), + @Schema(example = "This is their partner's address.") val notes: String?, ) { + @Schema(description = "Type or usage of address, for example `Business Address`, `Home Address`, `Work Address`.") data class Type( + @Schema(example = "BUS", description = "Address type code, for example: `BUS`, `HOME`, `WORK`.") val code: String?, + @Schema(example = "Business Address", description = "Description of address type, for example: `Business Address`, `Home Address`, `Work Address`.") val description: String?, ) } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Alert.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Alert.kt index 8bc04c7d5..dbaa75de3 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Alert.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Alert.kt @@ -1,16 +1,27 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class Alert( + @Schema(description = "Offender unique reference", example = "Z1234ZZ") val offenderNo: String? = null, + @Schema(description = "Alert type", example = "X") val type: String? = null, + @Schema(description = "Alert type description", example = "Security") val typeDescription: String? = null, + @Schema(description = "Alert code", example = "PO") val code: String? = null, + @Schema(description = "Alert code description", example = "MAPPA Nominal") val codeDescription: String? = null, + @Schema(description = "Alert comment", example = "Professional lock pick") val comment: String? = null, + @Schema(description = "Date of the alert, which might differ from the date it was created", example = "2014-09-23") val dateCreated: LocalDate? = null, + @Schema(description = "Date that the alert expires", example = "2015-09-23") val dateExpired: LocalDate? = null, + @Schema(description = "Whether the alert has expired", example = "true") val expired: Boolean? = null, + @Schema(description = "Whether the alert is active", example = "true") val active: Boolean? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Alias.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Alias.kt index bff8659ec..84737c30d 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Alias.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Alias.kt @@ -1,16 +1,23 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps import com.fasterxml.jackson.annotation.JsonAlias +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class Alias( + @Schema(description = "first name", example = "John") val firstName: String, @JsonAlias("surname") + @Schema(description = "last name", example = "Marston") val lastName: String, @JsonAlias("middleNames") + @Schema(description = "last name", example = "Marston") val middleName: String? = null, @JsonAlias("dob") + @Schema(description = "date of birth", example = "1965-12-01") var dateOfBirth: LocalDate? = null, + @Schema(description = "gender", example = "Male") val gender: String? = null, + @Schema(description = "ethnicity", example = "Prefer not to say") val ethnicity: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseDetail.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseDetail.kt index 9f9590268..ff7c02a4d 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseDetail.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseDetail.kt @@ -1,5 +1,7 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class CaseDetail( val nomsId: String? = null, val name: Name? = null, @@ -45,5 +47,6 @@ data class CourtAppearance( ) data class CourtDetails( + @Schema(description = "The name of the court", example = "Manchester Crown Court") val name: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNote.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNote.kt index 039bd4a67..49cb90815 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNote.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNote.kt @@ -1,18 +1,30 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDateTime data class CaseNote( + @Schema(example = "1234") val caseNoteId: String? = null, + @Schema(example = "A1234AA") val offenderIdentifier: String? = null, + @Schema(example = "KA") val type: String? = null, + @Schema(example = "Key Worker") val typeDescription: String? = null, + @Schema(example = "KS") val subType: String? = null, + @Schema(example = "Key Worker Session") val subTypeDescription: String? = null, + @Schema(description = "Date and Time of Case Note creation", example = "2023-09-05T10:15:41") val creationDateTime: LocalDateTime? = null, + @Schema(description = "Date and Time of when case note contact with offender was made", example = "2023-09-05T10:15:41") val occurrenceDateTime: LocalDateTime? = null, + @Schema(example = "This is some text") val text: String? = null, + @Schema(example = "MDI") val locationId: String? = null, val sensitive: Boolean = false, + @Schema(description = "List of amendments to the case note") val amendments: List = emptyList(), ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNoteAmendment.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNoteAmendment.kt index bd39e44ca..bb7e443ee 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNoteAmendment.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/CaseNoteAmendment.kt @@ -1,9 +1,13 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDateTime data class CaseNoteAmendment( + @Schema(example = "123232") val caseNoteAmendmentId: Long? = null, + @Schema(description = "Date and Time of Case Note creation", example = "2023-09-05T10:15:41") val creationDateTime: LocalDateTime? = null, + @Schema(example = "Some Additional Text") val additionalNoteText: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ContactDetailsWithEmailAndPhone.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ContactDetailsWithEmailAndPhone.kt index b74994999..63ec5bf97 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ContactDetailsWithEmailAndPhone.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ContactDetailsWithEmailAndPhone.kt @@ -1,6 +1,9 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class ContactDetailsWithEmailAndPhone( val phoneNumbers: List?, + @Schema(description = "A list of email addresses", example = "leslie.knope@example.com") val emails: List?, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Disability.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Disability.kt index 87b570d89..cf30290b9 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Disability.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Disability.kt @@ -1,5 +1,6 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate class Disability( @@ -7,5 +8,6 @@ class Disability( val condition: KeyValue? = null, val startDate: LocalDate? = null, val endDate: LocalDate? = null, + @Schema(example = "Walking issue") val notes: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/DynamicRisk.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/DynamicRisk.kt index 6f9add2ee..68944f311 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/DynamicRisk.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/DynamicRisk.kt @@ -1,9 +1,16 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class DynamicRisk( + @Schema(example = "RCCO") val code: String? = null, + @Schema(example = "Child Concerns - Safeguarding concerns where a child is at risk from the offender") val description: String? = null, + @Schema(example = "2022-01-01") val startDate: String? = null, + @Schema(example = "2025-01-01") val reviewDate: String? = null, + @Schema(example = "This is a note") val notes: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/GeneralPredictor.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/GeneralPredictor.kt index ef0008cda..e67476aa9 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/GeneralPredictor.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/GeneralPredictor.kt @@ -1,5 +1,19 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class GeneralPredictor( + @Schema( + description = """ + Indicator for general prediction. Possible values are: + `LOW`, + `MEDIUM`, + `HIGH`, + `VERY_HIGH`, + `NOT_APPLICABLE` + """, + example = "VERY_HIGH", + allowableValues = ["LOW", "MEDIUM", "HIGH", "VERY_HIGH", "NOT_APPLICABLE"], + ) val scoreLevel: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/GroupReconviction.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/GroupReconviction.kt index f03ba8d0b..3e7d3398b 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/GroupReconviction.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/GroupReconviction.kt @@ -1,5 +1,19 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class GroupReconviction( + @Schema( + description = """ + Indicator for risk of group reconviction. Possible values are: + `LOW`, + `MEDIUM`, + `HIGH`, + `VERY_HIGH`, + `NOT_APPLICABLE` + """, + example = "LOW", + allowableValues = ["LOW", "MEDIUM", "HIGH", "VERY_HIGH", "NOT_APPLICABLE"], + ) val scoreLevel: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Identifiers.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Identifiers.kt index 87b402f68..d750d4f5a 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Identifiers.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Identifiers.kt @@ -1,7 +1,13 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + +@Schema(description = "Other unique identifiers for a person.") data class Identifiers( + @Schema(description = "A prisoner identifier from NOMIS.", example = "A1234AA") val nomisNumber: String? = null, + @Schema(description = "A Criminal Records Office identifier from National Identification Service (NIS) or National Automated Fingerprint Identification System (NAFIS).", example = "SF80/655108T") val croNumber: String? = null, + @Schema(description = "A Case Reference Number from Delius.", example = "X00001") val deliusCrn: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ImageMetadata.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ImageMetadata.kt index fcf42a233..cef291c35 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ImageMetadata.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ImageMetadata.kt @@ -1,12 +1,73 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDateTime data class ImageMetadata( + @Schema(description = "The Image ID, in reference to a unique identifier.", example = "2461788") val id: Long, + @Schema(description = "A flag to indicate whether an image is in active use. It is no guarantee that the latest uploaded image will be the active one.", example = "true") val active: Boolean, + @Schema(description = "The Date and Time of when the image was captured.", example = "2015-05-27T17:13:59") val captureDateTime: LocalDateTime, + @Schema( + description = """ + View is the subject focus; describing the inner focus or subject of the image, normally referring to a marking, tattoo or deeper level focus of the orientation. In practise this is the interior foci of what is captured in the 'orientation' field. + Possible values are: + `FACE` - Facing, + `TAT` - Tattoo, + `OTH` - Other, + `SCAR` - Scar, + `MARK` - Mark, + `OIC` - Offence in Custody + """, + allowableValues = ["FACE", "TAT", "OTH", "SCAR", "MARK", "OIC"], + example = "FACE", + ) val view: String, + @Schema( + description = """ + Orientation is the scope focus; describing the scope or outer focus of the image, normally referring to the highest level object of interest within the bounds of the photo itself. This is normally a body part or an angle of photography, such as a photo of someone’s facial view (`FRONT`) or arm (`ARM`). + Possible values are: + `ANKLE` - Ankle, + `ARM` - Arm, + `DAMAGE` - Damage, + `EAR` - Ear, + `ELBOW` - Elbow, + `FACE` - Face, + `FIGHT` - Fight, + `FINGER` - Finger, + `FOOT` - Foot, + `FRONT` - Front Facial View, + `HAND` - Hand, + `HEAD` - Head, + `INCIDENT` - Incident, + `INJURY` - Injury, + `KNEE` - Knee, + `LEG` - Leg, + `LIP` - Lip, + `NECK` - Neck, + `NOSE` - Nose, + `SHOULDER` - Shoulder, + `THIGH` - Thigh, + `TOE` - Toe, + `TORSO` - Torso + """, + allowableValues = ["ANKLE", "ARM", "DAMAGE", "EAR", "ELBOW", "FACE", "FIGHT", "FINGER", "FOOT", "FRONT", "HAND", "HEAD", "INCIDENT", "INJURY", "KNEE", "LEG", "LIP", "NECK", "NOSE", "SHOULDER", "THIGH", "TOE", "TORSO"], + example = "FRONT", + ) val orientation: String, + @Schema( + description = """ + Type is the contextual focus; describing the context or scenario the image was taken within. It could be for a particular purpose or capturing the results of a particular type of incident. + Possible values are: + `OFF_BKG` - Offender Booking, + `OFF_IDM` - Offender Identification Marks, + `OIC` - Offence In Custody, + `PPTY` - Property Image + """, + allowableValues = ["OFF_BKG", "OFF_IDM", "OIC", "PPTY"], + example = "OFF_BKG", + ) val type: String, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/LatestSentenceKeyDatesAndAdjustments.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/LatestSentenceKeyDatesAndAdjustments.kt index 971a27f5c..582b199b7 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/LatestSentenceKeyDatesAndAdjustments.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/LatestSentenceKeyDatesAndAdjustments.kt @@ -1,5 +1,6 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class LatestSentenceKeyDatesAndAdjustments( @@ -19,10 +20,15 @@ data class LatestSentenceKeyDatesAndAdjustments( val release: ReleaseDate? = null, val sentence: SentenceDate? = null, val topupSupervision: TopupSupervision? = null, + @Schema(description = "the offender's actual parole date", example = "2023-03-01") val actualParoleDate: LocalDate? = null, + @Schema(description = "the date on which offender will be eligible for early removal (under the Early Removal Scheme for foreign nationals).", example = "2023-03-01") val earlyRemovalSchemeEligibilityDate: LocalDate? = null, + @Schema(description = "the date on which offender will be released on temporary licence.", example = "2023-03-01") val releaseOnTemporaryLicenceDate: LocalDate? = null, + @Schema(description = "date on which minimum term is reached for parole (indeterminate/life sentences).", example = "2023-03-01") val tariffDate: LocalDate? = null, + @Schema(description = "tariffEarlyRemovalSchemeEligibilityDate.", example = "2023-03-01") val tariffEarlyRemovalSchemeEligibilityDate: LocalDate? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/MappaDetail.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/MappaDetail.kt index d41bb96e5..ba85c3bf1 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/MappaDetail.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/MappaDetail.kt @@ -1,11 +1,20 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class MappaDetail( + @Schema(example = "1") val level: Number? = null, + @Schema(example = "Description of M1") val levelDescription: String? = null, + @Schema(example = "2") val category: Number? = null, + @Schema(example = "Description of M2") val categoryDescription: String? = null, + @Schema(example = "2024-02-07") val startDate: String? = null, + @Schema(example = "2024-02-07") val reviewDate: String? = null, + @Schema(example = "Mappa Detail for X00001") val notes: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Need.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Need.kt index e1523078b..35aa46f97 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Need.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Need.kt @@ -1,8 +1,14 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class Need( + @Schema(description = "The type of need", example = "DRUG_MISUSE") val type: String? = null, + @Schema(description = "Risk of harm") val riskOfHarm: Boolean? = null, + @Schema(description = "Risk of reoffending") val riskOfReoffending: Boolean? = null, + @Schema(description = "Severity of need", example = "NO_NEED") val severity: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Needs.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Needs.kt index 186da481b..dbeeb1337 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Needs.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Needs.kt @@ -1,8 +1,10 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDateTime data class Needs( + @Schema(description = "Needs assessment completion date", example = "2023-09-05T10:15:41") val assessedOn: LocalDateTime? = null, val identifiedNeeds: List = emptyList(), val notIdentifiedNeeds: List = emptyList(), diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/NonDtoDate.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/NonDtoDate.kt index 6bb9d58b8..6ed25fd90 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/NonDtoDate.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/NonDtoDate.kt @@ -1,8 +1,21 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class NonDtoDate( + @Schema(description = "Release date for non-DTO sentence (if applicable). This will be based on one of ARD, CRD, NPD or PRRD. NonDto stands for Non-Detention training order.", example = "2023-03-01") val date: LocalDate? = null, + @Schema( + description = """ + Indicates which type of non-DTO release date is the effective release date. One of 'ARD', 'CRD', 'NPD' or 'PRRD'. Possible values are: + `ARD`, + `CRD`, + `NPD`, + `PRRD`. + """, + example = "ARD", + allowableValues = ["ARD", "CRD", "NPD", "PRRD"], + ) val releaseDateType: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/OtherRisks.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/OtherRisks.kt index e76c916ec..1c95b75fc 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/OtherRisks.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/OtherRisks.kt @@ -1,8 +1,54 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class OtherRisks( + @Schema( + description = """ + Risk of escape/abscond. Possible values are: + `YES`, + `NO`, + `DK`, + `NA` + """, + example = "YES", + allowableValues = ["YES", "NO", "DK", "NA"], + ) val escapeOrAbscond: String? = null, + @Schema( + description = """ + Risk control issues/disruptive behaviour. Possible values are: + `YES`, + `NO`, + `DK`, + `NA` + """, + example = "DK", + allowableValues = ["YES", "NO", "DK", "NA"], + ) val controlIssuesDisruptiveBehaviour: String? = null, + @Schema( + description = """ + Risk of breach of trust. Possible values are: + `YES`, + `NO`, + `DK`, + `NA` + """, + example = "NO", + allowableValues = ["YES", "NO", "DK", "NA"], + ) val breachOfTrust: String? = null, + @Schema( + description = """ + Risk to other prisoners. Possible values are: + `YES`, + `NO`, + `DK`, + `NA` + """, + example = "YES", + allowableValues = ["YES", "NO", "DK", "NA"], + ) val riskToOtherPrisoners: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Person.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Person.kt index 0b8c10448..52fad339f 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Person.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Person.kt @@ -1,21 +1,30 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps import com.fasterxml.jackson.annotation.JsonAlias +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class Person( + @Schema(description = "First name", example = "John") val firstName: String, @JsonAlias("surname") + @Schema(description = "Last name", example = "Morgan") val lastName: String, @JsonAlias("middleNames") + @Schema(description = "Middle name", example = "John") val middleName: String? = null, + @Schema(description = "Date of birth", example = "1965-12-01") val dateOfBirth: LocalDate? = null, + @Schema(description = "Gender", example = "Male") val gender: String? = null, + @Schema(description = "Ethnicity", example = "White: Eng./Welsh/Scot./N.Irish/British") val ethnicity: String? = null, @JsonAlias("offenderAliases") val aliases: List = listOf(), val identifiers: Identifiers = Identifiers(), + @Schema(description = "An identifier from the Police National Computer (PNC)") val pncId: String? = null, + @Schema(description = "HMPPS identifier", example = "2008/0545166T") val hmppsId: String? = null, val contactDetails: ContactDetailsWithEmailAndPhone? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PersonLicences.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PersonLicences.kt index 84ef38da8..89e9e3c1f 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PersonLicences.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PersonLicences.kt @@ -1,7 +1,143 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class PersonLicences( + @Schema(example = "2008/0545166T") val hmppsId: String, + @Schema(example = "Z1234ZZ") val offenderNumber: String? = null, + @Schema( + example = """ + [ + { + "status": "IN_PROGRESS", + "typeCode": "AP", + "createdDate": "2015-09-23", + "approvedDate": "2015-09-24", + "updatedDate": "2015-10-23", + "conditions": [ + { + "type": "Standard", + "code": "5a105297-dce1-4d18-b9ea-4195b46b7594", + "category": "Residence at a specific place", + "condition": "You must reside at an approved address" + }, + { + "type": "Custom", + "code": "b457e9c3-68c6-4f5e-9bd8-c36c5b7e70fb", + "category": "Contact Restrictions", + "condition": "You must not contact the victim" + } + ] + }, + { + "status": "SUBMITTED", + "typeCode": "PSS", + "createdDate": "2016-01-15", + "approvedDate": "2016-01-16", + "updatedDate": "2016-02-15", + "conditions": [ + { + "type": "Standard", + "code": "5a105297-dce1-4d18-b9ea-4195b46b7594", + "category": "Residence at a specific place", + "condition": "You must reside at an approved address" + } + ] + }, + { + "status": "APPROVED", + "typeCode": "PSS", + "createdDate": "2016-01-15", + "approvedDate": "2016-01-16", + "updatedDate": "2016-02-15", + "conditions": [ + { + "type": "Standard", + "code": "5a105297-dce1-4d18-b9ea-4195b46b7594", + "category": "Residence at a specific place", + "condition": "You must reside at an approved address" + } + ] + }, + { + "status": "ACTIVE", + "typeCode": "AP", + "createdDate": "2018-05-20", + "approvedDate": "2018-05-21", + "updatedDate": "2018-06-20", + "conditions": [ + { + "type": "Custom", + "code": "c97f33e3-1e50-4b28-8f71-5de3e2fbbf79", + "category": "Travel Restrictions", + "condition": "You must not leave the country without permission" + } + ] + }, + { + "status": "VARIATION_IN_PROGRESS", + "typeCode": "AP", + "createdDate": "2019-07-01", + "approvedDate": "2019-07-02", + "updatedDate": "2019-08-01", + "conditions": [ + { + "type": "Rehabilitation", + "code": "a5371dd7-7f54-42b9-9c3b-35f9e8f6f1e9", + "category": "Rehabilitation Program", + "condition": "You must participate in a rehabilitation program" + } + ] + }, + { + "status": "VARIATION_SUBMITTED", + "typeCode": "AP_PSS", + "createdDate": "2020-09-12", + "approvedDate": "2020-09-13", + "updatedDate": "2020-10-12", + "conditions": [ + { + "type": "Monitoring", + "code": "e4a8b9cf-4a50-44a2-8a0c-5f38d2fae6f9", + "category": "Electronic Monitoring", + "condition": "You must comply with electronic monitoring" + } + ] + }, + { + "status": "VARIATION_APPROVED", + "typeCode": "AP_PSS", + "createdDate": "2021-11-23", + "approvedDate": "2021-11-24", + "updatedDate": "2021-12-23", + "conditions": [ + { + "type": "Substance Abuse", + "code": "d4b8b1e8-9e4e-4f6a-a2df-b41e8f8e8e8e", + "category": "Alcohol Restrictions", + "condition": "You must not consume alcohol" + } + ] + }, + { + "status": "VARIATION_REJECTED", + "typeCode": "PSS", + "createdDate": "2022-01-01", + "approvedDate": "2022-01-02", + "updatedDate": "2022-02-01", + "conditions": [ + { + "type": "Association", + "code": "f9e8f1c8-2f4a-4a6a-a1de-5e7e9f7d9e8f", + "category": "Contact Restrictions", + "condition": "You must not associate with known criminals" + } + ] + } + ] + """, + ) val licences: List = emptyList(), ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PersonProtectedCharacteristics.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PersonProtectedCharacteristics.kt index 416e48c3f..cc5be2a9a 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PersonProtectedCharacteristics.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PersonProtectedCharacteristics.kt @@ -1,13 +1,22 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + class PersonProtectedCharacteristics( + @Schema(description = "Age of the person", example = "35") val age: Number, + @Schema(description = "Gender of the person", example = "Female") val gender: String?, + @Schema(description = "Sexual orientation of the person", example = "Unknown") val sexualOrientation: String?, + @Schema(description = "Ethnicity of the person", example = "White: Eng./Welsh/Scot./N.Irish/British") val ethnicity: String?, + @Schema(description = "Nationality of the person", example = "Egyptian") val nationality: String?, + @Schema(description = "Religion of the person", example = "Church of England (Anglican)") val religion: String?, val disabilities: List, + @Schema(description = "Marital status of the person", example = "Widowed") var maritalStatus: String? = null, var reasonableAdjustments: List = emptyList(), ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PhoneNumber.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PhoneNumber.kt index a04ff6cca..b005fba2c 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PhoneNumber.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/PhoneNumber.kt @@ -1,6 +1,10 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class PhoneNumber( + @Schema(description = "A phone number", example = "079123456789") val number: String? = null, + @Schema(description = "The type of number", example = "TELEPHONE") val type: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Prison.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Prison.kt index 538bfd5f6..b4ed1d860 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Prison.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Prison.kt @@ -1,5 +1,8 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class Prison( + @Schema(description = "The prison code, which is usually short for the prison name.") val code: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ReasonableAdjustment.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ReasonableAdjustment.kt index da63e8f31..b58338397 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ReasonableAdjustment.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ReasonableAdjustment.kt @@ -1,11 +1,17 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate class ReasonableAdjustment( + @Schema(description = "Treatment code", example = "WHEELCHR_ACC") val treatmentCode: String? = null, + @Schema(description = "Comment text", example = "abcd") val commentText: String? = null, + @Schema(description = "Start date", example = "2013-04-11") val startDate: LocalDate? = null, + @Schema(description = "End date", example = "2023-04-11") val endDate: LocalDate? = null, + @Schema(description = "Treatment description", example = "Wheelchair accessibility") val treatmentDescription: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ReleaseDate.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ReleaseDate.kt index e04cafbcb..2f8dbb61c 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ReleaseDate.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ReleaseDate.kt @@ -1,8 +1,21 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class ReleaseDate( + @Schema( + description = """ + Confirmed, actual, approved, provisional or calculated release date for offender, according to offender release date algorithm. + + Algorithm + If there is a confirmed release date, the offender release date is the confirmed release date. + If there is no confirmed release date for the offender, the offender release date is either the actual parole date or the home detention curfew actual date. + If there is no confirmed release date, actual parole date or home detention curfew actual date for the offender, the release date is the later of the nonDtoReleaseDate or midTermDate value (if either or both are present) + """, + example = "2023-03-01", + ) val date: LocalDate? = null, + @Schema(description = "Confirmed release date for offender.", example = "2023-03-01") val confirmedDate: LocalDate? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Risk.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Risk.kt index f1946b007..0d1e25bbd 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Risk.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Risk.kt @@ -1,9 +1,52 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class Risk( + @Schema( + description = """ + Presence of risk. Possible values are: + `YES`, + `NO`, + `DK`, + `NA` + """, + example = "YES", + allowableValues = ["YES", "NO", "DK", "NA"], + ) val risk: String? = null, + @Schema( + description = """ + Previous concerns. Possible values are: + `YES`, + `NO`, + `DK`, + `NA` + """, + example = "NO", + allowableValues = ["YES", "NO", "DK", "NA"], + ) val previous: String? = null, + @Schema( + description = "Supporting comments for any previous concerns.", + example = "Risk of self harm concerns due to ...", + ) val previousConcernsText: String? = null, + @Schema( + description = """ + Current concerns. Possible values are: + `YES`, + `NO`, + `DK`, + `NA` + """, + example = "YES", + allowableValues = ["YES", "NO", "DK", "NA"], + ) val current: String? = null, + @Schema( + description = "Supporting comments for any current concerns.", + example = "Risk of self harm concerns due to ...", + ) val currentConcernsText: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskAssessment.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskAssessment.kt index 6cbc1af31..6f546faca 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskAssessment.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskAssessment.kt @@ -1,13 +1,24 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class RiskAssessment( + @Schema(description = "The classification code of the risk", example = "C") val classificationCode: String? = null, + @Schema(description = "The classification of the code", example = "Cat C") val classification: String? = null, + @Schema(description = "The assessment code", example = "CATEGORY") val assessmentCode: String? = null, + @Schema(description = "The description of the assessment", example = "Categorisation") val assessmentDescription: String? = null, + @Schema(description = "The date of the assessment", example = "2018-02-11") val assessmentDate: String? = null, + @Schema(description = "Next review date", example = "2018-02-11") val nextReviewDate: String? = null, + @Schema(description = "Agency ID of the assessment", example = "MDI") val assessmentAgencyId: String? = null, + @Schema(description = "The status of the assessment", example = "P") val assessmentStatus: String? = null, + @Schema(description = "Comments regarding the assessment", example = "Comment details") val assessmentComment: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskManagementPlan.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskManagementPlan.kt index df2fc5b87..4c7dfe559 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskManagementPlan.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskManagementPlan.kt @@ -1,18 +1,34 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class RiskManagementPlan( + @Schema(description = "The unique ID of the risk management plan", example = "123456") val assessmentId: String, + @Schema(description = "The date that the risk management plan was completed", example = "2024-05-04T01:04:20") val dateCompleted: String, + @Schema(description = "The date of plan initiation", example = "2024-05-04T01:04:20") val initiationDate: String, + @Schema(description = "The status of the plan", example = "COMPLETE") val assessmentStatus: String, + @Schema(description = "The type of assessment") val assessmentType: String, + @Schema(description = "Key information about the current situation of the subject being assessed") val keyInformationCurrentSituation: String, + @Schema(description = "Further considerations about the situation of the subject being assessed") val furtherConsiderationsCurrentSituation: String, + @Schema(description = "Who they see, when and why, any support they get from their community, and how well they're desisting from problematic behaviour") val supervision: String, + @Schema(description = "Information on restrictions in place to prevent reoffending, what steps have been taken to monitor potential reoffending, including license conditions, community order requirements, PPM restrictions and such.") val monitoringAndControl: String, + @Schema(description = "Interventions delivered to develop controls and protective factors to reduce risk of reoffending, including practical support, requirements to support interventions and details of who and where these interventions will be administered.") val interventionsAndTreatment: String, + @Schema(description = "Restrictions in place to specifically protect victims of, adults known to, and children potentially at risk from the offender.") val victimSafetyPlanning: String, + @Schema(description = "Future plans in the form \"If X happens, we will do Y....\" for if parts of the risk management plan break down or requirements or restrictions are breached by the offender.") val contingencyPlans: String, + @Schema(description = "An assessment is considered 'Signed and locked' once it is signed by the assessor, making the plan read-only. This is the date the plan has been signed by the assessor.", example = "2024-05-04T01:04:20") val latestSignLockDate: String, + @Schema(description = "Once a countersignature has been applied to the plan, the plan is considered complete. This is the date the plan has been countersigned.", example = "2024-05-04T01:04:20") val latestCompleteDate: String, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskOfSeriousRecidivism.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskOfSeriousRecidivism.kt index 9a9e3fdbf..cd763daf1 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskOfSeriousRecidivism.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskOfSeriousRecidivism.kt @@ -1,5 +1,19 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class RiskOfSeriousRecidivism( + @Schema( + description = """ + Indicator for risk of serious recidivism. Possible values are: + `LOW`, + `MEDIUM`, + `HIGH`, + `VERY_HIGH`, + `NOT_APPLICABLE` + """, + example = "MEDIUM", + allowableValues = ["LOW", "MEDIUM", "HIGH", "VERY_HIGH", "NOT_APPLICABLE"], + ) val scoreLevel: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskPredictorScore.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskPredictorScore.kt index 76056a06a..87144a6a6 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskPredictorScore.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskPredictorScore.kt @@ -1,9 +1,20 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDateTime data class RiskPredictorScore( + @Schema(description = "Risk scores calculation completion date", example = "2023-09-05T10:15:41") val completedDate: LocalDateTime? = null, + @Schema( + description = """ + Whether the risk score calculation is complete. Possible values are: + `COMPLETE`, + `LOCKED_INCOMPLETE` + """, + example = "COMPLETED", + allowableValues = ["COMPLETED", "LOCKED_INCOMPLETE"], + ) val assessmentStatus: String? = null, val generalPredictor: GeneralPredictor = GeneralPredictor(), val violencePredictor: ViolencePredictor = ViolencePredictor(), diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskSummary.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskSummary.kt index 23981ecee..128a14704 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskSummary.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/RiskSummary.kt @@ -1,12 +1,44 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class RiskSummary( + @Schema(description = "Who is at risk", example = "X, Y and Z are at risk") val whoIsAtRisk: String? = null, + @Schema(description = "What is the nature of the risk", example = "The nature of the risk is X") val natureOfRisk: String? = null, + @Schema(description = "When is the risk likely to be greatest. Consider the timescale and indicate whether risk is immediate or not. Consider the risks in custody as well as on release.", example = "The risk is imminent and more probable in X situation") val riskImminence: String? = null, + @Schema(description = "What circumstances are likely to increase risk. Describe factors, actions, events which might increase level of risk, now and in the future.", example = "If offender in situation X the risk can be higher") val riskIncreaseFactors: String? = null, + @Schema(description = "What factors are likely to reduce the risk. Describe factors, actions, and events which may reduce or contain the level of risk. What has previously stopped them?", example = "Giving offender therapy in X will reduce the risk") val riskMitigationFactors: String? = null, + @Schema(description = "The overall risk level", example = "HIGH", allowableValues = ["VERY_HIGH", "HIGH", "MEDIUM", "LOW"]) val overallRiskLevel: String? = null, + @Schema( + description = "Assess the risk of serious harm the offender poses on the basis that they could be released imminently back into the community. This field is a map which can return all or some of the properties given.", + example = """ + { + "children": "HIGH", + "public": "MEDIUM", + "knownAdult": "VERY_HIGH", + "staff": "HIGH", + "prisoners": "LOW" + } + """, + ) val riskInCommunity: Map? = null, + @Schema( + description = "Assess both the risk of serious harm the offender presents now, in custody, and the risk they could present to others whilst in a custodial setting. This field is a map which can return all or some of the properties given.", + example = """ + { + "children": "HIGH", + "public": "MEDIUM", + "knownAdult": "VERY_HIGH", + "staff": "HIGH", + "prisoners": "LOW" + } + """, + ) val riskInCustody: Map? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Risks.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Risks.kt index dd3596570..7871bbf59 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Risks.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Risks.kt @@ -1,8 +1,10 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDateTime data class Risks( + @Schema(description = "Date of risk assessment", example = "2023-09-05T10:15:41") val assessedOn: LocalDateTime? = null, val riskToSelf: RiskToSelf = RiskToSelf(), val otherRisks: OtherRisks = OtherRisks(), diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Sentence.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Sentence.kt index e79d6cbf0..1975da46e 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Sentence.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Sentence.kt @@ -1,14 +1,38 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class Sentence( + @Schema( + description = """ + Which upstream API service the sentence originates from. Possible values are: + `NOMIS`, + `NDELIUS` + """, + example = "NOMIS", + allowableValues = ["NOMIS", "NDELIUS"], + ) val serviceSource: UpstreamApi, + @Schema( + description = """ + Which upstream API system the sentence originates from. Possible values are: + `PRISON_SYSTEMS`, + `PROBATION_SYSTEMS` + """, + example = "PROBATION_SYSTEMS", + allowableValues = ["PRISON_SYSTEMS", "PROBATION_SYSTEMS"], + ) val systemSource: SystemSource, + @Schema(description = "Date of sentencing", example = "2009-09-09") val dateOfSentencing: LocalDate? = null, + @Schema(description = "Description of the sentence", example = "Young Offender Inst - >=12 mths") val description: String? = null, + @Schema(description = "Whether the sentence is active", example = "true") val isActive: Boolean? = null, + @Schema(description = "Whether the sentence is custodial", example = "true") val isCustodial: Boolean, + @Schema(description = "The amount of fine related to the sentence and offence", example = "480.59") val fineAmount: Number? = null, val length: SentenceLength = SentenceLength(), ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceAdjustment.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceAdjustment.kt index 4da3ad731..40ca3f590 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceAdjustment.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceAdjustment.kt @@ -1,14 +1,26 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class SentenceAdjustment( + @Schema(description = "Number of additional days awarded", example = "10") val additionalDaysAwarded: Number? = null, + @Schema(description = "Number unlawfully at large days", example = "16") val unlawfullyAtLarge: Number? = null, + @Schema(description = "Number of lawfully at large days", example = "11") val lawfullyAtLarge: Number? = null, + @Schema(description = "Number of restored additional days awarded", example = "20") val restoredAdditionalDaysAwarded: Number? = null, + @Schema(description = "Number of special remission days", example = "14") val specialRemission: Number? = null, + @Schema(description = "Number of recall sentence remand days", example = "7") val recallSentenceRemand: Number? = null, + @Schema(description = "Number of recall sentence tagged bail days", example = "19") val recallSentenceTaggedBail: Number? = null, + @Schema(description = "Number of remand days", example = "3") val remand: Number? = null, + @Schema(description = "Number of tagged bail days", example = "13") val taggedBail: Number? = null, + @Schema(description = "Number of unused remand days", example = "13") val unusedRemand: Number? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceDate.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceDate.kt index 2707d76ac..665aa0dbc 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceDate.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceDate.kt @@ -1,11 +1,17 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class SentenceDate( + @Schema(description = "Effective sentence end date.", example = "2023-03-01") val effectiveEndDate: LocalDate? = null, + @Schema(description = "date on which sentence expired (as calculated by NOMIS).", example = "2023-03-01") val expiryCalculatedDate: LocalDate? = null, + @Schema(description = "date on which sentence expires.", example = "2023-03-01") val expiryDate: LocalDate? = null, + @Schema(description = "date on which sentence expires (override).", example = "2023-03-01") val expiryOverrideDate: LocalDate? = null, + @Schema(description = "Sentence start date.", example = "2023-03-01") val startDate: LocalDate? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceKeyDate.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceKeyDate.kt index 67b136c81..a06580a47 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceKeyDate.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceKeyDate.kt @@ -1,7 +1,11 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps + +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class SentenceKeyDate( + @Schema(description = "release date for offender", example = "2023-03-01") val date: LocalDate? = null, + @Schema(description = "release override date for offender", example = "2023-03-01") val overrideDate: LocalDate? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceKeyDateWithCalculatedDate.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceKeyDateWithCalculatedDate.kt index 0e21909f3..2e1b269a8 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceKeyDateWithCalculatedDate.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceKeyDateWithCalculatedDate.kt @@ -1,9 +1,13 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class SentenceKeyDateWithCalculatedDate( + @Schema(description = "release date for offender", example = "2023-03-01") val date: LocalDate? = null, + @Schema(description = "release override date for offender", example = "2023-03-01") val overrideDate: LocalDate? = null, + @Schema(description = "release calculated date for offender", example = "2023-03-01") val calculatedDate: LocalDate? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceLength.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceLength.kt index 1e7b097e8..5539975cc 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceLength.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceLength.kt @@ -1,7 +1,22 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class SentenceLength( + @Schema(description = "Duration of the sentence", example = "10") val duration: Int? = null, + @Schema( + description = """ + Time unit that is used in combination with the duration field. Possible values are: + `Hours`, + `Days`, + `Weeks`, + `Months`, + `Years` + """, + example = "Hours", + allowableValues = ["Hours", "Days", "Weeks", "Months", "Years"], + ) val units: String? = null, val terms: List = emptyList(), ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceTerm.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceTerm.kt index 59880ff08..8db2b3c37 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceTerm.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SentenceTerm.kt @@ -1,10 +1,38 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class SentenceTerm( + @Schema(description = "Number of years in the term", example = "5") val years: Int? = null, + @Schema(description = "Number of months in the term", example = "4") val months: Int? = null, + @Schema(description = "Number of weeks in the term", example = "3") val weeks: Int? = null, + @Schema(description = "Number of days in the term", example = "2") val days: Int? = null, + @Schema(description = "Number of hours in the term", example = "1") val hours: Int? = null, + @Schema( + description = """ + The sentence term code + Possible values are: + `CUR` - Curfew Period, + `DEF` - Deferment Period, + `DET` - Detention, + `HOURS` - Hours Ordered, + `IMP` - Imprisonment, + `LIC` - Licence, + `PSYCH` - Psychiatric Hospital, + `SCUS` - Custodial Period, + `SEC104` - Breach of supervision requirements, + `SEC105` - Breach due to imprisonable offence, + `SEC86` - Section 86 of 2000 Act, + `SUP` - Sentence Length, + `SUSP` - Suspension Period + """, + example = "IMP", + allowableValues = ["CUR", "DEF", "DET", "HOURS", "IMP", "LIC", "PSYCH", "SCUS", "SEC104", "SEC105", "SEC86", "SUP", "SUSP"], + ) val prisonTermCode: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SexualPredictor.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SexualPredictor.kt index adf916320..e8291434a 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SexualPredictor.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/SexualPredictor.kt @@ -1,6 +1,32 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class SexualPredictor( + @Schema( + description = """ + Indicator for risk of sexual indecency. Possible values are: + `LOW`, + `MEDIUM`, + `HIGH`, + `VERY_HIGH`, + `NOT_APPLICABLE`, + """, + example = "MEDIUM", + allowableValues = ["LOW", "MEDIUM", "HIGH", "VERY_HIGH", "NOT_APPLICABLE"], + ) val indecentScoreLevel: String? = null, + @Schema( + description = """ + Indicator for risk of sexual contact. Possible values are: + `LOW`, + `MEDIUM`, + `HIGH`, + `VERY_HIGH`, + `NOT_APPLICABLE`, + """, + example = "MEDIUM", + allowableValues = ["LOW", "MEDIUM", "HIGH", "VERY_HIGH", "NOT_APPLICABLE"], + ) val contactScoreLevel: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/StatusInformation.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/StatusInformation.kt index f8258d63a..854dcced6 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/StatusInformation.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/StatusInformation.kt @@ -1,9 +1,16 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class StatusInformation( + @Schema(example = "ASFO") val code: String? = null, + @Schema(example = "Serious Further Offence - Subject to SFO review/investigation") val description: String? = null, + @Schema(example = "2022-01-01") val startDate: String? = null, + @Schema(example = "2025-01-01") val reviewDate: String? = null, + @Schema(example = "This is a note") val notes: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/TopupSupervision.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/TopupSupervision.kt index 5bf08c06f..2b0c02a12 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/TopupSupervision.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/TopupSupervision.kt @@ -1,10 +1,15 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema import java.time.LocalDate data class TopupSupervision( + @Schema(description = "(calculated) - top-up supervision expiry date for offender.", example = "2023-03-01") val expiryCalculatedDate: LocalDate? = null, + @Schema(description = "top-up supervision expiry date for offender.", example = "2023-03-01") val expiryDate: LocalDate? = null, + @Schema(description = "(override) - top-up supervision expiry date for offender.", example = "2023-03-01") val expiryOverrideDate: LocalDate? = null, + @Schema(description = "Top-up supervision start date for offender - calculated as licence end date + 1 day or releaseDate if licence end date not set.", example = "2023-03-01") val startDate: LocalDate? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ViolencePredictor.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ViolencePredictor.kt index 36ec4bebf..131639af7 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ViolencePredictor.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/ViolencePredictor.kt @@ -1,5 +1,19 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps +import io.swagger.v3.oas.annotations.media.Schema + data class ViolencePredictor( + @Schema( + description = """ + Indicator for risk of violence. Possible values are: + `LOW`, + `MEDIUM`, + `HIGH`, + `VERY_HIGH`, + `NOT_APPLICABLE` + """, + example = "MEDIUM", + allowableValues = ["LOW", "MEDIUM", "HIGH", "VERY_HIGH", "NOT_APPLICABLE"], + ) val scoreLevel: String? = null, ) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/util/PaginatedResponse.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/util/PaginatedResponse.kt index 8aa1baad1..a7a76ce12 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/util/PaginatedResponse.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/util/PaginatedResponse.kt @@ -1,17 +1,31 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.util +import io.swagger.v3.oas.annotations.media.Schema import org.springframework.data.domain.Page -class PaginatedResponse(pageableResponse: Page) { +class PaginatedResponse( + @Schema(hidden = true) pageableResponse: Page, +) { val data: List = pageableResponse.content val pagination: Pagination = Pagination(pageableResponse) inner class Pagination(pageableResponse: Page) { + @Schema(description = "Is the current page the last one?", example = "true") val isLastPage: Boolean = pageableResponse.isLast + + @Schema(description = "The number of results in `data` for the current page", example = "1") val count: Int = pageableResponse.numberOfElements + + @Schema(description = "The current page number", example = "1") val page: Int = pageableResponse.number + 1 + + @Schema(description = "The maximum number of results in `data` for a page", example = "10") val perPage: Int = pageableResponse.size + + @Schema(description = "The total number of results in `data` across all pages", example = "1") val totalCount: Long = pageableResponse.totalElements + + @Schema(description = "The total number of pages", example = "1") val totalPages: Int = pageableResponse.totalPages } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9c929cb2b..513463a57 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -18,6 +18,9 @@ spring: test: - "stdout" +springdoc: + default-produces-media-type: application/json + server: port: 8080 servlet: From 42e1392ea68f8f7e7b13b6f55bbcd1f5d6947554 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Fri, 16 Aug 2024 15:35:17 +0000 Subject: [PATCH 2/4] Exclude errors from response if none populated --- .../controllers/v1/HmppsIdController.kt | 6 +++--- .../controllers/v1/person/AddressController.kt | 6 +++--- .../controllers/v1/person/CellLocationController.kt | 6 +++--- .../v1/person/LicenceConditionController.kt | 6 +++--- .../controllers/v1/person/MappaDetailController.kt | 6 +++--- .../controllers/v1/person/NeedsController.kt | 6 +++--- .../controllers/v1/person/PersonController.kt | 10 +++++----- .../v1/person/PersonResponsibleOfficerController.kt | 6 +++--- .../v1/person/ProtectedCharacteristicsController.kt | 6 +++--- .../controllers/v1/person/RiskCategoriesController.kt | 6 +++--- .../controllers/v1/person/RiskSeriousHarmController.kt | 6 +++--- .../controllers/v1/person/SentencesController.kt | 6 +++--- .../hmpps/hmppsintegrationapi/models/hmpps/Response.kt | 7 ++++++- 13 files changed, 44 insertions(+), 39 deletions(-) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/HmppsIdController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/HmppsIdController.kt index 3a5cf47c8..9a46d176f 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/HmppsIdController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/HmppsIdController.kt @@ -8,8 +8,8 @@ import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.HmppsId -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetHmppsIdService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @@ -24,7 +24,7 @@ class HmppsIdController( @GetMapping("nomis-number/{encodedNomisNumber}") fun getHmppsIdByNomisNumber( @PathVariable encodedNomisNumber: String, - ): Response { + ): DataResponse { val nomisNumber = encodedNomisNumber.decodeUrlCharacters() val response = getHmppsIdService.execute(nomisNumber) @@ -35,6 +35,6 @@ class HmppsIdController( auditService.createEvent("GET_HMPPS_ID_BY_NOMIS_NUMBER", mapOf("nomisNumber" to nomisNumber)) - return Response(response.data) + return DataResponse(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt index 1c719e190..9661cfea8 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt @@ -15,7 +15,7 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Com import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Address -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetAddressesForPersonService @@ -39,7 +39,7 @@ class AddressController( ) fun getPersonAddresses( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response> { + ): DataResponse> { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getAddressesForPersonService.execute(hmppsId) @@ -50,6 +50,6 @@ class AddressController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_ADDRESS", mapOf("hmppsId" to hmppsId)) - return Response(response.data) + return DataResponse(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt index 222dd2414..78f96b817 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt @@ -11,7 +11,7 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Com import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CellLocation -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCellLocationForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @@ -26,7 +26,7 @@ class CellLocationController( @GetMapping("{encodedHmppsId}/cell-location") fun getPersonCellLocation( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response { + ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getCellLocationForPersonService.execute(hmppsId) @@ -37,6 +37,6 @@ class CellLocationController( auditService.createEvent("GET_PERSON_CELL_LOCATION", mapOf("hmppsId" to hmppsId)) - return Response(response.data) + return DataResponse(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt index 230e322b7..8132563a9 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt @@ -14,8 +14,8 @@ import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PersonLicences -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetLicenceConditionService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @@ -38,7 +38,7 @@ class LicenceConditionController( ) fun getLicenceConditions( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response { + ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getLicenceConditionService.execute(hmppsId) @@ -46,6 +46,6 @@ class LicenceConditionController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_LICENCE_CONDITION", mapOf("hmppsId" to hmppsId)) - return Response(response.data) + return DataResponse(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt index 8c47e5265..0f484da70 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt @@ -14,8 +14,8 @@ import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.MappaDetail -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetMappaDetailForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @@ -38,7 +38,7 @@ class MappaDetailController( ) fun getMappaDetail( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response { + ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getMappaDetailForPersonService.execute(hmppsId) @@ -46,6 +46,6 @@ class MappaDetailController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_MAPPA_DETAIL", mapOf("hmppsId" to hmppsId)) - return Response(response.data) + return DataResponse(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt index edd68a1cc..fd4b1eb15 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt @@ -14,8 +14,8 @@ import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Needs -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetNeedsForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @@ -43,7 +43,7 @@ class NeedsController( ) fun getPersonNeeds( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response { + ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getNeedsForPersonService.execute(hmppsId) @@ -51,6 +51,6 @@ class NeedsController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_NEED", mapOf("hmppsId" to hmppsId)) - return Response(response.data) + return DataResponse(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt index 80ad0a3b7..ccbc30fea 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt @@ -18,10 +18,10 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Com import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.ImageMetadata import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Person import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PersonName -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError.Type.ENTITY_NOT_FOUND @@ -95,7 +95,7 @@ class PersonController( ) fun getPerson( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response> { + ): DataResponse> { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getPersonService.getCombinedDataForPerson(hmppsId) @@ -105,7 +105,7 @@ class PersonController( auditService.createEvent("GET_PERSON_DETAILS", mapOf("hmppsId" to hmppsId)) val data = response.data.mapValues { it.value } - return Response(data) + return DataResponse(data) } @GetMapping("{encodedHmppsId}/images") @@ -145,7 +145,7 @@ class PersonController( ) fun getPersonName( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response { + ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getNameForPersonService.execute(hmppsId) @@ -156,7 +156,7 @@ class PersonController( auditService.createEvent("GET_PERSON_NAME", mapOf("hmppsId" to hmppsId)) - return Response(response.data) + return DataResponse(response.data) } private fun isValidISODateFormat(dateString: String): Boolean { diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt index f7b237013..5ad16c297 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt @@ -14,8 +14,8 @@ import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PersonResponsibleOfficer -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetCommunityOffenderManagerForPersonService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetPrisonOffenderManagerForPersonService @@ -40,7 +40,7 @@ class PersonResponsibleOfficerController( ) fun getPersonResponsibleOfficer( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response { + ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val prisonOffenderManager = getPrisonOffenderManagerForPersonService.execute(hmppsId) val communityOffenderManager = getCommunityOffenderManagerForPersonService.execute(hmppsId) @@ -60,6 +60,6 @@ class PersonResponsibleOfficerController( ) auditService.createEvent("GET_PERSON_RESPONSIBLE_OFFICER", mapOf("hmppsId" to hmppsId)) - return Response(mergedData) + return DataResponse(mergedData) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt index b0f54ae60..48feb2bb9 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt @@ -14,8 +14,8 @@ import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.PersonProtectedCharacteristics -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetProtectedCharacteristicsService import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.internal.AuditService @@ -38,7 +38,7 @@ class ProtectedCharacteristicsController( ) fun getPersonAddresses( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response { + ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getProtectedCharacteristicsService.execute(hmppsId) @@ -46,6 +46,6 @@ class ProtectedCharacteristicsController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_PROTECTED_CHARACTERISTICS", mapOf("hmppsId" to hmppsId)) - return Response(response.data) + return DataResponse(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt index 1e0ae1f1d..29f6aa96c 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt @@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.RiskCategory import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetRiskCategoriesForPersonService @@ -38,7 +38,7 @@ class RiskCategoriesController( ) fun getPersonRiskCategories( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response { + ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getRiskCategoriesForPersonService.execute(hmppsId) @@ -46,6 +46,6 @@ class RiskCategoriesController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_RISK_CATEGORIES", mapOf("hmppsId" to hmppsId)) - return Response(response.data) + return DataResponse(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt index cd3bfc3f7..630753ade 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt @@ -14,7 +14,7 @@ import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Risks import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError import uk.gov.justice.digital.hmpps.hmppsintegrationapi.services.GetRiskSeriousHarmForPersonService @@ -38,7 +38,7 @@ class RiskSeriousHarmController( ) fun getPersonRiskSeriousHarm( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response { + ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getRiskSeriousHarmForPersonService.execute(hmppsId) @@ -46,6 +46,6 @@ class RiskSeriousHarmController( throw EntityNotFoundException("Could not find person with id: $hmppsId") } auditService.createEvent("GET_PERSON_RISK", mapOf("hmppsId" to hmppsId)) - return Response(response.data) + return DataResponse(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt index 9be9abd70..7b1da5236 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt @@ -17,8 +17,8 @@ import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Com import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters +import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.LatestSentenceKeyDatesAndAdjustments -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Response import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Sentence import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApi import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.UpstreamApiError @@ -71,7 +71,7 @@ class SentencesController( ) fun getPersonLatestSentenceKeyDatesAndAdjustments( @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - ): Response { + ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getLatestSentenceKeyDatesAndAdjustmentsForPersonService.execute(hmppsId) @@ -82,6 +82,6 @@ class SentencesController( "GET_PERSON_SENTENCES_LATEST_KEY_DATES_AND_ADJUSTMENTS", mapOf("hmppsId" to hmppsId), ) - return Response(response.data) + return DataResponse(response.data) } } diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Response.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Response.kt index 325451057..3a494edea 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Response.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Response.kt @@ -1,6 +1,9 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps -data class Response(val data: T, val errors: List = emptyList()) { +data class Response( + val data: T, + val errors: List = emptyList(), +) { companion object { fun merge(responses: List>>): Response> = Response(data = responses.flatMap { it.data }, errors = responses.flatMap { it.errors }) } @@ -12,3 +15,5 @@ data class Response(val data: T, val errors: List = emptyLi causedBy: UpstreamApi, ): Boolean = this.errors.any { it.type == type && it.causedBy == causedBy } } + +data class DataResponse(val data: T) From f6157c9ad75914ccef0071e40eb8a04fdfd70b29 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Fri, 16 Aug 2024 15:39:21 +0000 Subject: [PATCH 3/4] ktlint! --- .../hmpps/hmppsintegrationapi/models/hmpps/Response.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Response.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Response.kt index 3a494edea..0b7cb7c66 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Response.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/models/hmpps/Response.kt @@ -1,9 +1,6 @@ package uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps -data class Response( - val data: T, - val errors: List = emptyList(), -) { +data class Response(val data: T, val errors: List = emptyList()) { companion object { fun merge(responses: List>>): Response> = Response(data = responses.flatMap { it.data }, errors = responses.flatMap { it.errors }) } From 12cd9ebb24610ec6097e2697d6a948e0e84583e5 Mon Sep 17 00:00:00 2001 From: Marcus Aspin Date: Fri, 16 Aug 2024 16:15:00 +0000 Subject: [PATCH 4/4] Remove re-usable parameters causes OpenAPI validation failures --- .../config/OpenAPIConfig.kt | 35 ------------------- .../v1/RiskManagementController.kt | 9 ++--- .../v1/person/AddressController.kt | 3 +- .../v1/person/AdjudicationsController.kt | 9 ++--- .../controllers/v1/person/AlertsController.kt | 15 ++++---- .../v1/person/CaseNotesController.kt | 3 +- .../v1/person/CellLocationController.kt | 3 +- .../v1/person/DynamicRisksController.kt | 9 ++--- .../v1/person/LicenceConditionController.kt | 3 +- .../v1/person/MappaDetailController.kt | 3 +- .../controllers/v1/person/NeedsController.kt | 3 +- .../v1/person/OffencesController.kt | 9 ++--- .../controllers/v1/person/PersonController.kt | 17 ++++----- .../PersonResponsibleOfficerController.kt | 3 +- .../ProtectedCharacteristicsController.kt | 3 +- .../v1/person/RiskCategoriesController.kt | 3 +- .../person/RiskPredictorScoresController.kt | 9 ++--- .../v1/person/RiskSeriousHarmController.kt | 3 +- .../v1/person/SentencesController.kt | 11 +++--- .../v1/person/StatusInformationController.kt | 9 ++--- src/main/resources/application.yml | 1 + 21 files changed, 46 insertions(+), 117 deletions(-) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/config/OpenAPIConfig.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/config/OpenAPIConfig.kt index 3dea47a14..506bd18d4 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/config/OpenAPIConfig.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/config/OpenAPIConfig.kt @@ -10,12 +10,10 @@ import io.swagger.v3.oas.annotations.security.SecurityScheme import io.swagger.v3.oas.annotations.servers.Server import io.swagger.v3.oas.models.OpenAPI import io.swagger.v3.oas.models.media.Schema -import io.swagger.v3.oas.models.parameters.Parameter import org.springdoc.core.customizers.GlobalOpenApiCustomizer import org.springdoc.core.customizers.OpenApiCustomizer import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration -import java.math.BigDecimal @OpenAPIDefinition( info = @@ -51,44 +49,11 @@ import java.math.BigDecimal ) @Configuration class OpenAPIConfig { - companion object { - const val HMPPS_ID = "#components/parameters/hmppsId" - const val PAGE = "#components/parameters/page" - const val PER_PAGE = "#components/parameters/perPage" - } - @Bean fun openApiCustomizer(): OpenApiCustomizer = object : GlobalOpenApiCustomizer { override fun customise(openApi: OpenAPI) { openApi.components - .addParameters( - "hmppsId", - Parameter() - .name("hmppsId") - .description("A URL-encoded HMPPS identifier") - .example("2008%2F0545166T") - .schema(Schema().type("string")) - .`in`("path") - .required(true), - ) - .addParameters( - "page", - Parameter() - .name("page") - .description("The page number (starting from 1)") - .schema(Schema().type("number").minimum(BigDecimal.ONE)._default(1)) - .`in`("query") - .required(false), - ) - .addParameters( - "perPage", - Parameter().name("perPage") - .description("The maximum number of results for a page") - .schema(Schema().type("number").minimum(BigDecimal.ONE)._default(10)) - .`in`("query") - .required(false), - ) .addSchemas( "BadRequest", Schema() diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/RiskManagementController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/RiskManagementController.kt index 5f1fa28f2..44d365205 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/RiskManagementController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/RiskManagementController.kt @@ -13,9 +13,6 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.AuthorisationConfig -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.RiskManagementPlan @@ -43,9 +40,9 @@ class RiskManagementController( ], ) fun getRiskManagementPlans( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, + @Parameter(description = "The page number (starting from 1)", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(description = "The maximum number of results for a page", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getRiskManagementPlansForCrnService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt index 9661cfea8..83c61da5b 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AddressController.kt @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Address @@ -38,7 +37,7 @@ class AddressController( ], ) fun getPersonAddresses( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse> { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getAddressesForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AdjudicationsController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AdjudicationsController.kt index 83b69d7b3..5c08e76a6 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AdjudicationsController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AdjudicationsController.kt @@ -12,9 +12,6 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Adjudication @@ -41,9 +38,9 @@ class AdjudicationsController( ], ) fun getPersonAdjudications( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "8", name = "perPage") perPage: Int, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, + @Parameter(description = "The page number (starting from 1)", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(description = "The maximum number of results for a page", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "8", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getAdjudicationsForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AlertsController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AlertsController.kt index 8f43f49e0..693ac18c2 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AlertsController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/AlertsController.kt @@ -13,9 +13,6 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Alert @@ -42,9 +39,9 @@ class AlertsController( ], ) fun getPersonAlerts( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, + @Parameter(description = "The page number (starting from 1)", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(description = "The maximum number of results for a page", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getAlertsForPersonService.execute(hmppsId) @@ -66,9 +63,9 @@ class AlertsController( ], ) fun getPersonAlertsPND( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, + @Parameter(description = "The page number (starting from 1)", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(description = "The maximum number of results for a page", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getAlertsForPersonService.getAlertsForPnd(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt index 1bd446bdc..2bce0c360 100755 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CaseNotesController.kt @@ -13,7 +13,6 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.filters.CaseNoteFilter @@ -43,7 +42,7 @@ class CaseNotesController( ], ) fun getCaseNotesForPerson( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, @Parameter(description = "Filter case notes from this date") @RequestParam(required = false, name = "startDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt index 78f96b817..785bd3567 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/CellLocationController.kt @@ -7,7 +7,6 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.CellLocation @@ -25,7 +24,7 @@ class CellLocationController( ) { @GetMapping("{encodedHmppsId}/cell-location") fun getPersonCellLocation( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/DynamicRisksController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/DynamicRisksController.kt index b6fca85a7..619412111 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/DynamicRisksController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/DynamicRisksController.kt @@ -13,9 +13,6 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DynamicRisk @@ -42,9 +39,9 @@ class DynamicRisksController( ], ) fun getDynamicRisks( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, + @Parameter(description = "The page number (starting from 1)", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(description = "The maximum number of results for a page", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getDynamicRisksForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt index 8132563a9..bfd6b799e 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/LicenceConditionController.kt @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse @@ -37,7 +36,7 @@ class LicenceConditionController( ], ) fun getLicenceConditions( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getLicenceConditionService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt index 0f484da70..3471738a8 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/MappaDetailController.kt @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse @@ -37,7 +36,7 @@ class MappaDetailController( ], ) fun getMappaDetail( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getMappaDetailForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt index fd4b1eb15..58a408c00 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/NeedsController.kt @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse @@ -42,7 +41,7 @@ class NeedsController( ], ) fun getPersonNeeds( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getNeedsForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/OffencesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/OffencesController.kt index 1bb876dc9..6c01a7d82 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/OffencesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/OffencesController.kt @@ -13,9 +13,6 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.Offence @@ -92,9 +89,9 @@ class OffencesController( ], ) fun getPersonOffences( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, + @Parameter(description = "The page number (starting from 1)", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(description = "The maximum number of results for a page", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getOffencesForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt index ccbc30fea..16e2a836d 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonController.kt @@ -13,9 +13,6 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse @@ -64,8 +61,8 @@ class PersonController( @Parameter(description = "A URL-encoded pnc identifier") @RequestParam(required = false, name = "pnc_number") pncNumber: String?, @Parameter(description = "The date of birth of the person") @RequestParam(required = false, name = "date_of_birth") dateOfBirth: String?, @Parameter(description = "Whether to return results that match the search criteria within the aliases of a person.") @RequestParam(required = false, defaultValue = "false", name = "search_within_aliases") searchWithinAliases: Boolean, - @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(description = "The page number (starting from 1)", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(description = "The maximum number of results for a page", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { if (firstName == null && lastName == null && pncNumber == null && dateOfBirth == null) { throw ValidationException("No query parameters specified.") @@ -94,7 +91,7 @@ class PersonController( ], ) fun getPerson( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse> { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getPersonService.getCombinedDataForPerson(hmppsId) @@ -118,9 +115,9 @@ class PersonController( ], ) fun getPersonImages( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, + @Parameter(description = "The page number (starting from 1)", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(description = "The maximum number of results for a page", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() @@ -144,7 +141,7 @@ class PersonController( ], ) fun getPersonName( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt index 5ad16c297..ca05a68f4 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/PersonResponsibleOfficerController.kt @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse @@ -39,7 +38,7 @@ class PersonResponsibleOfficerController( ], ) fun getPersonResponsibleOfficer( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val prisonOffenderManager = getPrisonOffenderManagerForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt index 48feb2bb9..222e3a150 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/ProtectedCharacteristicsController.kt @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse @@ -37,7 +36,7 @@ class ProtectedCharacteristicsController( ], ) fun getPersonAddresses( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getProtectedCharacteristicsService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt index 29f6aa96c..f871a6015 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskCategoriesController.kt @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse @@ -37,7 +36,7 @@ class RiskCategoriesController( ], ) fun getPersonRiskCategories( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getRiskCategoriesForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskPredictorScoresController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskPredictorScoresController.kt index d7bb1134d..168e1a8e6 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskPredictorScoresController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskPredictorScoresController.kt @@ -12,9 +12,6 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.RiskPredictorScore @@ -41,9 +38,9 @@ class RiskPredictorScoresController( ], ) fun getPersonRiskPredictorScores( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, + @Parameter(description = "The page number (starting from 1)", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(description = "The maximum number of results for a page", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getRiskPredictorScoresForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt index 630753ade..93ff21bd3 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/RiskSeriousHarmController.kt @@ -11,7 +11,6 @@ import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse @@ -37,7 +36,7 @@ class RiskSeriousHarmController( ], ) fun getPersonRiskSeriousHarm( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getRiskSeriousHarmForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt index 7b1da5236..d948fad9b 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/SentencesController.kt @@ -12,9 +12,6 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.DataResponse @@ -46,9 +43,9 @@ class SentencesController( ], ) fun getPersonSentences( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, + @Parameter(description = "The page number (starting from 1)", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(description = "The maximum number of results for a page", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getSentencesForPersonService.execute(hmppsId) @@ -70,7 +67,7 @@ class SentencesController( ], ) fun getPersonLatestSentenceKeyDatesAndAdjustments( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, ): DataResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getLatestSentenceKeyDatesAndAdjustmentsForPersonService.execute(hmppsId) diff --git a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/StatusInformationController.kt b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/StatusInformationController.kt index f186319d4..ae6c49b0c 100644 --- a/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/StatusInformationController.kt +++ b/src/main/kotlin/uk/gov/justice/digital/hmpps/hmppsintegrationapi/controllers/v1/person/StatusInformationController.kt @@ -13,9 +13,6 @@ import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestParam import org.springframework.web.bind.annotation.RestController -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.HMPPS_ID -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PAGE -import uk.gov.justice.digital.hmpps.hmppsintegrationapi.config.OpenAPIConfig.Companion.PER_PAGE import uk.gov.justice.digital.hmpps.hmppsintegrationapi.exception.EntityNotFoundException import uk.gov.justice.digital.hmpps.hmppsintegrationapi.extensions.decodeUrlCharacters import uk.gov.justice.digital.hmpps.hmppsintegrationapi.models.hmpps.StatusInformation @@ -42,9 +39,9 @@ class StatusInformationController( ], ) fun getStatusInformation( - @Parameter(ref = HMPPS_ID) @PathVariable encodedHmppsId: String, - @Parameter(ref = PAGE) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, - @Parameter(ref = PER_PAGE) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, + @Parameter(description = "A URL-encoded HMPPS identifier", example = "2008%2F0545166T") @PathVariable encodedHmppsId: String, + @Parameter(description = "The page number (starting from 1)", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "1", name = "page") page: Int, + @Parameter(description = "The maximum number of results for a page", schema = Schema(minimum = "1")) @RequestParam(required = false, defaultValue = "10", name = "perPage") perPage: Int, ): PaginatedResponse { val hmppsId = encodedHmppsId.decodeUrlCharacters() val response = getStatusInformationForPersonService.execute(hmppsId) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 513463a57..fbb27c09c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -20,6 +20,7 @@ spring: springdoc: default-produces-media-type: application/json + api-docs.version: openapi_3_1 server: port: 8080