diff --git a/public/api/docs/v1/swagger.yaml b/public/api/docs/v1/swagger.yaml index fc3f7b9c03..94656c1c89 100644 --- a/public/api/docs/v1/swagger.yaml +++ b/public/api/docs/v1/swagger.yaml @@ -299,7 +299,7 @@ paths: schema: "$ref": "#/components/schemas/ApplicationChangeFundedPlaceRequest" required: true - "/api/v2/participant-declarations.csv": + "/api/v1/participant-declarations.csv": get: summary: Retrieve all Participant declarations in CSV format tags: @@ -319,6 +319,170 @@ paths: text/csv: schema: "$ref": "#/components/schemas/UnauthorisedResponse" + "/api/v1/participant-declarations": + get: + summary: Retrieve multiple Participant declarations + tags: + - Participant declarations + security: + - api_key: [] + parameters: + - name: filter + in: query + required: false + schema: + "$ref": "#/components/schemas/ListParticipantDeclarationsFilter" + - name: page + in: query + required: false + schema: + "$ref": "#/components/schemas/PaginationFilter" + responses: + '200': + description: A list of Participant declarations + content: + application/json: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationsResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + post: + summary: Declare a participant has reached a milestone + tags: + - Participant declarations + security: + - api_key: [] + parameters: [] + responses: + '200': + description: The participant declaration being created + content: + application/json: + examples: + success: + value: + data: + id: d0b4a32e-a272-489e-b30a-cb17131457fc + type: participant-declaration + attributes: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: started + declaration_date: '2022-04-30' + course_identifier: npq-senior-leadership + eligible_for_payment: true + voided: false + state: submitted + updated_at: '2021-05-31T02:22:32.000Z' + has_passed: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + '400': + description: Bad request + content: + application/json: + schema: + "$ref": "#/components/schemas/BadRequestResponse" + '422': + description: Unprocessable entity + content: + application/json: + schema: + "$ref": "#/components/schemas/UnprocessableEntityResponse" + requestBody: + content: + application/json: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationRequest" + "/api/v1/participant-declarations/{id}": + get: + summary: Retrieve a single Participant declarations + tags: + - Participant declarations + security: + - api_key: [] + parameters: + - name: id + in: path + required: true + schema: + "$ref": "#/components/schemas/IDAttribute" + responses: + '200': + description: A single Participant declarations + content: + application/json: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + '404': + description: Not found + content: + application/json: + schema: + "$ref": "#/components/schemas/NotFoundResponse" + "/api/v1/participant-declarations/{id}/void": + put: + summary: Void a declaration + tags: + - Participant declarations + security: + - api_key: [] + parameters: + - name: id + in: path + required: true + schema: + "$ref": "#/components/schemas/IDAttribute" + responses: + '200': + description: The participant declaration being voided + content: + application/json: + examples: + success: + value: + data: + id: d0b4a32e-a272-489e-b30a-cb17131457fc + type: participant-declaration + attributes: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: started + declaration_date: '2022-04-30' + course_identifier: npq-senior-leadership + eligible_for_payment: true + voided: true + state: voided + updated_at: '2021-05-31T02:22:32.000Z' + has_passed: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + '404': + description: Not found + content: + application/json: + schema: + "$ref": "#/components/schemas/NotFoundResponse" "/api/v1/participants/npq": get: summary: Retrieve multiple NPQ participants @@ -647,6 +811,19 @@ components: and time (ISO 8601 date format). type: string example: '2021-05-13T11:21:55Z' + ListParticipantDeclarationsFilter: + description: Refine participant declarations to return. + type: object + properties: + participant_id: + description: The unique id of the participant + type: string + example: 7e5bcdbf-c818-4961-8da5-439cab1984e0 + updated_since: + description: Return only records that have been updated since this date + and time (ISO 8601 date format). + type: string + example: '2021-05-13T11:21:55Z' UnauthorisedResponse: description: Authorization information is missing or invalid. type: object @@ -1676,3 +1853,298 @@ components: nullable: true type: string example: '2023' + ParticipantDeclaration: + description: The details of a participant declaration + type: object + required: + - id + - type + - attributes + properties: + id: + "$ref": "#/components/schemas/IDAttribute" + type: + type: string + enum: + - participant-declaration + example: participant-declaration + attributes: + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + - eligible_for_payment + - voided + - state + - updated_at + properties: + participant_id: + description: The unique identifier of this participant declaration record + type: string + format: uuid + nullable: false + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + nullable: false + example: started + enum: + - started + - retained-1 + - retained-2 + - completed + declaration_date: + description: The event declaration date + type: string + nullable: false + example: '2022-04-30' + course_identifier: + description: The NPQ course this NPQ application relates to + type: string + nullable: false + example: npq-senior-leadership + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + eligible_for_payment: + description: "[Deprecated - use state instead] Indicates whether this + declaration would be eligible for funding from the DfE" + type: boolean + nullable: true + example: true + voided: + description: "[Deprecated - use state instead] Indicates whether this + declaration has been voided" + type: boolean + nullable: true + example: false + state: + description: Indicates the state of this payment declaration + type: string + nullable: false + example: submitted + enum: + - submitted + - eligible + - payable + - paid + - voided + - ineligible + - awaiting_clawback + - clawed_back + updated_at: + description: The date the application was last updated + type: string + nullable: false + format: date-time + example: '2021-05-31T02:22:32.000Z' + has_passed: + description: Whether the participant has failed or passed + type: string + nullable: true + example: + ParticipantDeclarationRequest: + description: A participant declaration data request + type: object + required: + - type + - attributes + properties: + type: + type: string + required: true + enum: + - participant-declaration + example: participant-declaration + attributes: + required: true + anyOf: + - "$ref": "#/components/schemas/ParticipantDeclarationStartedRequest" + - "$ref": "#/components/schemas/ParticipantDeclarationRetainedRequest" + - "$ref": "#/components/schemas/ParticipantDeclarationCompletedRequest" + ParticipantDeclarationResponse: + description: A single participant declaration. + type: object + required: + - data + properties: + data: + "$ref": "#/components/schemas/ParticipantDeclaration" + ParticipantDeclarationsResponse: + description: A list of participant declarations. + type: object + required: + - data + properties: + data: + type: array + items: + "$ref": "#/components/schemas/ParticipantDeclaration" + ParticipantDeclarationStartedRequest: + description: An NPQ started participant declaration + type: object + additionalProperties: false + properties: + participant_id: + description: The unique id of the participant + type: string + format: uuid + required: true + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + required: true + enum: + - started + example: started + declaration_date: + description: The event declaration date + type: string + required: true + format: date-time + example: '2021-05-31T02:21:32.000Z' + course_identifier: + description: The type of course the participant is enrolled in + type: string + required: true + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + example: npq-senior-leadership + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + example: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: started + declaration_date: '2021-05-31T02:21:32.000Z' + course_identifier: npq-senior-leadership + ParticipantDeclarationRetainedRequest: + description: An NPQ participant retained declaration + type: object + additionalProperties: false + properties: + participant_id: + description: The unique id of the participant + type: string + format: uuid + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + enum: + - retained-1 + - retained-2 + example: retained-1 + declaration_date: + description: The event declaration date + type: string + format: date-time + example: '2021-05-31T02:21:32.000Z' + course_identifier: + description: The type of course the participant is enrolled in + type: string + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + example: npq-senior-leadership + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + example: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: retained-1 + declaration_date: '2021-05-31T02:21:32.000Z' + course_identifier: npq-senior-leadership + ParticipantDeclarationCompletedRequest: + description: An NPQ completed participant declaration + type: object + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + - has_passed + additionalProperties: false + properties: + participant_id: + description: The unique id of the participant + type: string + format: uuid + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + enum: + - completed + example: completed + declaration_date: + description: The event declaration date + type: string + format: date-time + example: '2021-05-31T02:21:32.000Z' + course_identifier: + description: The type of course the participant is enrolled in + type: string + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + example: npq-senior-leadership + has_passed: + description: Whether the participant has failed or passed + type: boolean + example: true + nullable: true + example: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: completed + declaration_date: '2021-05-31T02:21:32.000Z' + course_identifier: npq-senior-leadership + has_passed: true diff --git a/public/api/docs/v2/swagger.yaml b/public/api/docs/v2/swagger.yaml index 314346ac92..73456c3851 100644 --- a/public/api/docs/v2/swagger.yaml +++ b/public/api/docs/v2/swagger.yaml @@ -319,6 +319,166 @@ paths: text/csv: schema: "$ref": "#/components/schemas/UnauthorisedResponse" + "/api/v2/participant-declarations": + get: + summary: Retrieve multiple Participant declarations + tags: + - Participant declarations + security: + - api_key: [] + parameters: + - name: filter + in: query + required: false + schema: + "$ref": "#/components/schemas/ListParticipantDeclarationsFilter" + - name: page + in: query + required: false + schema: + "$ref": "#/components/schemas/PaginationFilter" + responses: + '200': + description: A list of Participant declarations + content: + application/json: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationsResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + post: + summary: Declare a participant has reached a milestone + tags: + - Participant declarations + security: + - api_key: [] + parameters: [] + responses: + '200': + description: The participant declaration being created + content: + application/json: + examples: + success: + value: + data: + id: d0b4a32e-a272-489e-b30a-cb17131457fc + type: participant-declaration + attributes: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: started + declaration_date: '2022-04-30' + course_identifier: npq-senior-leadership + state: submitted + updated_at: '2021-05-31T02:22:32.000Z' + has_passed: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + '400': + description: Bad request + content: + application/json: + schema: + "$ref": "#/components/schemas/BadRequestResponse" + '422': + description: Unprocessable entity + content: + application/json: + schema: + "$ref": "#/components/schemas/UnprocessableEntityResponse" + requestBody: + content: + application/json: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationRequest" + "/api/v2/participant-declarations/{id}": + get: + summary: Retrieve a single Participant declarations + tags: + - Participant declarations + security: + - api_key: [] + parameters: + - name: id + in: path + required: true + schema: + "$ref": "#/components/schemas/IDAttribute" + responses: + '200': + description: A single Participant declarations + content: + application/json: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + '404': + description: Not found + content: + application/json: + schema: + "$ref": "#/components/schemas/NotFoundResponse" + "/api/v2/participant-declarations/{id}/void": + put: + summary: Void a declaration + tags: + - Participant declarations + security: + - api_key: [] + parameters: + - name: id + in: path + required: true + schema: + "$ref": "#/components/schemas/IDAttribute" + responses: + '200': + description: The participant declaration being voided + content: + application/json: + examples: + success: + value: + data: + id: d0b4a32e-a272-489e-b30a-cb17131457fc + type: participant-declaration + attributes: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: started + declaration_date: '2022-04-30' + course_identifier: npq-senior-leadership + state: voided + updated_at: '2021-05-31T02:22:32.000Z' + has_passed: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + '404': + description: Not found + content: + application/json: + schema: + "$ref": "#/components/schemas/NotFoundResponse" "/api/v2/npq-enrolments.csv": get: summary: Retrieve all NPQ enrolments in CSV format @@ -748,6 +908,19 @@ components: and time (ISO 8601 date format). type: string example: '2021-05-13T11:21:55Z' + ListParticipantDeclarationsFilter: + description: Refine participant declarations to return. + type: object + properties: + participant_id: + description: The unique id of the participant + type: string + example: 7e5bcdbf-c818-4961-8da5-439cab1984e0 + updated_since: + description: Return only records that have been updated since this date + and time (ISO 8601 date format). + type: string + example: '2021-05-13T11:21:55Z' UnauthorisedResponse: description: Authorization information is missing or invalid. type: object @@ -1893,3 +2066,284 @@ components: nullable: true type: string example: '2023' + ParticipantDeclaration: + description: The details of a participant declaration + type: object + required: + - id + - type + - attributes + properties: + id: + "$ref": "#/components/schemas/IDAttribute" + type: + type: string + enum: + - participant-declaration + example: participant-declaration + attributes: + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + - state + - updated_at + properties: + participant_id: + description: The unique identifier of this participant declaration record + type: string + format: uuid + nullable: false + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + nullable: false + example: started + enum: + - started + - retained-1 + - retained-2 + - completed + declaration_date: + description: The event declaration date + type: string + nullable: false + example: '2022-04-30' + course_identifier: + description: The NPQ course this NPQ application relates to + type: string + nullable: false + example: npq-senior-leadership + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + state: + description: Indicates the state of this payment declaration + type: string + nullable: false + example: submitted + enum: + - submitted + - eligible + - payable + - paid + - voided + - ineligible + - awaiting_clawback + - clawed_back + updated_at: + description: The date the application was last updated + type: string + nullable: false + format: date-time + example: '2021-05-31T02:22:32.000Z' + has_passed: + description: Whether the participant has failed or passed + type: string + nullable: true + example: + ParticipantDeclarationRequest: + description: A participant declaration data request + type: object + required: + - type + - attributes + properties: + type: + type: string + required: true + enum: + - participant-declaration + example: participant-declaration + attributes: + required: true + anyOf: + - "$ref": "#/components/schemas/ParticipantDeclarationStartedRequest" + - "$ref": "#/components/schemas/ParticipantDeclarationRetainedRequest" + - "$ref": "#/components/schemas/ParticipantDeclarationCompletedRequest" + ParticipantDeclarationResponse: + description: A single participant declaration. + type: object + required: + - data + properties: + data: + "$ref": "#/components/schemas/ParticipantDeclaration" + ParticipantDeclarationsResponse: + description: A list of participant declarations. + type: object + required: + - data + properties: + data: + type: array + items: + "$ref": "#/components/schemas/ParticipantDeclaration" + ParticipantDeclarationStartedRequest: + description: An NPQ started participant declaration + type: object + additionalProperties: false + properties: + participant_id: + description: The unique id of the participant + type: string + format: uuid + required: true + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + required: true + enum: + - started + example: started + declaration_date: + description: The event declaration date + type: string + required: true + format: date-time + example: '2021-05-31T02:21:32.000Z' + course_identifier: + description: The type of course the participant is enrolled in + type: string + required: true + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + example: npq-senior-leadership + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + example: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: started + declaration_date: '2021-05-31T02:21:32.000Z' + course_identifier: npq-senior-leadership + ParticipantDeclarationRetainedRequest: + description: An NPQ participant retained declaration + type: object + additionalProperties: false + properties: + participant_id: + description: The unique id of the participant + type: string + format: uuid + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + enum: + - retained-1 + - retained-2 + example: retained-1 + declaration_date: + description: The event declaration date + type: string + format: date-time + example: '2021-05-31T02:21:32.000Z' + course_identifier: + description: The type of course the participant is enrolled in + type: string + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + example: npq-senior-leadership + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + example: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: retained-1 + declaration_date: '2021-05-31T02:21:32.000Z' + course_identifier: npq-senior-leadership + ParticipantDeclarationCompletedRequest: + description: An NPQ completed participant declaration + type: object + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + - has_passed + additionalProperties: false + properties: + participant_id: + description: The unique id of the participant + type: string + format: uuid + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + enum: + - completed + example: completed + declaration_date: + description: The event declaration date + type: string + format: date-time + example: '2021-05-31T02:21:32.000Z' + course_identifier: + description: The type of course the participant is enrolled in + type: string + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + example: npq-senior-leadership + has_passed: + description: Whether the participant has failed or passed + type: boolean + example: true + nullable: true + example: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: completed + declaration_date: '2021-05-31T02:21:32.000Z' + course_identifier: npq-senior-leadership + has_passed: true diff --git a/public/api/docs/v3/swagger.yaml b/public/api/docs/v3/swagger.yaml index ab4d57384e..1d42e081a4 100644 --- a/public/api/docs/v3/swagger.yaml +++ b/public/api/docs/v3/swagger.yaml @@ -280,6 +280,163 @@ paths: schema: "$ref": "#/components/schemas/ApplicationChangeFundedPlaceRequest" required: true + "/api/v3/participant-declarations": + get: + summary: Retrieve multiple Participant declarations + tags: + - Participant declarations + security: + - api_key: [] + parameters: + - name: filter + in: query + required: false + schema: + "$ref": "#/components/schemas/ListParticipantDeclarationsFilter" + - name: page + in: query + required: false + schema: + "$ref": "#/components/schemas/PaginationFilter" + - name: sort + in: query + required: false + schema: + "$ref": "#/components/schemas/SortingOptions" + responses: + '200': + description: A list of Participant declarations + content: + application/json: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationsResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + post: + summary: Declare a participant has reached a milestone + tags: + - Participant declarations + security: + - api_key: [] + parameters: [] + responses: + '200': + description: The participant declaration being created + content: + application/json: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + '400': + description: Bad request + content: + application/json: + schema: + "$ref": "#/components/schemas/BadRequestResponse" + '422': + description: Unprocessable entity + content: + application/json: + schema: + "$ref": "#/components/schemas/UnprocessableEntityResponse" + requestBody: + content: + application/json: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationRequest" + "/api/v3/participant-declarations/{id}": + get: + summary: Retrieve a single Participant declarations + tags: + - Participant declarations + security: + - api_key: [] + parameters: + - name: id + in: path + required: true + schema: + "$ref": "#/components/schemas/IDAttribute" + responses: + '200': + description: A single Participant declarations + content: + application/json: + schema: + "$ref": "#/components/schemas/ParticipantDeclarationResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + '404': + description: Not found + content: + application/json: + schema: + "$ref": "#/components/schemas/NotFoundResponse" + "/api/v3/participant-declarations/{id}/void": + put: + summary: Void a declaration + tags: + - Participant declarations + security: + - api_key: [] + parameters: + - name: id + in: path + required: true + schema: + "$ref": "#/components/schemas/IDAttribute" + responses: + '200': + description: The participant declaration being voided + content: + application/json: + examples: + success: + value: + data: + id: d0b4a32e-a272-489e-b30a-cb17131457fc + type: participant-declaration + attributes: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: started + declaration_date: '2022-04-30' + course_identifier: npq-senior-leadership + state: voided + updated_at: '2021-05-31T02:22:32.000Z' + has_passed: + statement_id: cd3a12347-7308-4879-942a-c4a70ced400a + clawback_statement_id: cd3a12347-7308-4879-942a-c4a70ced400a + ineligible_for_funding_reason: duplicate_declaration + uplift_paid: true + lead_provider_name: Example Institute + created_at: '2021-05-31T02:22:32.000Z' + schema: + "$ref": "#/components/schemas/ParticipantDeclarationResponse" + '401': + description: Unauthorized + content: + application/json: + schema: + "$ref": "#/components/schemas/UnauthorisedResponse" + '404': + description: Not found + content: + application/json: + schema: + "$ref": "#/components/schemas/NotFoundResponse" "/api/v3/participants/npq": get: summary: Retrieve multiple NPQ participants @@ -797,6 +954,24 @@ components: description: Return only records that have this from Participant ID type: string example: 7e5bcdbf-c818-4961-8da5-439cab1984e0 + ListParticipantDeclarationsFilter: + description: Refine participant declarations to return. + type: object + properties: + participant_id: + description: The unique id of the participant + type: string + example: 7e5bcdbf-c818-4961-8da5-439cab1984e0 + updated_since: + description: Return only records that have been updated since this date + and time (ISO 8601 date format). + type: string + example: '2021-05-13T11:21:55Z' + cohort: + description: Return participant declarations associated to the specified + cohort or cohorts. This is a comma delimited string of years. + type: string + example: '2021,2022' ListStatementsFilter: description: Filter statements to return more specific results type: object @@ -1765,3 +1940,321 @@ components: - "-created_at" - updated_at - "-updated_at" + ParticipantDeclaration: + description: The details of a participant declaration + type: object + required: + - id + - type + - attributes + properties: + id: + "$ref": "#/components/schemas/IDAttribute" + type: + type: string + enum: + - participant-declaration + example: participant-declaration + attributes: + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + - state + - updated_at + properties: + participant_id: + description: The unique identifier of this participant declaration record + type: string + format: uuid + nullable: false + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + nullable: false + example: started + enum: + - started + - retained-1 + - retained-2 + - completed + declaration_date: + description: The event declaration date + type: string + nullable: false + example: '2022-04-30' + course_identifier: + description: The NPQ course this NPQ application relates to + type: string + nullable: false + example: npq-senior-leadership + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + state: + description: Indicates the state of this payment declaration + type: string + nullable: false + example: submitted + enum: + - submitted + - eligible + - payable + - paid + - voided + - ineligible + - awaiting_clawback + - clawed_back + updated_at: + description: The date the application was last updated + type: string + nullable: false + format: date-time + example: '2021-05-31T02:22:32.000Z' + has_passed: + description: Whether the participant has failed or passed + type: string + example: + nullable: true + statement_id: + description: Unique ID of the statement the declaration will be paid + as part of + type: string + format: uuid + example: cd3a12347-7308-4879-942a-c4a70ced400a + nullable: true + clawback_statement_id: + description: Unique id of the statement to which the declaration will + be clawed back on, if any + type: string + format: uuid + example: cd3a12347-7308-4879-942a-c4a70ced400a + nullable: true + ineligible_for_funding_reason: + description: If the declaration is ineligible, the reason why + type: string + enum: + - duplicate_declaration + nullable: true + example: duplicate_declaration + uplift_paid: + description: If participant is eligible for uplift, whether it has been + paid as part of this declaration + type: boolean + example: true + lead_provider_name: + description: The name of the provider that submitted the declaration + type: string + example: Example Institute + nullable: false + created_at: + description: The date the application was created + type: string + nullable: false + format: date-time + example: '2021-05-31T02:22:32.000Z' + ParticipantDeclarationRequest: + description: A participant declaration data request + type: object + required: + - type + - attributes + properties: + type: + type: string + required: true + enum: + - participant-declaration + example: participant-declaration + attributes: + required: true + anyOf: + - "$ref": "#/components/schemas/ParticipantDeclarationStartedRequest" + - "$ref": "#/components/schemas/ParticipantDeclarationRetainedRequest" + - "$ref": "#/components/schemas/ParticipantDeclarationCompletedRequest" + ParticipantDeclarationResponse: + description: A single participant declaration. + type: object + required: + - data + properties: + data: + "$ref": "#/components/schemas/ParticipantDeclaration" + ParticipantDeclarationsResponse: + description: A list of participant declarations. + type: object + required: + - data + properties: + data: + type: array + items: + "$ref": "#/components/schemas/ParticipantDeclaration" + ParticipantDeclarationStartedRequest: + description: An NPQ started participant declaration + type: object + additionalProperties: false + properties: + participant_id: + description: The unique id of the participant + type: string + format: uuid + required: true + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + required: true + enum: + - started + example: started + declaration_date: + description: The event declaration date + type: string + required: true + format: date-time + example: '2021-05-31T02:21:32.000Z' + course_identifier: + description: The type of course the participant is enrolled in + type: string + required: true + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + example: npq-senior-leadership + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + example: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: started + declaration_date: '2021-05-31T02:21:32.000Z' + course_identifier: npq-senior-leadership + ParticipantDeclarationRetainedRequest: + description: An NPQ participant retained declaration + type: object + additionalProperties: false + properties: + participant_id: + description: The unique id of the participant + type: string + format: uuid + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + enum: + - retained-1 + - retained-2 + example: retained-1 + declaration_date: + description: The event declaration date + type: string + format: date-time + example: '2021-05-31T02:21:32.000Z' + course_identifier: + description: The type of course the participant is enrolled in + type: string + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + example: npq-senior-leadership + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + example: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: retained-1 + declaration_date: '2021-05-31T02:21:32.000Z' + course_identifier: npq-senior-leadership + ParticipantDeclarationCompletedRequest: + description: An NPQ completed participant declaration + type: object + required: + - participant_id + - declaration_type + - declaration_date + - course_identifier + - has_passed + additionalProperties: false + properties: + participant_id: + description: The unique id of the participant + type: string + format: uuid + example: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: + description: The event declaration type + type: string + enum: + - completed + example: completed + declaration_date: + description: The event declaration date + type: string + format: date-time + example: '2021-05-31T02:21:32.000Z' + course_identifier: + description: The type of course the participant is enrolled in + type: string + enum: + - npq-senior-leadership + - npq-headship + - npq-executive-leadership + - npq-early-years-leadership + - npq-leading-teaching + - npq-leading-behaviour-culture + - npq-leading-teaching-development + - npq-leading-literacy + - npq-leading-primary-mathematics + - npq-additional-support-offer + - npq-early-headship-coaching-offer + - npq-senco + example: npq-senior-leadership + has_passed: + description: Whether the participant has failed or passed + type: boolean + example: true + nullable: true + example: + participant_id: db3a7848-7308-4879-942a-c4a70ced400a + declaration_type: completed + declaration_date: '2021-05-31T02:21:32.000Z' + course_identifier: npq-senior-leadership + has_passed: true diff --git a/spec/requests/api/docs/v1/applications_spec.rb b/spec/requests/api/docs/v1/applications_spec.rb index 6e6e6b5d7a..2b53f21433 100644 --- a/spec/requests/api/docs/v1/applications_spec.rb +++ b/spec/requests/api/docs/v1/applications_spec.rb @@ -45,7 +45,7 @@ extract_swagger_example(schema: "#/components/schemas/ApplicationResponse", version: :v1) end - it_behaves_like "an API create on resource endpoint documentation", + it_behaves_like "an API create on existing resource endpoint documentation", "/api/v1/npq-applications/{id}/accept", "NPQ Applications", "Accept an NPQ application", @@ -63,7 +63,7 @@ end end - it_behaves_like "an API create on resource endpoint documentation", + it_behaves_like "an API create on existing resource endpoint documentation", "/api/v1/npq-applications/{id}/reject", "NPQ Applications", "Reject an NPQ application", diff --git a/spec/requests/api/docs/v1/declarations_spec.rb b/spec/requests/api/docs/v1/declarations_spec.rb index da843ae6d8..b5dada10f8 100644 --- a/spec/requests/api/docs/v1/declarations_spec.rb +++ b/spec/requests/api/docs/v1/declarations_spec.rb @@ -5,8 +5,77 @@ include_context "with authorization for api doc request" it_behaves_like "an API index Csv endpoint documentation", - "/api/v2/participant-declarations.csv", + "/api/v1/participant-declarations.csv", "Participant declarations", "Participant declarations", "#/components/schemas/DeclarationsCsvResponse" + + it_behaves_like "an API index endpoint documentation", + "/api/v1/participant-declarations", + "Participant declarations", + "Participant declarations", + "#/components/schemas/ListParticipantDeclarationsFilter", + "#/components/schemas/ParticipantDeclarationsResponse" + + describe "single declarations" do + let(:lead_provider) { create(:lead_provider) } + let(:type) { "participant-declaration" } # check + let(:application) { create(:application, :accepted, :with_declaration, lead_provider:) } + let(:resource) { application.declarations.first } + let(:base_response_example) do + extract_swagger_example(schema: "#/components/schemas/ParticipantDeclarationResponse", version: :v1) + end + + it_behaves_like "an API show endpoint documentation", + "/api/v1/participant-declarations/{id}", + "Participant declarations", + "Participant declarations", + "#/components/schemas/ParticipantDeclarationResponse" + + it_behaves_like "an API update endpoint documentation", + "/api/v1/participant-declarations/{id}/void", + "Participant declarations", + "Void a declaration", + "The participant declaration being voided", + "#/components/schemas/ParticipantDeclarationResponse" do + let(:response_example) do + base_response_example.tap do |example| + example[:data][:attributes][:state] = "voided" + example[:data][:attributes][:voided] = true + example[:data][:attributes][:has_passed] = nil + end + end + end + end + + describe "create declarations" do + let(:lead_provider) { create(:lead_provider) } + let(:type) { "participant-declaration" } # check + let(:cohort) { create(:cohort, :current) } + let(:course_group) { CourseGroup.find_by(name: "leadership") } + let(:course) { create(:course, :sl, course_group:) } + let!(:schedule) { create(:schedule, :npq_leadership_autumn, course_group:, cohort:) } + let(:application) { create(:application, :accepted, cohort:, course:, lead_provider:) } + let(:declaration_date) { schedule.applies_from + 1.day } + let(:response_example) do + extract_swagger_example(schema: "#/components/schemas/ParticipantDeclarationResponse", version: :v1) + end + let(:invalid_attributes) { { participant_id: "invalid" } } + let(:attributes) do + { + participant_id: application.user.ecf_id, + declaration_type: "started", + declaration_date: application.schedule.applies_from.rfc3339, + course_identifier: course.identifier, + } + end + + it_behaves_like "an API create on resource endpoint documentation", + "/api/v1/participant-declarations", + "Participant declarations", + "Declare a participant has reached a milestone", + "The participant declaration being created", + "#/components/schemas/ParticipantDeclarationResponse", + "#/components/schemas/ParticipantDeclarationRequest" + end end diff --git a/spec/requests/api/docs/v2/applications_spec.rb b/spec/requests/api/docs/v2/applications_spec.rb index da25e0adf8..b5e297498e 100644 --- a/spec/requests/api/docs/v2/applications_spec.rb +++ b/spec/requests/api/docs/v2/applications_spec.rb @@ -45,7 +45,7 @@ extract_swagger_example(schema: "#/components/schemas/ApplicationResponse", version: :v2) end - it_behaves_like "an API create on resource endpoint documentation", + it_behaves_like "an API create on existing resource endpoint documentation", "/api/v2/npq-applications/{id}/accept", "NPQ Applications", "Accept an NPQ application", @@ -63,7 +63,7 @@ end end - it_behaves_like "an API create on resource endpoint documentation", + it_behaves_like "an API create on existing resource endpoint documentation", "/api/v2/npq-applications/{id}/reject", "NPQ Applications", "Reject an NPQ application", diff --git a/spec/requests/api/docs/v2/declarations_spec.rb b/spec/requests/api/docs/v2/declarations_spec.rb index 60edd40dfd..3b3143631d 100644 --- a/spec/requests/api/docs/v2/declarations_spec.rb +++ b/spec/requests/api/docs/v2/declarations_spec.rb @@ -9,4 +9,72 @@ "Participant declarations", "Participant declarations", "#/components/schemas/DeclarationsCsvResponse" + + it_behaves_like "an API index endpoint documentation", + "/api/v2/participant-declarations", + "Participant declarations", + "Participant declarations", + "#/components/schemas/ListParticipantDeclarationsFilter", + "#/components/schemas/ParticipantDeclarationsResponse" + + describe "single declarations" do + let(:lead_provider) { create(:lead_provider) } + let(:type) { "participant-declaration" } # check + let(:application) { create(:application, :accepted, :with_declaration, lead_provider:) } + let(:resource) { application.declarations.first } + let(:base_response_example) do + extract_swagger_example(schema: "#/components/schemas/ParticipantDeclarationResponse", version: :v2) + end + + it_behaves_like "an API show endpoint documentation", + "/api/v2/participant-declarations/{id}", + "Participant declarations", + "Participant declarations", + "#/components/schemas/ParticipantDeclarationResponse" + + it_behaves_like "an API update endpoint documentation", + "/api/v2/participant-declarations/{id}/void", + "Participant declarations", + "Void a declaration", + "The participant declaration being voided", + "#/components/schemas/ParticipantDeclarationResponse" do + let(:response_example) do + base_response_example.tap do |example| + example[:data][:attributes][:state] = "voided" + example[:data][:attributes][:has_passed] = nil + end + end + end + end + + describe "create declarations" do + let(:lead_provider) { create(:lead_provider) } + let(:type) { "participant-declaration" } # check + let(:cohort) { create(:cohort, :current) } + let(:course_group) { CourseGroup.find_by(name: "leadership") } + let(:course) { create(:course, :sl, course_group:) } + let!(:schedule) { create(:schedule, :npq_leadership_autumn, course_group:, cohort:) } + let(:application) { create(:application, :accepted, cohort:, course:, lead_provider:) } + let(:declaration_date) { schedule.applies_from + 1.day } + let(:response_example) do + extract_swagger_example(schema: "#/components/schemas/ParticipantDeclarationResponse", version: :v2) + end + let(:invalid_attributes) { { participant_id: "invalid" } } + let(:attributes) do + { + participant_id: application.user.ecf_id, + declaration_type: "started", + declaration_date: application.schedule.applies_from.rfc3339, + course_identifier: course.identifier, + } + end + + it_behaves_like "an API create on resource endpoint documentation", + "/api/v2/participant-declarations", + "Participant declarations", + "Declare a participant has reached a milestone", + "The participant declaration being created", + "#/components/schemas/ParticipantDeclarationResponse", + "#/components/schemas/ParticipantDeclarationRequest" + end end diff --git a/spec/requests/api/docs/v3/applications_spec.rb b/spec/requests/api/docs/v3/applications_spec.rb index 2b74e45f05..0d885402c2 100644 --- a/spec/requests/api/docs/v3/applications_spec.rb +++ b/spec/requests/api/docs/v3/applications_spec.rb @@ -38,7 +38,7 @@ extract_swagger_example(schema: "#/components/schemas/ApplicationResponse", version: :v3) end - it_behaves_like "an API create on resource endpoint documentation", + it_behaves_like "an API create on existing resource endpoint documentation", "/api/v3/npq-applications/{id}/accept", "NPQ Applications", "Accept an NPQ application", @@ -56,7 +56,7 @@ end end - it_behaves_like "an API create on resource endpoint documentation", + it_behaves_like "an API create on existing resource endpoint documentation", "/api/v3/npq-applications/{id}/reject", "NPQ Applications", "Reject an NPQ application", diff --git a/spec/requests/api/docs/v3/declarations_spec.rb b/spec/requests/api/docs/v3/declarations_spec.rb new file mode 100644 index 0000000000..99ff78b5fa --- /dev/null +++ b/spec/requests/api/docs/v3/declarations_spec.rb @@ -0,0 +1,71 @@ +require "rails_helper" +require "swagger_helper" + +RSpec.describe "Participant Declarations endpoint", type: :request, openapi_spec: "v3/swagger.yaml" do + include_context "with authorization for api doc request" + + it_behaves_like "an API index endpoint documentation", + "/api/v3/participant-declarations", + "Participant declarations", + "Participant declarations", + "#/components/schemas/ListParticipantDeclarationsFilter", + "#/components/schemas/ParticipantDeclarationsResponse" + + describe "single declarations" do + let(:lead_provider) { create(:lead_provider) } + let(:type) { "participant-declaration" } # check + let(:application) { create(:application, :accepted, :with_declaration, lead_provider:) } + let(:resource) { application.declarations.first } + let(:base_response_example) do + extract_swagger_example(schema: "#/components/schemas/ParticipantDeclarationResponse", version: :v3) + end + + it_behaves_like "an API show endpoint documentation", + "/api/v3/participant-declarations/{id}", + "Participant declarations", + "Participant declarations", + "#/components/schemas/ParticipantDeclarationResponse" + + it_behaves_like "an API update endpoint documentation", + "/api/v3/participant-declarations/{id}/void", + "Participant declarations", + "Void a declaration", + "The participant declaration being voided", + "#/components/schemas/ParticipantDeclarationResponse" do + let(:response_example) do + base_response_example.tap do |example| + example[:data][:attributes][:state] = "voided" + example[:data][:attributes][:has_passed] = nil + end + end + end + end + + describe "create declarations" do + let(:lead_provider) { create(:lead_provider) } + let(:type) { "participant-declaration" } # check + let(:cohort) { create(:cohort, :current) } + let(:course_group) { CourseGroup.find_by(name: "leadership") } + let(:course) { create(:course, :sl, course_group:) } + let!(:schedule) { create(:schedule, :npq_leadership_autumn, course_group:, cohort:) } + let(:application) { create(:application, :accepted, cohort:, course:, lead_provider:) } + let(:declaration_date) { schedule.applies_from + 1.day } + let(:invalid_attributes) { { participant_id: "invalid" } } + let(:attributes) do + { + participant_id: application.user.ecf_id, + declaration_type: "started", + declaration_date: application.schedule.applies_from.rfc3339, + course_identifier: course.identifier, + } + end + + it_behaves_like "an API create on resource endpoint documentation", + "/api/v3/participant-declarations", + "Participant declarations", + "Declare a participant has reached a milestone", + "The participant declaration being created", + "#/components/schemas/ParticipantDeclarationResponse", + "#/components/schemas/ParticipantDeclarationRequest" + end +end diff --git a/spec/support/shared_examples/api_create_on_existing_resource_endpoint_documentation_support.rb b/spec/support/shared_examples/api_create_on_existing_resource_endpoint_documentation_support.rb new file mode 100644 index 0000000000..7580cdac72 --- /dev/null +++ b/spec/support/shared_examples/api_create_on_existing_resource_endpoint_documentation_support.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +RSpec.shared_examples "an API create on existing resource endpoint documentation" do |url, tag, resource_description, response_description, response_schema_ref, request_schema_ref| + path url do + post resource_description do + tags tag + consumes "application/json" + produces "application/json" + security [api_key: []] + + parameter name: :id, + in: :path, + required: true, + schema: { + "$ref": "#/components/schemas/IDAttribute", + } + + if request_schema_ref + parameter name: :params, + in: :body, + style: :deepObject, + required: false, + schema: { + "$ref": request_schema_ref, + } + + let(:params) do + { + data: { + type:, + attributes:, + }, + } + end + end + + response "200", response_description do + let(:id) { resource.ecf_id } + + schema({ "$ref": response_schema_ref }) + + after do |example| + if defined?(response_example) + example_spec = { + "application/json" => { + examples: { + success: { + value: response_example, + }, + }, + }, + } + example.metadata[:response][:content] = example_spec + end + end + + run_test! + end + + response "401", "Unauthorized" do + let(:id) { resource.ecf_id } + let(:token) { "invalid" } + + schema({ "$ref": "#/components/schemas/UnauthorisedResponse" }) + + run_test! + end + + if request_schema_ref + response "400", "Bad request" do + let(:id) { resource.ecf_id } + let(:params) { { data: {} } } + + schema({ "$ref": "#/components/schemas/BadRequestResponse" }) + + run_test! + end + + response "422", "Unprocessable entity" do + let(:id) { resource.ecf_id } + let(:attributes) { invalid_attributes } + + schema({ "$ref": "#/components/schemas/UnprocessableEntityResponse" }) + + run_test! + end + end + + response "404", "Not found", exceptions_app: true do + let(:id) { SecureRandom.uuid } + + schema({ "$ref": "#/components/schemas/NotFoundResponse" }) + + run_test! + end + end + end +end diff --git a/spec/support/shared_examples/api_create_on_resource_endpoint_documentation_support.rb b/spec/support/shared_examples/api_create_on_resource_endpoint_documentation_support.rb index a0fa6ab9c5..0c2b60b614 100644 --- a/spec/support/shared_examples/api_create_on_resource_endpoint_documentation_support.rb +++ b/spec/support/shared_examples/api_create_on_resource_endpoint_documentation_support.rb @@ -8,13 +8,6 @@ produces "application/json" security [api_key: []] - parameter name: :id, - in: :path, - required: true, - schema: { - "$ref": "#/components/schemas/IDAttribute", - } - if request_schema_ref parameter name: :params, in: :body, @@ -35,8 +28,6 @@ end response "200", response_description do - let(:id) { resource.ecf_id } - schema({ "$ref": response_schema_ref }) after do |example| @@ -58,7 +49,6 @@ end response "401", "Unauthorized" do - let(:id) { resource.ecf_id } let(:token) { "invalid" } schema({ "$ref": "#/components/schemas/UnauthorisedResponse" }) @@ -68,7 +58,6 @@ if request_schema_ref response "400", "Bad request" do - let(:id) { resource.ecf_id } let(:params) { { data: {} } } schema({ "$ref": "#/components/schemas/BadRequestResponse" }) @@ -77,7 +66,6 @@ end response "422", "Unprocessable entity" do - let(:id) { resource.ecf_id } let(:attributes) { invalid_attributes } schema({ "$ref": "#/components/schemas/UnprocessableEntityResponse" }) @@ -85,14 +73,6 @@ run_test! end end - - response "404", "Not found", exceptions_app: true do - let(:id) { SecureRandom.uuid } - - schema({ "$ref": "#/components/schemas/NotFoundResponse" }) - - run_test! - end end end end diff --git a/spec/support/shared_examples/api_update_endpoint_documentation_support.rb b/spec/support/shared_examples/api_update_endpoint_documentation_support.rb index e6457d2e7b..b337f465eb 100644 --- a/spec/support/shared_examples/api_update_endpoint_documentation_support.rb +++ b/spec/support/shared_examples/api_update_endpoint_documentation_support.rb @@ -15,21 +15,23 @@ "$ref": "#/components/schemas/IDAttribute", } - parameter name: :params, - in: :body, - style: :deepObject, - required: true, - schema: { - "$ref": request_schema_ref, - } - - let(:params) do - { - data: { - type:, - attributes:, - }, - } + if request_schema_ref.present? + parameter name: :params, + in: :body, + style: :deepObject, + required: true, + schema: { + "$ref": request_schema_ref, + } + + let(:params) do + { + data: { + type:, + attributes:, + }, + } + end end response "200", response_description do @@ -64,22 +66,24 @@ run_test! end - response "400", "Bad request" do - let(:id) { resource.ecf_id } - let(:params) { { data: {} } } + if request_schema_ref.present? + response "400", "Bad request" do + let(:id) { resource.ecf_id } + let(:params) { { data: {} } } - schema({ "$ref": "#/components/schemas/BadRequestResponse" }) + schema({ "$ref": "#/components/schemas/BadRequestResponse" }) - run_test! - end + run_test! + end - response "422", "Unprocessable entity" do - let(:id) { resource.ecf_id } - let(:attributes) { invalid_attributes } + response "422", "Unprocessable entity" do + let(:id) { resource.ecf_id } + let(:attributes) { invalid_attributes } - schema({ "$ref": "#/components/schemas/UnprocessableEntityResponse" }) + schema({ "$ref": "#/components/schemas/UnprocessableEntityResponse" }) - run_test! + run_test! + end end response "404", "Not found", exceptions_app: true do diff --git a/spec/swagger_helper.rb b/spec/swagger_helper.rb index ae75cce37a..3fccd253ed 100644 --- a/spec/swagger_helper.rb +++ b/spec/swagger_helper.rb @@ -50,6 +50,7 @@ ListApplicationsFilter: LIST_APPLICATIONS_FILTER[version], ListEnrolmentsFilter: LIST_ENROLMENTS_FILTER[version], ListParticipantsFilter: LIST_PARTICIPANTS_FILTER[version], + ListParticipantDeclarationsFilter: LIST_PARTICIPANT_DECLARATIONS_FILTER[version], ListStatementsFilter: LIST_STATEMENTS_FILTER[version], UnauthorisedResponse: UNAUTHORISED_RESPONSE, NotFoundResponse: NOT_FOUND_RESPONSE, @@ -78,6 +79,14 @@ StatementsResponse: STATEMENTS_RESPONSE[version], Statement: STATEMENT[version], SortingOptions: SORTING_OPTIONS[version], + + ParticipantDeclaration: PARTICIPANT_DECLARATION[version], + ParticipantDeclarationRequest: PARTICIPANT_DECLARATION_REQUEST, + ParticipantDeclarationResponse: PARTICIPANT_DECLARATION_RESPONSE[version], + ParticipantDeclarationsResponse: PARTICIPANT_DECLARATIONS_RESPONSE[version], + ParticipantDeclarationStartedRequest: PARTICIPANT_DECLARATION_STARTED_REQUEST, + ParticipantDeclarationRetainedRequest: PARTICIPANT_DECLARATION_RETAINED_REQUEST, + ParticipantDeclarationCompletedRequest: PARTICIPANT_DECLARATION_COMPLETED_REQUEST, }.compact, }, } diff --git a/spec/swagger_schemas/filters/list_participant_declarations.rb b/spec/swagger_schemas/filters/list_participant_declarations.rb new file mode 100644 index 0000000000..26cf9db2c2 --- /dev/null +++ b/spec/swagger_schemas/filters/list_participant_declarations.rb @@ -0,0 +1,28 @@ +LIST_PARTICIPANT_DECLARATIONS_FILTER = { + v1: { + description: "Refine participant declarations to return.", + type: :object, + properties: { + participant_id: { + description: "The unique id of the participant", + type: :string, + example: "7e5bcdbf-c818-4961-8da5-439cab1984e0", + }, + updated_since: { + description: "Return only records that have been updated since this date and time (ISO 8601 date format).", + type: :string, + example: "2021-05-13T11:21:55Z", + }, + }, + }, +}.tap { |h| + h[:v2] = h[:v1] + h[:v3] = h[:v1].deep_dup + h[:v3][:properties].merge!({ + cohort: { + description: "Return participant declarations associated to the specified cohort or cohorts. This is a comma delimited string of years.", + type: :string, + example: "2021,2022", + }, + }) +}.freeze diff --git a/spec/swagger_schemas/models/participant_declaration.rb b/spec/swagger_schemas/models/participant_declaration.rb new file mode 100644 index 0000000000..bf63aeaa12 --- /dev/null +++ b/spec/swagger_schemas/models/participant_declaration.rb @@ -0,0 +1,144 @@ +PARTICIPANT_DECLARATION = { + v1: { + description: "The details of a participant declaration", + type: :object, + required: %i[id type attributes], + properties: { + id: { + "$ref": "#/components/schemas/IDAttribute", + }, + type: { + type: :string, + enum: %w[ + participant-declaration + ], + example: "participant-declaration", + }, + attributes: { + required: %i[ + participant_id + declaration_type + declaration_date + course_identifier + eligible_for_payment + voided + state + updated_at + ], + properties: { + participant_id: { + description: "The unique identifier of this participant declaration record", + type: :string, + format: :uuid, + nullable: false, + example: "db3a7848-7308-4879-942a-c4a70ced400a", + }, + declaration_type: { + description: "The event declaration type", + type: :string, + nullable: false, + example: "started", + enum: Schedule::DECLARATION_TYPES, + }, + declaration_date: { + description: "The event declaration date", + type: :string, + nullable: false, + example: "2022-04-30", + }, + course_identifier: { + description: "The NPQ course this NPQ application relates to", + type: :string, + nullable: false, + example: Course::IDENTIFIERS.first, + enum: Course::IDENTIFIERS, + }, + eligible_for_payment: { + description: "[Deprecated - use state instead] Indicates whether this declaration would be eligible for funding from the DfE", + type: :boolean, + nullable: true, + example: true, + }, + voided: { + description: "[Deprecated - use state instead] Indicates whether this declaration has been voided", + type: :boolean, + nullable: true, + example: false, + }, + state: { + description: "Indicates the state of this payment declaration", + type: :string, + nullable: false, + example: "submitted", + enum: Declaration.states.keys, + }, + updated_at: { + description: "The date the application was last updated", + type: :string, + nullable: false, + format: :"date-time", + example: "2021-05-31T02:22:32.000Z", + }, + has_passed: { + description: "Whether the participant has failed or passed", + type: :string, + nullable: true, + example: nil, + }, + }, + }, + }, + }, +}.tap { |h| + h[:v2] = h[:v1].deep_dup + h[:v2][:properties][:attributes][:required] = h[:v1][:properties][:attributes][:required].excluding(:voided, :eligible_for_payment) + h[:v2][:properties][:attributes][:properties] = h[:v1][:properties][:attributes][:properties].excluding(:voided, :eligible_for_payment) + h[:v3] = h[:v2].deep_dup + h[:v3][:properties][:attributes][:properties][:statement_id] = { + description: "Unique ID of the statement the declaration will be paid as part of", + type: "string", + format: "uuid", + example: "cd3a12347-7308-4879-942a-c4a70ced400a", + nullable: true, + } + h[:v3][:properties][:attributes][:properties][:clawback_statement_id] = { + description: "Unique id of the statement to which the declaration will be clawed back on, if any", + type: "string", + format: "uuid", + example: "cd3a12347-7308-4879-942a-c4a70ced400a", + nullable: true, + } + h[:v3][:properties][:attributes][:properties][:ineligible_for_funding_reason] = { + description: "If the declaration is ineligible, the reason why", + type: "string", + enum: %w[ + duplicate_declaration + ], + nullable: true, + example: "duplicate_declaration", + } + h[:v3][:properties][:attributes][:properties][:uplift_paid] = { + description: "If participant is eligible for uplift, whether it has been paid as part of this declaration", + type: "boolean", + example: true, + } + h[:v3][:properties][:attributes][:properties][:has_passed] = { + description: "Whether the participant has failed or passed", + type: "string", # Need update when completed + example: nil, + nullable: true, + } + h[:v3][:properties][:attributes][:properties][:lead_provider_name] = { + description: "The name of the provider that submitted the declaration", + type: "string", + example: "Example Institute", + nullable: false, + } + h[:v3][:properties][:attributes][:properties][:created_at] = { + description: "The date the application was created", + type: :string, + nullable: false, + format: :"date-time", + example: "2021-05-31T02:22:32.000Z", + } +}.freeze diff --git a/spec/swagger_schemas/requests/participant_declaration_completed_request.rb b/spec/swagger_schemas/requests/participant_declaration_completed_request.rb new file mode 100644 index 0000000000..232860f351 --- /dev/null +++ b/spec/swagger_schemas/requests/participant_declaration_completed_request.rb @@ -0,0 +1,53 @@ +PARTICIPANT_DECLARATION_COMPLETED_REQUEST = { + description: "An NPQ completed participant declaration", + type: :object, + required: %i[ + participant_id + declaration_type + declaration_date + course_identifier + has_passed + ], + additionalProperties: false, + properties: { + participant_id: { + description: "The unique id of the participant", + type: :string, + format: :uuid, + example: "db3a7848-7308-4879-942a-c4a70ced400a", + }, + declaration_type: { + description: "The event declaration type", + type: :string, + enum: %w[ + completed + ], + example: "completed", + }, + declaration_date: { + description: "The event declaration date", + type: :string, + format: "date-time", + example: "2021-05-31T02:21:32.000Z", + }, + course_identifier: { + description: "The type of course the participant is enrolled in", + type: :string, + enum: Course::IDENTIFIERS, + example: Course::IDENTIFIERS.first, + }, + has_passed: { + description: "Whether the participant has failed or passed", + type: :boolean, + example: true, + nullable: true, + }, + }, + example: { + participant_id: "db3a7848-7308-4879-942a-c4a70ced400a", + declaration_type: "completed", + declaration_date: "2021-05-31T02:21:32.000Z", + course_identifier: Course::IDENTIFIERS.first, + has_passed: true, + }, +}.freeze diff --git a/spec/swagger_schemas/requests/participant_declaration_request.rb b/spec/swagger_schemas/requests/participant_declaration_request.rb new file mode 100644 index 0000000000..ed6529de86 --- /dev/null +++ b/spec/swagger_schemas/requests/participant_declaration_request.rb @@ -0,0 +1,23 @@ +PARTICIPANT_DECLARATION_REQUEST = { + description: "A participant declaration data request", + type: :object, + required: %w[type attributes], + properties: { + type: { + type: :string, + required: true, + enum: %w[ + participant-declaration + ], + example: "participant-declaration", + }, + attributes: { + required: true, + anyOf: [ + { "$ref": "#/components/schemas/ParticipantDeclarationStartedRequest" }, + { "$ref": "#/components/schemas/ParticipantDeclarationRetainedRequest" }, + { "$ref": "#/components/schemas/ParticipantDeclarationCompletedRequest" }, + ], + }, + }, +}.freeze diff --git a/spec/swagger_schemas/requests/participant_declaration_retained_request.rb b/spec/swagger_schemas/requests/participant_declaration_retained_request.rb new file mode 100644 index 0000000000..fb5a4010b0 --- /dev/null +++ b/spec/swagger_schemas/requests/participant_declaration_retained_request.rb @@ -0,0 +1,46 @@ +PARTICIPANT_DECLARATION_RETAINED_REQUEST = { + description: "An NPQ participant retained declaration", + type: :object, + additionalProperties: false, + properties: { + participant_id: { + description: "The unique id of the participant", + type: :string, + format: :uuid, + example: "db3a7848-7308-4879-942a-c4a70ced400a", + }, + declaration_type: { + description: "The event declaration type", + type: :string, + enum: %w[ + retained-1 + retained-2 + ], + example: "retained-1", + }, + declaration_date: { + description: "The event declaration date", + type: :string, + format: "date-time", + example: "2021-05-31T02:21:32.000Z", + }, + course_identifier: { + description: "The type of course the participant is enrolled in", + type: :string, + enum: Course::IDENTIFIERS, + example: Course::IDENTIFIERS.first, + }, + }, + required: %i[ + participant_id + declaration_type + declaration_date + course_identifier + ], + example: { + participant_id: "db3a7848-7308-4879-942a-c4a70ced400a", + declaration_type: "retained-1", + declaration_date: "2021-05-31T02:21:32.000Z", + course_identifier: Course::IDENTIFIERS.first, + }, +}.freeze diff --git a/spec/swagger_schemas/requests/participant_declaration_started_request.rb b/spec/swagger_schemas/requests/participant_declaration_started_request.rb new file mode 100644 index 0000000000..28c949a2dd --- /dev/null +++ b/spec/swagger_schemas/requests/participant_declaration_started_request.rb @@ -0,0 +1,49 @@ +PARTICIPANT_DECLARATION_STARTED_REQUEST = { + description: "An NPQ started participant declaration", + type: :object, + additionalProperties: false, + properties: { + participant_id: { + description: "The unique id of the participant", + type: :string, + format: :uuid, + required: true, + example: "db3a7848-7308-4879-942a-c4a70ced400a", + }, + declaration_type: { + description: "The event declaration type", + type: :string, + required: true, + enum: %w[ + started + ], + example: "started", + }, + declaration_date: { + description: "The event declaration date", + type: :string, + required: true, + format: "date-time", + example: "2021-05-31T02:21:32.000Z", + }, + course_identifier: { + description: "The type of course the participant is enrolled in", + type: :string, + required: true, + enum: Course::IDENTIFIERS, + example: Course::IDENTIFIERS.first, + }, + }, + required: %i[ + participant_id + declaration_type + declaration_date + course_identifier + ], + example: { + participant_id: "db3a7848-7308-4879-942a-c4a70ced400a", + declaration_type: "started", + declaration_date: "2021-05-31T02:21:32.000Z", + course_identifier: Course::IDENTIFIERS.first, + }, +}.freeze diff --git a/spec/swagger_schemas/responses/participant_declaration.rb b/spec/swagger_schemas/responses/participant_declaration.rb new file mode 100644 index 0000000000..efe3df90ae --- /dev/null +++ b/spec/swagger_schemas/responses/participant_declaration.rb @@ -0,0 +1,15 @@ +PARTICIPANT_DECLARATION_RESPONSE = { + v1: { + description: "A single participant declaration.", + type: :object, + required: %i[data], + properties: { + data: { + "$ref": "#/components/schemas/ParticipantDeclaration", + }, + }, + }, +}.tap { |h| + h[:v2] = h[:v1] + h[:v3] = h[:v1] +}.freeze diff --git a/spec/swagger_schemas/responses/participant_declarations.rb b/spec/swagger_schemas/responses/participant_declarations.rb new file mode 100644 index 0000000000..f138dbf4ae --- /dev/null +++ b/spec/swagger_schemas/responses/participant_declarations.rb @@ -0,0 +1,16 @@ +PARTICIPANT_DECLARATIONS_RESPONSE = { + v1: { + description: "A list of participant declarations.", + type: :object, + required: %i[data], + properties: { + data: { + type: :array, + items: { "$ref": "#/components/schemas/ParticipantDeclaration" }, + }, + }, + }, +}.tap { |h| + h[:v2] = h[:v1] + h[:v3] = h[:v1] +}.freeze