test(notifications): cover tap targets, quick-answer tokens and the action route; document them

This commit is contained in:
Marc-André Bombeck committed 2026-10-11 12:33:02 +02:00
1 parent 40e66bf027
commit 5435890275
16 files changed
+1300 -2

No files matched your search

+112
View File
@@ -13103,6 +13103,7 @@ paths:
- WEB
- TELEGRAM
- DAYLIO
- NOTIFICATION
- in: query
name: from
schema:
@@ -21632,6 +21633,56 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
/api/notifications/action/{token}:
post:
tags:
- Notifications
summary: Log a quick answer tapped inside a notification
description: "Called by a notification app (ntfy `http` action), never by a signed-in client: the signed path token is
the only credential. The token is bound to one user and one answer, expires six hours after the reminder was
sent, and is single-use across all answers offered on that reminder. Rate-limited per client address before the
token is read. Writes a mood entry with source `NOTIFICATION`; refused with 403 when the mood module is off."
parameters:
- in: path
name: token
schema:
type: string
description: Signed action token from the notification's URL.
required: true
description: Signed action token from the notification's URL.
responses:
"200":
description: The answer was logged.
content:
application/json:
schema:
$ref: "#/components/schemas/NotificationActionResponse"
"401":
description: Invalid token (forged, altered, or unknown user).
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"403":
description: The mood module is turned off for this account.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"409":
description: This reminder was already answered.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"410":
description: The answer expired.
content:
application/json:
schema:
$ref: "#/components/schemas/ErrorEnvelope"
"422": *a4
"429": *a5
/api/notifications/preferences:
get:
tags:
@@ -27417,6 +27468,14 @@ components:
properties:
clientManaged:
type: boolean
content:
type: object
properties:
detail:
type: string
enum:
- generic
- detailed
baseUpdatedAt:
description: "Optimistic-concurrency base token: the `updatedAt` the client last read for this resource. Omit it for the
legacy unconditional write (older clients are unaffected). When present, the write is guarded on the stored
@@ -28816,6 +28875,7 @@ components:
- WEB
- TELEGRAM
- DAYLIO
- NOTIFICATION
externalId:
description: "iOS-side source-stable id for idempotent dedup on the `(userId, source, externalId)` key. Must be stable
across app restarts — an object description or memory address (`<Class: 0x…>`, `0x12ab34cd`) is a new value
@@ -29336,6 +29396,7 @@ components:
- WEB
- TELEGRAM
- DAYLIO
- NOTIFICATION
externalId:
type: string
minLength: 1
@@ -52677,6 +52738,19 @@ components:
- nudgeRoutine
- nudgeFrequency
additionalProperties: false
content:
type: object
properties:
detail:
type: string
enum:
- generic
- detailed
description: What a notification may show. "generic" (default) names what it is about with no health figure; "detailed"
adds figures such as the morning score. Tap targets and quick answers are the same in both.
required:
- detail
additionalProperties: false
updatedAt:
description: "Optimistic-concurrency token: the stored row's `updatedAt` at read/write time. Echo it back as
`baseUpdatedAt` on the next write. Opaque — only ever echo a server-returned value, never parse or
@@ -52689,6 +52763,7 @@ components:
- mood
- cycle
- coach
- content
additionalProperties: false
PatchNotificationPrefsResponse:
type: object
@@ -65116,6 +65191,7 @@ components:
- WEB
- TELEGRAM
- DAYLIO
- NOTIFICATION
externalId:
anyOf:
- type: string
@@ -78271,6 +78347,42 @@ components:
required:
- ok
additionalProperties: false
NotificationActionResponse:
type: object
properties:
data:
$ref: "#/components/schemas/NotificationActionResult"
error:
type: "null"
meta:
type: object
properties:
requestId:
type: string
additionalProperties: false
required:
- data
- error
additionalProperties: false
NotificationActionResult:
type: object
properties:
logged:
type: boolean
const: true
action:
type: string
enum:
- mood-good
- mood-okay
- mood-bad
description: "The answer that was logged: mood-good = 4 (GUT), mood-okay = 3 (OKAY), mood-bad = 2 (SCHLECHT) on the
five-point mood scale."
required:
- logged
- action
additionalProperties: false
description: A quick answer from a notification, logged as a mood entry.
GetNotificationPreferences:
type: object
properties: