From 48a90a16d7922ca63231224fc98cda3019822a13 Mon Sep 17 00:00:00 2001 From: "Claude Sonnet 5.5" Date: Thu, 22 Oct 2026 13:59:44 +0200 Subject: [PATCH 1/3] [O2B-1623] Document the shift data handler The handler documentation was replaced by a disabled JSDoc rule: it now describes its parameters and its result. --- lib/server/controllers/shift.controller.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/server/controllers/shift.controller.js b/lib/server/controllers/shift.controller.js index cbba276f3f..c6c4380d1b 100644 --- a/lib/server/controllers/shift.controller.js +++ b/lib/server/controllers/shift.controller.js @@ -15,9 +15,14 @@ const { shiftService } = require('../services/shift/ShiftService.js'); const { updateExpressResponseFromNativeError } = require('../express/updateExpressResponseFromNativeError.js'); const { GetShiftDataDto } = require('../../domain/dtos/shift/GetShiftDataDto.js'); -// eslint-disable-next-line jsdoc/require-param /** - * Route to fetch shift data + * Route to fetch the data of the pending shift of the calling user + * + * @param {Object} request The *request* object represents the HTTP request and has properties for the request query + * string, parameters, body, HTTP headers, and so on. + * @param {Object} response The *response* object represents the HTTP response that an Express app sends when it gets an + * HTTP request. + * @returns {Promise} resolves once the response has been sent */ const getShiftDataHandler = async (request, response) => { const requestDto = await dtoValidator(GetShiftDataDto, request, response); From aa1c6bfa959579359800abf47c0a23be8b858841 Mon Sep 17 00:00:00 2001 From: "Claude Sonnet 5.5" Date: Tue, 20 Oct 2026 15:00:27 +0200 Subject: [PATCH 2/3] [O2B-1623] Document the shift-data endpoint in the HTTP API specification --- lib/server/api-docs/openapi.yaml | 73 ++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/lib/server/api-docs/openapi.yaml b/lib/server/api-docs/openapi.yaml index 2069aec8fa..605499ea69 100644 --- a/lib/server/api-docs/openapi.yaml +++ b/lib/server/api-docs/openapi.yaml @@ -47,6 +47,8 @@ tags: description: Types of runs (e.g. calibration kinds). - name: CTP trigger counters description: Counters of the central trigger processor, per run and trigger class. + - name: Shifts + description: Data used to fill end-of-shift reports. paths: /tags: @@ -394,6 +396,37 @@ paths: errors: - { status: 404, title: Not found, detail: Run with this run number (999999999) could not be found } + /shift-data: + get: + tags: [Shifts] + operationId: getShiftData + summary: Get the data of the pending shift of the calling user + description: | + Returns what a shifter needs to write their end-of-shift (EoS) report for the **pending shift**: the current shift, or the previous one + during the 30 minutes that follow its end. Shifts last 8 hours and are Night (23h-7h), Morning (7h-15h) and Afternoon (15h-23h) in the + Geneva time zone. The shift is deduced from the current time and the calling user, not from a parameter. + + `typeSpecific` depends on `shiftType`: `{ environments }` for `ECS`, `{ runs }` for `QC/PDP`, `{ runs, tagsCounters }` for `SL`, and `null` + for `SLIMOS` and `DCS`. + parameters: + - name: shiftType + in: query + required: true + description: Kind of shift. + schema: { type: string, enum: [ECS, QC/PDP, SLIMOS, SL, DCS], examples: [ECS] } + responses: + '200': + description: The shift data. + content: + application/json: + schema: { $ref: '#/components/schemas/ShiftDataResponse' } + '400': { $ref: '#/components/responses/ValidationError' } + '404': + description: The calling user is not known to Bookkeeping. + content: + application/json: + schema: { $ref: '#/components/schemas/ErrorResponse' } + components: securitySchemes: jwtQuery: @@ -596,3 +629,43 @@ components: data: type: array items: { $ref: '#/components/schemas/CtpTriggerCounters' } + Shift: + type: object + required: [start, end, period] + properties: + start: { type: integer, description: Epoch milliseconds. } + end: { type: integer, description: Epoch milliseconds. } + period: { type: string, enum: [Night, Morning, Afternoon] } + ShiftData: + type: object + required: [shift, issuesLogs, typeSpecific, infoFromPreviousShifter] + properties: + shift: { $ref: '#/components/schemas/Shift' } + issuesLogs: + type: array + description: Log entries of the shift carrying the tags of the shift type, EoS reports excluded (see the Logs resource). + items: { type: object, additionalProperties: true } + typeSpecific: + type: [object, 'null'] + description: Depends on the shift type, see the operation description. + properties: + environments: { type: array, description: 'ECS shift only.', items: { type: object, additionalProperties: true } } + runs: + type: object + description: QC/PDP and SL shifts only. Runs of the shift grouped by run definition. + additionalProperties: { type: array, items: { type: object, additionalProperties: true } } + tagsCounters: + type: object + description: SL shift only. Number of root logs of the shift per tag text, EoS reports excluded. + additionalProperties: { type: integer } + infoFromPreviousShifter: + type: object + description: The "For next shifter" section of the EoS report of the previous shift. Exactly one of the properties is set. + properties: + value: { type: string } + errorMessage: { type: string, description: 'Why nothing could be retrieved (no report, several reports, empty section...).' } + ShiftDataResponse: + type: object + required: [data] + properties: + data: { $ref: '#/components/schemas/ShiftData' } From 47cba7592d163191437982f14c4a5e91667fe54f Mon Sep 17 00:00:00 2001 From: "Claude Sonnet 5.5" Date: Thu, 22 Oct 2026 13:59:55 +0200 Subject: [PATCH 3/3] [O2B-1623] Regenerate the HTTP API documentation with the shift-data endpoint --- lib/server/api-docs/API.md | 29 ++++++++++++++++++++++++++ lib/server/api-docs/index.html | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/lib/server/api-docs/API.md b/lib/server/api-docs/API.md index 0b9bdd80fe..7dd06411a7 100644 --- a/lib/server/api-docs/API.md +++ b/lib/server/api-docs/API.md @@ -350,3 +350,32 @@ Responses: ```bash curl -g "$BOOKKEEPING_URL/api/ctp-trigger-counters/106?token=$TOKEN" ``` + +## Shifts + +Data used to fill end-of-shift reports. + +### `GET /shift-data` - Get the data of the pending shift of the calling user + +Operation id: `getShiftData` + +Returns what a shifter needs to write their end-of-shift (EoS) report for the **pending shift**: the current shift, or the previous one +during the 30 minutes that follow its end. Shifts last 8 hours and are Night (23h-7h), Morning (7h-15h) and Afternoon (15h-23h) in the +Geneva time zone. The shift is deduced from the current time and the calling user, not from a parameter. + +`typeSpecific` depends on `shiftType`: `{ environments }` for `ECS`, `{ runs }` for `QC/PDP`, `{ runs, tagsCounters }` for `SL`, and `null` +for `SLIMOS` and `DCS`. + +| Parameter | In | Type | Required | Notes | +| --- | --- | --- | --- | --- | +| `shiftType` | query | string | yes | Kind of shift. | + +Responses: + +- `200`: The shift data. +- `400`: The request failed validation. HTTP status is 400 although each error's `status` field is `"422"`. `source.pointer` has the form `/data/attributes//`. +- `404`: The calling user is not known to Bookkeeping. + +```bash +curl -g "$BOOKKEEPING_URL/api/shift-data?shiftType=ECS&token=$TOKEN" +``` diff --git a/lib/server/api-docs/index.html b/lib/server/api-docs/index.html index 6f3163ee7f..8caf3ba071 100644 --- a/lib/server/api-docs/index.html +++ b/lib/server/api-docs/index.html @@ -570,6 +570,44 @@

