chore(release): v1.32.25 — surface mirrored-medication provenance and cap external mirror growth

This commit is contained in:
Marc-André Bombeck committed 2026-07-24 23:18:26 +02:00
1 parent 40aae4b66d
commit bb79d28911
4 files changed
+42 -9

No files matched your search

+17
View File
@@ -2,6 +2,23 @@
## [Unreleased]
## [1.32.25] — 2026-07-24
Mirrored medications are now marked as such, and the server limits how many
medications one external source can mirror so a client bug can no longer fill
the list with duplicates.
- **Mirrored medications are marked on the list.** The medications list now
reports whether each entry was mirrored from an external source (today Apple
Health) or created in HealthLog directly. A synced row is no longer
indistinguishable from one you added yourself.
- **One external source can no longer flood the list.** The server refuses to
mirror more than 30 medications from a single external source per account. A
client that keeps re-sending the same medication under a changing identifier
can no longer create a fresh row on every sync. A repeat of a medication
already mirrored still resolves to the existing row, and medications you add
yourself are never affected.
## [1.32.24] — 2026-07-24
Polar sync is more resilient when one data type is unavailable. A single
+23 -7
View File
@@ -1,7 +1,7 @@
openapi: 3.1.0
info:
title: HealthLog API
version: 1.32.24
version: 1.32.25
description: >-
Self-hosted personal-health-tracking PWA — public API surface for the iOS native client and external ingest.
@@ -3526,7 +3526,12 @@ paths:
summary: Create a medication with at least one schedule
description: Validates the body against `CreateMedicationRequest`, applies the v1.5 cross-field invariants (one-shot
consistency, recurring default `FREQ=DAILY`, `timesOfDay` dual-write), and creates the medication + its
schedules in a single Prisma write. Audits as `medication.create`.
schedules in a single Prisma write. Audits as `medication.create`. v1.28 — a mirror create (`externalSource` +
`externalId`) re-posting a pair the caller already holds returns the existing medication with 200 instead of a
duplicate. v1.32.25 — a NEW mirror create is refused with 422 (`meta.errorCode =
medications.mirror.limit_exceeded`) once the caller already holds 30 medications mirrored from the same external
source; an idempotent re-post of a medication already mirrored is unaffected, and native creates are never
gated.
requestBody:
required: true
content:
@@ -19794,6 +19799,15 @@ components:
$ref: "#/components/schemas/MedicationScheduleOutput"
category:
$ref: "#/components/schemas/MedicationCategory"
externalSource:
anyOf:
- type: string
const: APPLE_HEALTH
- type: "null"
description: v1.32.25 — provenance of the medication. `APPLE_HEALTH` marks the row a read-only mirror of the iOS 26+
HealthKit Medications sync; NULL is a native HealthLog medication. Read-only echo of the stored provenance —
the create route sets it, the list read surfaces it so mirrored-vs-native is visible without inspecting the
iOS client's local registry.
lastTakenAt:
anyOf:
- type: string
@@ -19851,16 +19865,18 @@ components:
- updatedAt
- schedules
- category
- externalSource
- lastTakenAt
- todayEventCount
- stockUnitsRemaining
- stockDosesRemaining
additionalProperties: false
description: List-row variant of the medication resource enriched with the joined `category`, `lastTakenAt`,
`todayEventCount`, and the v1.16.10 aggregated stock fields (`stockUnitsRemaining`, `stockDosesRemaining`) the
dashboard + iOS client consume. The base medication fields (`id`, `name`, `dose`, `treatmentClass`,
`dosesPerUnit`, `active`, `notificationsEnabled`, `pausedAt`, `snoozedUntil`, `startsOn`, `endsOn`, `oneShot`,
`createdAt`, `updatedAt`, `schedules`) are inlined; see the `Medication` component for their semantics.
description: List-row variant of the medication resource enriched with the joined `category`, the v1.32.25
`externalSource` provenance echo, `lastTakenAt`, `todayEventCount`, and the v1.16.10 aggregated stock fields
(`stockUnitsRemaining`, `stockDosesRemaining`) the dashboard + iOS client consume. The base medication fields
(`id`, `name`, `dose`, `treatmentClass`, `dosesPerUnit`, `active`, `notificationsEnabled`, `pausedAt`,
`snoozedUntil`, `startsOn`, `endsOn`, `oneShot`, `createdAt`, `updatedAt`, `schedules`) are inlined; see the
`Medication` component for their semantics.
MedicationCategory:
type: string
enum:
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "healthlog",
"version": "1.32.24",
"version": "1.32.25",
"description": "Self-hosted personal-health-tracking PWA with Withings integration, AI insights, and doctor-report PDF export.",
"license": "PolyForm-Noncommercial-1.0.0",
"homepage": "https://healthlog.dev",
+1 -1
View File
@@ -36,7 +36,7 @@ try {
// v1.4.38.4 → v1.4.42. Do not hand-edit; bump `package.json` and rebuild.
const CACHE_VERSION =
(typeof self !== "undefined" && self.__APP_VERSION__) ||
/* @sw-version-fallback */ "v1.32.24";
/* @sw-version-fallback */ "v1.32.25";
const STATIC_CACHE = `healthlog-static-${CACHE_VERSION}`;
const PAGE_CACHE = `healthlog-pages-${CACHE_VERSION}`;
// v1.18.6 — read-only data cache for a curated allowlist of safe GET `/api/*`