mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 21:10:59 +00:00
Answer the native client's open server asks
- Publish timezone, glucoseUnit and a features block on the account payload; glucoseUnit reads as the closed pair the contract names, and features.trackIntake tells a separately released client that medications take the record-only switch. - Refuse a new dose for a record-only medication with medication.intake.notTracked on every dose-writing route; the bulk route reports it per entry as intake_not_tracked, and correcting an already resolved event stays open. - Answer passkey sign-in failures by name instead of a 500: passkey.challenge.expired, passkey.unknown, passkey.response.invalid and passkey.verification.failed, each with an audit row. - Carry one account-wide adherence figure in meta.aggregate on the batched compliance read, weighted by expected doses, and accept ?days=30|60|90|180|365 for a report window. - Accept ?days=30|90|180|365 on the mood insights read so stability covers the period shown, and name the window it covers. - Keep only the reminder that announces a dose off APNs when the phone owns medication reminders; follow-ups for a dose still open are pushed again, marked by a followUp flag the reminder cron sets. - Document which batch validation issues belong to an entry and pin it with a test that splits and resends a batch; publish rejectedFields items as ValidationIssue.
This commit is contained in:
1 parent
7bcb6f71d9
commit
bb563b6506
50 files changed
+1789
-142
No files matched your search
+234
-61
@@ -2650,7 +2650,15 @@ paths:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/PasskeyLoginVerifyResponse"
|
||||
"401": *a1
|
||||
"401":
|
||||
description: The sign-in did not prove anything (v1.42.0 codes; before, the first case answered 500). `meta.errorCode` =
|
||||
`passkey.challenge.expired` when the challenge is gone — it expired after five minutes, was already used, or
|
||||
was begun for a different account — so start a new sign-in; `passkey.verification.failed` when the assertion
|
||||
was checked and refused (signature, origin, relying-party id or challenge mismatch).
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"403":
|
||||
description: Passkey login is disabled — the operator runs `OIDC_ONLY=true`. `meta.errorCode` = `oidc_only`.
|
||||
content:
|
||||
@@ -2658,12 +2666,20 @@ paths:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"404":
|
||||
description: The assertion resolved to a user row that no longer exists.
|
||||
description: "`meta.errorCode` = `passkey.unknown` (v1.42.0): no passkey with this credential id is registered on this
|
||||
server — it was removed here, or belongs to another server. Tell the person to sign in another way. Without
|
||||
a code: the assertion resolved to a user row that no longer exists."
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"422":
|
||||
description: "`challengeId` or `credential` is missing, or (`meta.errorCode` = `passkey.response.invalid`, v1.42.0)
|
||||
`credential` is not a WebAuthn authentication response."
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"422": *a4
|
||||
"429": *a5
|
||||
/api/auth/refresh:
|
||||
post:
|
||||
@@ -4497,7 +4513,12 @@ paths:
|
||||
(`measurement.batch.invalid`, with every issue under `details.issues`), or
|
||||
(`measurement.batch.source_not_permitted`) carried an entry naming a source, any source, under a narrow
|
||||
`measurements:write` credential. Nothing was written in any of the three cases, and all three are permanent
|
||||
for the batch as sent: resending it unchanged is refused the same way."
|
||||
for the batch as sent: resending it unchanged is refused the same way. Which issues belong to an entry:
|
||||
every issue caused by one entry has a `path` that starts `entries.<n>` (the entry's index in the request,
|
||||
then the field, e.g. `entries.3.startDate`, or just `entries.4` when the entry is not an object). Those are
|
||||
the only per-entry issues, so a client may drop the named entries and resend the rest. An issue whose `path`
|
||||
is `\"\"` (the body is not an object), `entries` (missing, not an array, or empty) or `syncTrigger` is about
|
||||
the batch itself, and no split recovers it."
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
@@ -5131,11 +5152,14 @@ paths:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"422":
|
||||
description: Body validation failed (multi-issue envelope, breadcrumbed as
|
||||
description: "Body validation failed (multi-issue envelope, breadcrumbed as
|
||||
`medications.intake.update.validation-failed`), or `meta.errorCode` =
|
||||
`medications.intake.injection_site.disallowed` when the site is outside the medication's effective allowed
|
||||
set, or `medications.intake.force_slot.invalid` when `forceSlotInstant` is not a real slot of the
|
||||
medication. The latter two carry no issue list — branch on the code.
|
||||
medication, or (v1.42.0) `medication.intake.notTracked` when the event is still open and its medication is
|
||||
kept as a record only (`trackIntake: false`): resolving or snoozing it would record a new dose that is
|
||||
counted nowhere. Correcting an event that is already taken or skipped stays open. The coded refusals carry
|
||||
no issue list — branch on the code."
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
@@ -6397,7 +6421,16 @@ paths:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"409": *a7
|
||||
"422": *a4
|
||||
"422":
|
||||
description: "Body validation failed (multi-issue envelope), or `meta.errorCode` names the refusal:
|
||||
`medications.intake.injection_site.disallowed`, `medications.intake.force_slot.invalid`, or (v1.42.0)
|
||||
`medication.intake.notTracked` when the medication is kept as a record only (`trackIntake: false`). Its
|
||||
stored history stays; a new dose is refused rather than stored and counted nowhere. The check runs after
|
||||
ownership, so a foreign medication is still a 404."
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: "#/components/schemas/ErrorEnvelope"
|
||||
"429": *a13
|
||||
get:
|
||||
tags:
|
||||
@@ -6721,13 +6754,36 @@ paths:
|
||||
tags:
|
||||
- Medications
|
||||
summary: Batched adherence read for every medication of the caller
|
||||
description: Returns one compact row per non-PRN medication. A scheduled medication with no local schedule remains in
|
||||
the array with applicable=false and reason NO_LOCAL_SCHEDULE. compliance7/compliance30 stay non-null as all-zero
|
||||
description: >-
|
||||
Returns one compact row per non-PRN medication. A scheduled medication with no local schedule remains in the
|
||||
array with applicable=false and reason NO_LOCAL_SCHEDULE. compliance7/compliance30 stay non-null as all-zero
|
||||
compatibility placeholders for released clients; aware clients must ignore those percentages when
|
||||
applicable=false. complianceDisplay is null.
|
||||
|
||||
|
||||
v1.42.0, additive: `meta.aggregate` carries one figure for the whole account (`MedicationComplianceAggregate`,
|
||||
weighted by expected doses across the applicable medications; `null` when none applies), so a client never
|
||||
averages the rows itself. `days` (30, 60, 90, 180 or 365) adds a `complianceN` block in the same shape to every
|
||||
row and to the aggregate, for a report that covers its own window; `meta.days` echoes it. Any other `days` is a
|
||||
422 rather than a rounded window.
|
||||
parameters:
|
||||
- in: query
|
||||
name: days
|
||||
schema:
|
||||
description: Report window in days. 30 is already `compliance30`; the others add `compliance60` / `compliance90` /
|
||||
`compliance180` / `compliance365`.
|
||||
type: string
|
||||
enum:
|
||||
- "30"
|
||||
- "60"
|
||||
- "90"
|
||||
- "180"
|
||||
- "365"
|
||||
description: Report window in days. 30 is already `compliance30`; the others add `compliance60` / `compliance90` /
|
||||
`compliance180` / `compliance365`.
|
||||
responses:
|
||||
"200":
|
||||
description: One adherence row per medication.
|
||||
description: One adherence row per medication, and the account aggregate in `meta`.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
@@ -8773,9 +8829,10 @@ paths:
|
||||
summary: Update per-user notification preferences
|
||||
description: 'Deep-merges the supplied partial shape over the persisted row — a PATCH touching only one category leaves
|
||||
the siblings intact. Always returns the fully-resolved next state so clients can hard-set their optimistic
|
||||
update. `medication.clientManaged: true` (or `deliveryDefault: "client"`) suppresses server-side
|
||||
MEDICATION_REMINDER APNs; `medication.lowStockRunwayDays` (1–60, nullable, default 7) tunes the low-stock alert
|
||||
— null switches it off. Rate-limit 60/min per user.'
|
||||
update. `medication.clientManaged: true` (or `deliveryDefault: "client"`) keeps the MEDICATION_REMINDER that
|
||||
announces a dose off APNs and leaves the follow-ups for a dose still open on it (v1.42.0);
|
||||
`medication.lowStockRunwayDays` (1–60, nullable, default 7) tunes the low-stock alert — null switches it off.
|
||||
Rate-limit 60/min per user.'
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
@@ -12620,7 +12677,20 @@ paths:
|
||||
window the prior aggregate is served immediately while one background recompute warms a new one, so an active
|
||||
logger never re-pays the cold compute. Module-gated on `mood`; a disabled module answers 403 `module.disabled`
|
||||
even for a valid Bearer token. Cookie or Bearer auth; the caller is always resolved as themselves, so this read
|
||||
cannot be delegated to a shared record — which makes it the one mood surface a delegate cannot reach."
|
||||
cannot be delegated to a shared record — which makes it the one mood surface a delegate cannot reach. v1.42.0 —
|
||||
`days` cuts `stability` to the period a client shows; every other block is unchanged by it."
|
||||
parameters:
|
||||
- in: query
|
||||
name: days
|
||||
schema:
|
||||
description: "Trailing window for `stability`, in days. Omitted: 365. Any other value is a 422."
|
||||
type: string
|
||||
enum:
|
||||
- "30"
|
||||
- "90"
|
||||
- "180"
|
||||
- "365"
|
||||
description: "Trailing window for `stability`, in days. Omitted: 365. Any other value is a 422."
|
||||
responses:
|
||||
"200":
|
||||
description: The aggregate bundle.
|
||||
@@ -22283,7 +22353,10 @@ paths:
|
||||
"422":
|
||||
description: "Validation failed, with every issue listed rather than the first — an integration operator should see the
|
||||
whole shape at once. An empty or unstable `idempotencyKey` fails here: the column is unique table-wide, so
|
||||
an empty key would resolve to whichever unrelated row stored it first."
|
||||
an empty key would resolve to whichever unrelated row stored it first. Also 422 with `meta.errorCode` =
|
||||
`medication.intake.notTracked` (v1.42.0) when the named medication is kept as a record only (`trackIntake:
|
||||
false`); checked after the token's scope, so a token without this medication's scope learns nothing about
|
||||
it."
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
@@ -33578,25 +33651,26 @@ components:
|
||||
measurement.batch.too_large, measurement.bulk-delete.invalid, measurement.create.invalid,
|
||||
measurement.create.source_not_permitted, measurement.delete.too_large, measurement.duplicate_timestamp,
|
||||
measurement.restore.invalid, measurement.update.server_owned_source; medication —
|
||||
medication.intake.import.invalid_format; medications — medications.category.invalid,
|
||||
medications.category.limitReached, medications.category.unknown, medications.course.currentOpen,
|
||||
medications.course.invalid, medications.course.invalidRange, medications.course.notFound,
|
||||
medications.course.oneShot, medications.course.overlap, medications.course.windowRequired,
|
||||
medications.intake.bulk.apple_health_not_mirrored, medications.intake.bulk.invalid,
|
||||
medications.intake.bulk.too_large, medications.intake.force_slot.invalid,
|
||||
medications.intake.force_slot.occupied, medications.intake.injection_site.disallowed,
|
||||
medications.intake.taken_at.before_start, medications.mirror.limit_exceeded; mentalHealth —
|
||||
mentalHealth.rateLimited; module — module.disabled; modules — modules.body.invalid_json,
|
||||
modules.invalid; mood — mood.bulk-delete.invalid, mood.bulk.invalid, mood.bulk.too_large,
|
||||
mood.create.external_id_not_delegable, mood.create.invalid, mood.duplicate_timestamp,
|
||||
mood.linkedContext.invalid, mood.list.invalid, mood.not_found, mood.ratedFactor.out_of_range,
|
||||
mood.restore.invalid, mood.update.invalid; notification-prefs — notification-prefs.body.invalid_json;
|
||||
nutrient — nutrient.batch.invalid, nutrient.batch.too_large, nutrient.daily.invalid,
|
||||
nutrient.read.invalid, nutrient.water.invalid, nutrient.water.invalid_day; onboarding —
|
||||
onboarding.answers.invalid, onboarding.answers.rateLimited, onboarding.complete.invalid,
|
||||
medication.intake.import.invalid_format, medication.intake.notTracked; medications —
|
||||
medications.category.invalid, medications.category.limitReached, medications.category.unknown,
|
||||
medications.course.currentOpen, medications.course.invalid, medications.course.invalidRange,
|
||||
medications.course.notFound, medications.course.oneShot, medications.course.overlap,
|
||||
medications.course.windowRequired, medications.intake.bulk.apple_health_not_mirrored,
|
||||
medications.intake.bulk.invalid, medications.intake.bulk.too_large,
|
||||
medications.intake.force_slot.invalid, medications.intake.force_slot.occupied,
|
||||
medications.intake.injection_site.disallowed, medications.intake.taken_at.before_start,
|
||||
medications.mirror.limit_exceeded; mentalHealth — mentalHealth.rateLimited; module — module.disabled;
|
||||
modules — modules.body.invalid_json, modules.invalid; mood — mood.bulk-delete.invalid,
|
||||
mood.bulk.invalid, mood.bulk.too_large, mood.create.external_id_not_delegable, mood.create.invalid,
|
||||
mood.duplicate_timestamp, mood.linkedContext.invalid, mood.list.invalid, mood.not_found,
|
||||
mood.ratedFactor.out_of_range, mood.restore.invalid, mood.update.invalid; notification-prefs —
|
||||
notification-prefs.body.invalid_json; nutrient — nutrient.batch.invalid, nutrient.batch.too_large,
|
||||
nutrient.daily.invalid, nutrient.read.invalid, nutrient.water.invalid, nutrient.water.invalid_day;
|
||||
onboarding — onboarding.answers.invalid, onboarding.answers.rateLimited, onboarding.complete.invalid,
|
||||
onboarding.complete.recordNotFound, onboarding.complete.recordTargetMismatch,
|
||||
onboarding.disclaimer.invalid, onboarding.restart.invalid, onboarding.restart.rateLimited,
|
||||
onboarding.tour.invalid; personal_records — personal_records.invalid_query; practitioner —
|
||||
onboarding.tour.invalid; passkey — passkey.challenge.expired, passkey.response.invalid, passkey.unknown,
|
||||
passkey.verification.failed; personal_records — personal_records.invalid_query; practitioner —
|
||||
practitioner.invalid; profile — profile.update.emailInUse, profile.update.emailRateLimited,
|
||||
profile.update.emailSecondFactorRequired, profile.update.invalidBody, profile.update.nothingSaved;
|
||||
record_write — record_write.rate_limited; report-selection — report-selection.body.invalid_json,
|
||||
@@ -42535,19 +42609,7 @@ components:
|
||||
accepted once the window rolls over."
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
path:
|
||||
type: string
|
||||
code:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
required:
|
||||
- path
|
||||
- code
|
||||
- message
|
||||
additionalProperties: false
|
||||
$ref: "#/components/schemas/ValidationIssue"
|
||||
required:
|
||||
- id
|
||||
- username
|
||||
@@ -46546,6 +46608,11 @@ components:
|
||||
description: "`inserted`/`updated`/`duplicate` — the row landed (advance the cursor). `skipped` — not stored; see
|
||||
`reason`."
|
||||
reason:
|
||||
description: "Why a `skipped` entry was not stored. Among others: `medication_not_found`, `unstable_external_id`,
|
||||
`force_slot_invalid`, `force_slot_occupied`, `injection_site_not_allowed`, and (v1.42.0)
|
||||
`intake_not_tracked` for an entry against a medication kept as a record only (`trackIntake: false`), the
|
||||
per-entry form of `medication.intake.notTracked`. A skip is final: resending the entry gives the same
|
||||
answer."
|
||||
type: string
|
||||
id:
|
||||
description: The landed row id (absent on skips).
|
||||
@@ -48140,12 +48207,33 @@ components:
|
||||
meta:
|
||||
type: object
|
||||
properties:
|
||||
aggregate:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/MedicationComplianceAggregate"
|
||||
- type: "null"
|
||||
days:
|
||||
description: The `days` the request asked for.
|
||||
anyOf:
|
||||
- type: number
|
||||
const: 30
|
||||
- type: number
|
||||
const: 60
|
||||
- type: number
|
||||
const: 90
|
||||
- type: number
|
||||
const: 180
|
||||
- type: number
|
||||
const: 365
|
||||
requestId:
|
||||
type: string
|
||||
required:
|
||||
- aggregate
|
||||
additionalProperties: false
|
||||
description: Absent on servers older than v1.42.0; a client that reads it treats absence as no aggregate.
|
||||
required:
|
||||
- data
|
||||
- error
|
||||
- meta
|
||||
additionalProperties: false
|
||||
MedicationComplianceSummaryEntry:
|
||||
type: object
|
||||
@@ -48168,6 +48256,18 @@ components:
|
||||
compliance30:
|
||||
description: Thirty-day adherence summary, or an all-zero compatibility placeholder when applicable is false.
|
||||
$ref: "#/components/schemas/ComplianceResult"
|
||||
compliance60:
|
||||
description: "Present only on `?days=60`: the trailing 60 days."
|
||||
$ref: "#/components/schemas/ComplianceResult"
|
||||
compliance90:
|
||||
description: "Present only on `?days=90`: the trailing 90 days."
|
||||
$ref: "#/components/schemas/ComplianceResult"
|
||||
compliance180:
|
||||
description: "Present only on `?days=180`: the trailing 180 days."
|
||||
$ref: "#/components/schemas/ComplianceResult"
|
||||
compliance365:
|
||||
description: "Present only on `?days=365`: the trailing 365 days."
|
||||
$ref: "#/components/schemas/ComplianceResult"
|
||||
complianceDisplay:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/ComplianceDisplay"
|
||||
@@ -48393,6 +48493,45 @@ components:
|
||||
additionalProperties: false
|
||||
description: The two-row card block whose windows scale with dosing cadence (dense meds keep 7 / 30 days, sparse meds
|
||||
step both windows up). NOT the 30-day denominator — read `compliance30.totalExpected` for that.
|
||||
MedicationComplianceAggregate:
|
||||
type: object
|
||||
properties:
|
||||
compliance7:
|
||||
$ref: "#/components/schemas/ComplianceResult"
|
||||
compliance30:
|
||||
$ref: "#/components/schemas/ComplianceResult"
|
||||
compliance60:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/ComplianceResult"
|
||||
- type: "null"
|
||||
compliance90:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/ComplianceResult"
|
||||
- type: "null"
|
||||
compliance180:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/ComplianceResult"
|
||||
- type: "null"
|
||||
compliance365:
|
||||
anyOf:
|
||||
- $ref: "#/components/schemas/ComplianceResult"
|
||||
- type: "null"
|
||||
medicationCount:
|
||||
type: integer
|
||||
exclusiveMinimum: 0
|
||||
maximum: 9007199254740991
|
||||
description: How many applicable medications the figure is built from.
|
||||
required:
|
||||
- compliance7
|
||||
- compliance30
|
||||
- medicationCount
|
||||
additionalProperties: false
|
||||
description: "One adherence figure for the whole account in the `ComplianceResult` shape, weighted by expected doses:
|
||||
`taken`, `skipped` and `missed` are summed across every medication with `applicable: true`, and `rate` is
|
||||
recomputed from the sums by the per-medication rule (round(100 · taken / (taken + missed)), capped at 100, 100
|
||||
when nothing was expected). Averaging the per-medication rates would let a weekly injection weigh as much as a
|
||||
three-times-daily tablet. `streak` is the shortest per-medication streak. The `complianceN` block for a
|
||||
requested `days` is present when `days` was sent and is not 30."
|
||||
GetMedicationComplianceResponse:
|
||||
type: object
|
||||
properties:
|
||||
@@ -52445,19 +52584,7 @@ components:
|
||||
it was published only on PUT /api/auth/profile."
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
path:
|
||||
type: string
|
||||
code:
|
||||
type: string
|
||||
message:
|
||||
type: string
|
||||
required:
|
||||
- path
|
||||
- code
|
||||
- message
|
||||
additionalProperties: false
|
||||
$ref: "#/components/schemas/ValidationIssue"
|
||||
required:
|
||||
- username
|
||||
- email
|
||||
@@ -52503,8 +52630,10 @@ components:
|
||||
properties:
|
||||
clientManaged:
|
||||
type: boolean
|
||||
description: True when the iOS app owns local medication reminders; the server-side MEDICATION_REMINDER APNs cron is
|
||||
suppressed.
|
||||
description: True when the iOS app delivers medication reminders locally. The server then keeps the reminder that
|
||||
announces a dose off APNs (the phone shows its own at dose time) and still pushes the follow-ups for a
|
||||
dose that stays open, which the phone does not send (v1.42.0; before, every MEDICATION_REMINDER push was
|
||||
suppressed). Other channels are never affected.
|
||||
deliveryDefault:
|
||||
type: string
|
||||
enum:
|
||||
@@ -63358,7 +63487,20 @@ components:
|
||||
- days
|
||||
additionalProperties: false
|
||||
- type: "null"
|
||||
description: Null for a sparse logger below the day floor.
|
||||
description: Day-to-day steadiness over the trailing `stabilityWindowDays` days. Null below the day floor (seven days
|
||||
with an entry) inside that window, so a short window can be null where the year is not.
|
||||
stabilityWindowDays:
|
||||
anyOf:
|
||||
- type: number
|
||||
const: 30
|
||||
- type: number
|
||||
const: 90
|
||||
- type: number
|
||||
const: 180
|
||||
- type: number
|
||||
const: 365
|
||||
description: "The window `stability` covers: the `days` query parameter, or 365 (the whole daily series) when it was not
|
||||
sent. Added in v1.42.0; absent from older servers, whose score always covers the year."
|
||||
tags:
|
||||
type: array
|
||||
items:
|
||||
@@ -63814,6 +63956,7 @@ components:
|
||||
- weekday
|
||||
- timeOfDay
|
||||
- stability
|
||||
- stabilityWindowDays
|
||||
- tags
|
||||
- contextComparison
|
||||
- structuredTags
|
||||
@@ -76257,6 +76400,33 @@ components:
|
||||
type: string
|
||||
username:
|
||||
type: string
|
||||
timezone:
|
||||
type: string
|
||||
description: "The IANA zone the server cuts this account's days in: the stored zone, or the instance default when the
|
||||
stored one is unusable. Resolved, never the raw column, so bucket day keys by this value."
|
||||
glucoseUnit:
|
||||
anyOf:
|
||||
- type: string
|
||||
enum:
|
||||
- mg/dL
|
||||
- mmol/L
|
||||
- type: "null"
|
||||
description: The account's chosen glucose display unit, as stored. `null` means the person never chose one (or the
|
||||
stored value is neither unit), and the server then shows glucose in mg/dL.
|
||||
features:
|
||||
type: object
|
||||
properties:
|
||||
trackIntake:
|
||||
type: boolean
|
||||
const: true
|
||||
description: "Medications take `trackIntake`: a medication can be kept as a record whose doses are never due, and a dose
|
||||
written against one is refused with `medication.intake.notTracked`."
|
||||
required:
|
||||
- trackIntake
|
||||
additionalProperties: false
|
||||
description: What this server understands, for a client released apart from it. Constant across accounts; a flag appears
|
||||
once the server supports the feature and stays `true`. Absent on servers older than v1.42.0. A client that
|
||||
meets a flag it does not know ignores it.
|
||||
accountAccess:
|
||||
$ref: "#/components/schemas/AccountAccess"
|
||||
moduleAccess:
|
||||
@@ -76288,6 +76458,9 @@ components:
|
||||
required:
|
||||
- id
|
||||
- username
|
||||
- timezone
|
||||
- glucoseUnit
|
||||
- features
|
||||
- accountAccess
|
||||
- moduleAccess
|
||||
- ai
|
||||
|
||||
Reference in new issue
Block a user