mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-08 20:42:43 +00:00
feat(topics): compute topic overviews and topic pages on the server
GET /api/topics answers one entry per topic the record holds data for:
a headline value, a rule-based sentence and a 30-day sparkline.
GET /api/topics/{topic} answers a topic's signals with their usual
ranges, side-by-side series for a chosen window, the relationships
between its signals, 90-day trends, what it holds nothing for yet, and
its blocks (training load, lab markers with their trend, screener
trends, the cycle day).
Every figure comes from reads the metric pages already make: the local
daily values, the reconstructed nights, the mood score, computeLabTrend,
the training load and the screener trends. No model is involved. A
relationship says nothing below 14 paired days and is only called a
pattern at p < 0.05; a lab trend needs three readings spanning a year.
The preview is the viewer's own opt-in: with it off both routes answer
404 topics.preview_off. Topics, signals and blocks follow the record's
module switches and the sections the viewer's grant opens; the routes
read across sections, so a scoped grant is refused like the timeline.
/api/auth/me publishes the caller's opt-ins as previewFeatures.
This commit is contained in:
1 parent
14d0184b63
commit
cc04e0944d
30 files changed
+3937
-35
No files matched your search
+758
-5
@@ -26754,6 +26754,95 @@ paths:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"422": *a4
|
||||
"429": *a5
|
||||
/api/topics:
|
||||
get:
|
||||
tags:
|
||||
- Insights
|
||||
summary: Topic overview (preview)
|
||||
description: One entry per topic the record holds data for, with a headline value, a rule-based sentence and a 30-day
|
||||
sparkline, computed from the same daily values the metric pages draw. No model, no AI gate. Topics follow the
|
||||
record's module switches. Reads across sections, so a grant scoped to some of them is refused.
|
||||
responses:
|
||||
"200":
|
||||
description: The overview.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/TopicOverviewEnvelope"
|
||||
"401": *a1
|
||||
"403": *a15
|
||||
"404":
|
||||
description: "`topics.preview_off`: the person reading has not switched the topics preview on (Settings > System >
|
||||
Preview features). The preview is per account and off by default."
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"422": *a4
|
||||
"429": *a5
|
||||
/api/topics/{topic}:
|
||||
get:
|
||||
tags:
|
||||
- Insights
|
||||
summary: One topic (preview)
|
||||
description: "A topic's signals with their usual ranges, the side-by-side series for `range`, relationships between its
|
||||
signals (nothing is said below 14 paired days), 90-day trends, the signals it holds nothing for yet, and its
|
||||
blocks: training load, lab markers with their trend (three readings spanning a year), screener trends, today's
|
||||
cycle day. No model, no AI gate."
|
||||
parameters:
|
||||
- in: path
|
||||
name: topic
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- heart
|
||||
- body
|
||||
- blood-pressure
|
||||
- sleep
|
||||
- activity
|
||||
- metabolism
|
||||
- mind
|
||||
- cycle
|
||||
description: The topic, as its URL slug.
|
||||
required: true
|
||||
description: The topic, as its URL slug.
|
||||
- in: query
|
||||
name: range
|
||||
schema:
|
||||
default: 30d
|
||||
description: The window the side-by-side series cover. The usual ranges, the trends and the relationships always read at
|
||||
least the trailing 90 days.
|
||||
type: string
|
||||
enum:
|
||||
- 7d
|
||||
- 30d
|
||||
- 90d
|
||||
- 1y
|
||||
description: The window the side-by-side series cover. The usual ranges, the trends and the relationships always read at
|
||||
least the trailing 90 days.
|
||||
responses:
|
||||
"200":
|
||||
description: The topic.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/TopicDetailEnvelope"
|
||||
"401": *a1
|
||||
"403": *a15
|
||||
"404":
|
||||
description: >-
|
||||
`topics.preview_off`: the person reading has not switched the topics preview on (Settings > System > Preview
|
||||
features). The preview is per account and off by default.
|
||||
|
||||
|
||||
`topics.not_found`: no topic by that name. `topics.not_available`: the record's module switches do not offer
|
||||
this topic.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"422": *a4
|
||||
"429": *a5
|
||||
/api/bugreport:
|
||||
post:
|
||||
security: []
|
||||
@@ -38003,10 +38092,11 @@ components:
|
||||
symptoms.definition.limitReached, symptoms.definition.notFound, symptoms.episode.notOpen,
|
||||
symptoms.event.notFound, symptoms.invalid; timeline — timeline.invalid; tokens —
|
||||
tokens.documents.ceiling_reached, tokens.measurements.ceiling_reached, tokens.workouts.ceiling_reached;
|
||||
vaccination — vaccination.booster-invalid, vaccination.booster-no-antigen,
|
||||
vaccination.booster-out-of-scope, vaccination.custom-vaccine-not-found, vaccination.custom.invalid,
|
||||
vaccination.custom.name-taken, vaccination.custom.not-found, vaccination.encounter-not-found,
|
||||
vaccination.identity-required, vaccination.invalid, vaccination.link.invalid, vaccination.not-found,
|
||||
topics — topics.not_available, topics.not_found, topics.preview_off; vaccination —
|
||||
vaccination.booster-invalid, vaccination.booster-no-antigen, vaccination.booster-out-of-scope,
|
||||
vaccination.custom-vaccine-not-found, vaccination.custom.invalid, vaccination.custom.name-taken,
|
||||
vaccination.custom.not-found, vaccination.encounter-not-found, vaccination.identity-required,
|
||||
vaccination.invalid, vaccination.link.invalid, vaccination.not-found,
|
||||
vaccination.practitioner-not-found; workout — workout.batch.invalid, workout.batch.payload_too_large,
|
||||
workout.batch.source_not_permitted, workout.batch.too_large, workout.delete.synced_source; (unprefixed)
|
||||
— about_me_conflict, ai_response_truncated, coach_prefs_conflict, dashboard_layout_conflict, empty_file,
|
||||
@@ -72671,7 +72761,8 @@ components:
|
||||
properties:
|
||||
topics:
|
||||
type: boolean
|
||||
description: Topic overview pages above the single-metric Insights pages. Off by default.
|
||||
description: "The Topics area (`/api/topics`): overview pages that bring related signals together above the
|
||||
single-metric Insights pages, which stay as they are. Off by default."
|
||||
required:
|
||||
- topics
|
||||
additionalProperties: false
|
||||
@@ -85168,6 +85259,8 @@ components:
|
||||
$ref: "#/components/schemas/AiAccountBlock"
|
||||
coachReasoning:
|
||||
$ref: "#/components/schemas/CoachReasoningState"
|
||||
previewFeatures:
|
||||
$ref: "#/components/schemas/PreviewFeatures"
|
||||
recordSession:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/RecordSessionState"
|
||||
@@ -85198,6 +85291,7 @@ components:
|
||||
- moduleAccess
|
||||
- ai
|
||||
- coachReasoning
|
||||
- previewFeatures
|
||||
- recordSession
|
||||
- notificationPrefs
|
||||
- onboarding
|
||||
@@ -92230,6 +92324,665 @@ components:
|
||||
- data
|
||||
- error
|
||||
additionalProperties: false
|
||||
TopicOverviewEnvelope:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: "#/components/schemas/TopicOverview"
|
||||
error:
|
||||
type: "null"
|
||||
meta:
|
||||
type: object
|
||||
properties:
|
||||
requestId:
|
||||
type: string
|
||||
additionalProperties: false
|
||||
required:
|
||||
- data
|
||||
- error
|
||||
additionalProperties: false
|
||||
TopicOverview:
|
||||
type: object
|
||||
properties:
|
||||
topics:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/TopicOverviewEntry"
|
||||
empty:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/TopicKey"
|
||||
description: Offered topics with nothing recorded yet.
|
||||
hiddenByModule:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/TopicKey"
|
||||
description: Topics whose every module is switched off for the record.
|
||||
required:
|
||||
- topics
|
||||
- empty
|
||||
- hiddenByModule
|
||||
additionalProperties: false
|
||||
TopicOverviewEntry:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
$ref: "#/components/schemas/TopicKey"
|
||||
headline:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/TopicHeadline"
|
||||
- type: "null"
|
||||
summary:
|
||||
$ref: "#/components/schemas/TopicSummary"
|
||||
tone:
|
||||
type: string
|
||||
enum:
|
||||
- steady
|
||||
- watch
|
||||
- learning
|
||||
sparkline:
|
||||
type: array
|
||||
items:
|
||||
type: number
|
||||
description: The headline signal's daily values over the last 30 days, oldest first; empty when the headline is a block.
|
||||
recorded:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
total:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
required:
|
||||
- key
|
||||
- headline
|
||||
- summary
|
||||
- tone
|
||||
- sparkline
|
||||
- recorded
|
||||
- total
|
||||
additionalProperties: false
|
||||
TopicKey:
|
||||
type: string
|
||||
enum:
|
||||
- heart
|
||||
- body
|
||||
- blood-pressure
|
||||
- sleep
|
||||
- activity
|
||||
- metabolism
|
||||
- mind
|
||||
- cycle
|
||||
description: A topic, as its URL slug.
|
||||
TopicHeadline:
|
||||
oneOf:
|
||||
- type: object
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
const: signal
|
||||
key:
|
||||
$ref: "#/components/schemas/TopicSignalKey"
|
||||
value:
|
||||
type: number
|
||||
day:
|
||||
type: string
|
||||
description: A local calendar day, `YYYY-MM-DD`.
|
||||
required:
|
||||
- kind
|
||||
- key
|
||||
- value
|
||||
- day
|
||||
additionalProperties: false
|
||||
- type: object
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
const: labs
|
||||
inRange:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
total:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
required:
|
||||
- kind
|
||||
- inRange
|
||||
- total
|
||||
additionalProperties: false
|
||||
- type: object
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
const: cycleDay
|
||||
dayOfCycle:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
required:
|
||||
- kind
|
||||
- dayOfCycle
|
||||
additionalProperties: false
|
||||
- type: object
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
const: screener
|
||||
instrument:
|
||||
type: string
|
||||
score:
|
||||
type: number
|
||||
required:
|
||||
- kind
|
||||
- instrument
|
||||
- score
|
||||
additionalProperties: false
|
||||
type: object
|
||||
TopicSignalKey:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/MeasurementType"
|
||||
- type: string
|
||||
const: MOOD
|
||||
description: "A daily series a topic reads: a `MeasurementType`, or `MOOD` for the day's mean mood score (1 to 5).
|
||||
Values are in the type's stored unit (sleep in minutes asleep per night, keyed by the day the night ended);
|
||||
clients convert for display as they do for the metric pages."
|
||||
TopicSummary:
|
||||
type: object
|
||||
properties:
|
||||
code:
|
||||
type: string
|
||||
enum:
|
||||
- outside
|
||||
- labs
|
||||
- cycleDay
|
||||
- steady
|
||||
- learning
|
||||
- empty
|
||||
signal:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/TopicSignalKey"
|
||||
- type: "null"
|
||||
direction:
|
||||
anyOf:
|
||||
- type: string
|
||||
enum:
|
||||
- above
|
||||
- below
|
||||
- type: "null"
|
||||
count:
|
||||
anyOf:
|
||||
- type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
- type: "null"
|
||||
total:
|
||||
anyOf:
|
||||
- type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
- type: "null"
|
||||
required:
|
||||
- code
|
||||
- signal
|
||||
- direction
|
||||
- count
|
||||
- total
|
||||
additionalProperties: false
|
||||
description: "The topic's one sentence as a code with parameters, picked by a fixed rule (never model text): `outside`
|
||||
names the first signal outside its usual range and the direction; `labs` counts lab markers inside their window
|
||||
(`count` of `total`); `cycleDay` gives today's cycle day in `count`; `steady` counts signals inside their range
|
||||
(`count` of `total` recorded); `learning` while no range is established; `empty` without any data."
|
||||
TopicDetailEnvelope:
|
||||
type: object
|
||||
properties:
|
||||
data:
|
||||
$ref: "#/components/schemas/TopicDetail"
|
||||
error:
|
||||
type: "null"
|
||||
meta:
|
||||
type: object
|
||||
properties:
|
||||
requestId:
|
||||
type: string
|
||||
additionalProperties: false
|
||||
required:
|
||||
- data
|
||||
- error
|
||||
additionalProperties: false
|
||||
TopicDetail:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
$ref: "#/components/schemas/TopicKey"
|
||||
range:
|
||||
type: string
|
||||
enum:
|
||||
- 7d
|
||||
- 30d
|
||||
- 90d
|
||||
- 1y
|
||||
from:
|
||||
type: string
|
||||
description: A local calendar day, `YYYY-MM-DD`.
|
||||
to:
|
||||
type: string
|
||||
description: A local calendar day, `YYYY-MM-DD`.
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- ready
|
||||
- partial
|
||||
- empty
|
||||
summary:
|
||||
$ref: "#/components/schemas/TopicSummary"
|
||||
signals:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/TopicSignal"
|
||||
series:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
$ref: "#/components/schemas/TopicSignalKey"
|
||||
usual:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/TopicUsualRange"
|
||||
- type: "null"
|
||||
points:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
day:
|
||||
type: string
|
||||
description: A local calendar day, `YYYY-MM-DD`.
|
||||
value:
|
||||
type: number
|
||||
required:
|
||||
- day
|
||||
- value
|
||||
additionalProperties: false
|
||||
required:
|
||||
- key
|
||||
- usual
|
||||
- points
|
||||
additionalProperties: false
|
||||
relationships:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/TopicRelationship"
|
||||
trends:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/TopicTrend"
|
||||
missing:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/TopicSignalKey"
|
||||
description: Signals the topic could show that hold no value yet.
|
||||
labs:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/TopicLabPanel"
|
||||
- type: "null"
|
||||
training:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/WorkoutTrainingLoad"
|
||||
- type: "null"
|
||||
screeners:
|
||||
anyOf:
|
||||
- type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/MentalHealthAssessmentTrend"
|
||||
- type: "null"
|
||||
cycle:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/TopicCycleSummary"
|
||||
- type: "null"
|
||||
required:
|
||||
- key
|
||||
- range
|
||||
- from
|
||||
- to
|
||||
- status
|
||||
- summary
|
||||
- signals
|
||||
- series
|
||||
- relationships
|
||||
- trends
|
||||
- missing
|
||||
- labs
|
||||
- training
|
||||
- screeners
|
||||
- cycle
|
||||
additionalProperties: false
|
||||
TopicSignal:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
$ref: "#/components/schemas/TopicSignalKey"
|
||||
latest:
|
||||
anyOf:
|
||||
- type: object
|
||||
properties:
|
||||
day:
|
||||
type: string
|
||||
description: A local calendar day, `YYYY-MM-DD`.
|
||||
value:
|
||||
type: number
|
||||
required:
|
||||
- day
|
||||
- value
|
||||
additionalProperties: false
|
||||
- type: "null"
|
||||
usual:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/TopicUsualRange"
|
||||
- type: "null"
|
||||
state:
|
||||
type: string
|
||||
enum:
|
||||
- within
|
||||
- above
|
||||
- below
|
||||
- learning
|
||||
- none
|
||||
description: "`latest` against `usual`: `learning` while the range needs more days, `none` without a value."
|
||||
href:
|
||||
description: The in-app single-metric page of this signal.
|
||||
type:
|
||||
- string
|
||||
- "null"
|
||||
required:
|
||||
- key
|
||||
- latest
|
||||
- usual
|
||||
- state
|
||||
- href
|
||||
additionalProperties: false
|
||||
TopicUsualRange:
|
||||
type: object
|
||||
properties:
|
||||
low:
|
||||
type: number
|
||||
high:
|
||||
type: number
|
||||
center:
|
||||
type: number
|
||||
days:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
description: Days the band was built from.
|
||||
required:
|
||||
- low
|
||||
- high
|
||||
- center
|
||||
- days
|
||||
additionalProperties: false
|
||||
description: "The personal usual range over the trailing 90 days: median ± 3 scaled MAD of the daily values, never
|
||||
narrower than the measurement's own wobble. Needs 7 days, else null."
|
||||
TopicRelationship:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
x:
|
||||
$ref: "#/components/schemas/TopicSignalKey"
|
||||
y:
|
||||
$ref: "#/components/schemas/TopicSignalKey"
|
||||
lagDays:
|
||||
anyOf:
|
||||
- type: number
|
||||
const: 0
|
||||
- type: number
|
||||
const: 1
|
||||
description: "`x` on day d is held against `y` on day d + `lagDays`."
|
||||
kind:
|
||||
type: string
|
||||
enum:
|
||||
- correlation
|
||||
- split
|
||||
pairedDays:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
requiredDays:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
description: "Paired days needed before anything is said: 14."
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- insufficient
|
||||
- no_clear_link
|
||||
- linked
|
||||
description: "`linked` only at p < 0.05 (Pearson, or Welch for a split); a pattern, never a cause."
|
||||
r:
|
||||
type:
|
||||
- number
|
||||
- "null"
|
||||
pValue:
|
||||
type:
|
||||
- number
|
||||
- "null"
|
||||
split:
|
||||
anyOf:
|
||||
- type: object
|
||||
properties:
|
||||
threshold:
|
||||
type: number
|
||||
belowDays:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
otherDays:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
belowMean:
|
||||
type: number
|
||||
otherMean:
|
||||
type: number
|
||||
difference:
|
||||
type: number
|
||||
required:
|
||||
- threshold
|
||||
- belowDays
|
||||
- otherDays
|
||||
- belowMean
|
||||
- otherMean
|
||||
- difference
|
||||
additionalProperties: false
|
||||
- type: "null"
|
||||
description: "For a split: the mean of `y` on days `x` sat below `threshold` against the other days."
|
||||
points:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
x:
|
||||
type: number
|
||||
y:
|
||||
type: number
|
||||
required:
|
||||
- x
|
||||
- y
|
||||
additionalProperties: false
|
||||
description: Paired values for a scatter, at most 120; empty when insufficient.
|
||||
required:
|
||||
- id
|
||||
- x
|
||||
- y
|
||||
- lagDays
|
||||
- kind
|
||||
- pairedDays
|
||||
- requiredDays
|
||||
- status
|
||||
- r
|
||||
- pValue
|
||||
- split
|
||||
- points
|
||||
additionalProperties: false
|
||||
TopicTrend:
|
||||
type: object
|
||||
properties:
|
||||
key:
|
||||
$ref: "#/components/schemas/TopicSignalKey"
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- ok
|
||||
- insufficient
|
||||
days:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
change:
|
||||
description: The least-squares change across the trailing 90 days, in the stored unit. Needs 14 days.
|
||||
type:
|
||||
- number
|
||||
- "null"
|
||||
weekly:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
day:
|
||||
type: string
|
||||
description: A local calendar day, `YYYY-MM-DD`.
|
||||
value:
|
||||
type: number
|
||||
required:
|
||||
- day
|
||||
- value
|
||||
additionalProperties: false
|
||||
description: Weekly means, each keyed by its Monday.
|
||||
required:
|
||||
- key
|
||||
- status
|
||||
- days
|
||||
- change
|
||||
- weekly
|
||||
additionalProperties: false
|
||||
TopicLabPanel:
|
||||
type: object
|
||||
properties:
|
||||
markers:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/components/schemas/TopicLabMarker"
|
||||
description: At most 24, newest reading first.
|
||||
inRange:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
withRange:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
latestOn:
|
||||
anyOf:
|
||||
- type: string
|
||||
description: A local calendar day, `YYYY-MM-DD`.
|
||||
- type: "null"
|
||||
required:
|
||||
- markers
|
||||
- inRange
|
||||
- withRange
|
||||
- latestOn
|
||||
additionalProperties: false
|
||||
TopicLabMarker:
|
||||
type: object
|
||||
properties:
|
||||
biomarkerId:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
unit:
|
||||
type: string
|
||||
latest:
|
||||
type: number
|
||||
takenOn:
|
||||
type: string
|
||||
description: A local calendar day, `YYYY-MM-DD`.
|
||||
low:
|
||||
type:
|
||||
- number
|
||||
- "null"
|
||||
high:
|
||||
type:
|
||||
- number
|
||||
- "null"
|
||||
status:
|
||||
type: string
|
||||
enum:
|
||||
- in-range
|
||||
- below
|
||||
- above
|
||||
- unknown
|
||||
readings:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
trend:
|
||||
$ref: "#/components/schemas/BiomarkerTrend"
|
||||
required:
|
||||
- biomarkerId
|
||||
- name
|
||||
- unit
|
||||
- latest
|
||||
- takenOn
|
||||
- low
|
||||
- high
|
||||
- status
|
||||
- readings
|
||||
- trend
|
||||
additionalProperties: false
|
||||
TopicCycleSummary:
|
||||
type: object
|
||||
properties:
|
||||
today:
|
||||
anyOf:
|
||||
- type: object
|
||||
properties:
|
||||
dayOfCycle:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
phase:
|
||||
type:
|
||||
- string
|
||||
- "null"
|
||||
required:
|
||||
- dayOfCycle
|
||||
- phase
|
||||
additionalProperties: false
|
||||
- type: "null"
|
||||
lengths:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
averageLength:
|
||||
type:
|
||||
- number
|
||||
- "null"
|
||||
periodsLogged:
|
||||
type: integer
|
||||
minimum: -9007199254740991
|
||||
maximum: 9007199254740991
|
||||
required:
|
||||
- today
|
||||
- lengths
|
||||
- averageLength
|
||||
- periodsLogged
|
||||
additionalProperties: false
|
||||
__schema0:
|
||||
anyOf:
|
||||
- type: string
|
||||
|
||||
Reference in new issue
Block a user