Add the mobile push working hours to the user preferences API

What does this MR do and why?

Exposes the mobile push working hours through the REST API, so the mobile app can show and change them.

  • GET /user/preferences returns mobile_push_working_hours_enabled, mobile_push_working_hours_start and _end (minutes after midnight), mobile_push_working_days (weekday names, default Monday to Friday) and mobile_push_working_hours_time_zone (IANA name).
  • PUT /user/preferences accepts the same five attributes, with the minute range, the weekday names and the 64-character zone limit checked at the boundary. The array you send replaces the whole set of days.
  • A failed model validation now returns its message in the 400 response, so a client can show what was wrong.
  • An older server returns none of the fields, which is how the mobile app learns the instance cannot do this.
  • doc/api/users.md, doc/api/mobile_push_subscriptions.md and the OpenAPI document describe the fields. bin/rake gitlab:openapi:v3:generate leaves doc/api/openapi/openapi_v3.yaml unchanged.

This MR is the switch for the feature. It targets the summary MR (C2b), so the API cannot reach master before the server can hold a push and send the summary.

References

Split from !260440 (closed), as agreed with the reviewer there: seven merge requests of 200 to 300 lines each, cut where the code does not reference the other parts. Each one targets its parent branch and is retargeted to master when the parent merges.

Merge request Targets
A Extract the mobile push recipient checks and the APNs fan-out master
B1 Add a value object for mobile push working hours A
B2 Store mobile push working hours on the user preference B1
C1 Hold mobile pushes for to-dos outside working hours B2
C2a Add the held summary that resumes one user's mobile pushes C1
C2b Send the mobile push summaries when working hours begin C2a
D (this MR) Add the mobile push working hours to the user preferences API C2b

Merge order is the chain order: A, B1, B2, C1, C2a, C2b, then D. D is the switch: it targets C2b, so the API cannot reach master before the server can hold a push and send its summary. Any other order would open a window on GitLab.com where users who enabled the schedule have their pushes held but not summarized until C2b deploys.

Screenshots or screen recordings

No UI changes.

How to set up and validate locally

  1. Set a window, in your zone:

    curl --request PUT --header "PRIVATE-TOKEN: <token>" "http://gdk.test:3000/api/v4/user/preferences" \
      --data "mobile_push_working_hours_enabled=true&mobile_push_working_hours_start=600&mobile_push_working_hours_end=1020&mobile_push_working_days[]=monday&mobile_push_working_days[]=tuesday&mobile_push_working_hours_time_zone=Europe/Berlin"
  2. curl --header "PRIVATE-TOKEN: <token>" "http://gdk.test:3000/api/v4/user/preferences" returns the five fields.

  3. An unknown zone on PUT returns 400 with "Mobile push working hours time zone is not a valid time zone"; a start of 1500 is rejected by the parameter validation.

MR acceptance checklist

Evaluated against the MR acceptance checklist.

🤖 Generated with Claude Code

Edited by Marcel van Remmerden

Merge request reports

Loading
Loading