CTP trigger counters

curl -g "$BOOKKEEPING_URL/api/ctp-trigger-counters/106?token=$TOKEN"
 
+

Shifts

+

Data used to fill end-of-shift reports.

+
+

GET /shift-data - Get the data of the pending shift of the calling user

+ +

Operation id: getShiftData

+

Returns what a shifter needs to write their end-of-shift (EoS) report for the pending shift: the current shift, or the previous one +during the 30 minutes that follow its end. Shifts last 8 hours and are Night (23h-7h), Morning (7h-15h) and Afternoon (15h-23h) in the +Geneva time zone. The shift is deduced from the current time and the calling user, not from a parameter.

+

typeSpecific depends on shiftType: { environments } for ECS, { runs } for QC/PDP, { runs, tagsCounters } for SL, and null +for SLIMOS and DCS.

+ + + + + + + + + + + + + + + + + +
ParameterInTypeRequiredNotes
shiftTypequerystringyesKind of shift.
+

Responses:

+
    +
  • 200: The shift data.
  • +
  • 400: The request failed validation. HTTP status is 400 although each error's status field is "422". source.pointer has the form /data/attributes/<query|params|body>/<field>.
  • +
  • 404: The calling user is not known to Bookkeeping.
  • +
+
curl -g "$BOOKKEEPING_URL/api/shift-data?shiftType=ECS&token=$TOKEN"
+
+