mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 15:02:04 +00:00
chore(release): v1.6.0
Medication editor overhaul, route of administration, today-tile read-flip. - Route-of-administration column (ORAL | INJECTION | OTHER) decoupled from treatmentClass; injection-site picker surfaces for any injection. Migration 0088 backfills ORAL via a constant column default. - One-time injection (oneShot + deliveryForm = INJECTION) editor path. - Profile-photo upload card on Settings → Account. - Today-tile read-flip: /api/medications/intake?scope=today and /api/dashboard/summary gate through the canonical recurrence engine, matching the reminder worker for bi-weekly, rolling, RRULE, and one-time cadences. - Measurement note cap 25 → 200; dashboard range colors on semantic tokens; admin sidebar icons + shared-helper consolidation; API-tokens multi-language snippets restored. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
d01d1d1dc9
commit
8ee7aaac44
53 files changed
+1049
-1017
No files matched your search
@@ -252,12 +252,20 @@ export function validateMeasurementRange(
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* v1.6.0 — notes cap raised from 25 to 200. A 25-char limit could not
|
||||
* hold a meaningful clinical note ("took after large meal, felt dizzy
|
||||
* standing up"). The DB column is unbounded `String?`; this is the
|
||||
* single source of truth the client char-counters import.
|
||||
*/
|
||||
export const MEASUREMENT_NOTES_MAX_LENGTH = 200;
|
||||
|
||||
export const createMeasurementSchema = z
|
||||
.object({
|
||||
type: measurementTypeEnum,
|
||||
value: z.number(),
|
||||
measuredAt: z.iso.datetime({ offset: true }).transform((s) => new Date(s)),
|
||||
notes: z.string().max(25).optional(),
|
||||
notes: z.string().max(MEASUREMENT_NOTES_MAX_LENGTH).optional(),
|
||||
source: measurementSourceEnum.optional().default("MANUAL"),
|
||||
// Only applies when type === BLOOD_GLUCOSE. Mirrored by a CHECK
|
||||
// constraint in Postgres (see migration 0021).
|
||||
@@ -293,7 +301,10 @@ export const updateMeasurementSchema = z.object({
|
||||
.optional(),
|
||||
notes: z
|
||||
.string()
|
||||
.max(25, "Note cannot exceed 25 characters")
|
||||
.max(
|
||||
MEASUREMENT_NOTES_MAX_LENGTH,
|
||||
`Note cannot exceed ${MEASUREMENT_NOTES_MAX_LENGTH} characters`,
|
||||
)
|
||||
.nullable()
|
||||
.optional(),
|
||||
});
|
||||
|
||||
@@ -38,6 +38,20 @@ export const MEDICATION_TREATMENT_CLASS_VALUES = ["GENERIC", "GLP1"] as const;
|
||||
export type MedicationTreatmentClass =
|
||||
(typeof MEDICATION_TREATMENT_CLASS_VALUES)[number];
|
||||
|
||||
/**
|
||||
* v1.6.0 — route of administration. Decoupled from `treatmentClass`:
|
||||
* the injection-site picker surfaces for any `INJECTION` dose, and a
|
||||
* one-time injection is `oneShot: true` + `deliveryForm: "INJECTION"`.
|
||||
* ORAL is the default the migration backfilled onto every existing row.
|
||||
*/
|
||||
export const MEDICATION_DELIVERY_FORM_VALUES = [
|
||||
"ORAL",
|
||||
"INJECTION",
|
||||
"OTHER",
|
||||
] as const;
|
||||
export type MedicationDeliveryForm =
|
||||
(typeof MEDICATION_DELIVERY_FORM_VALUES)[number];
|
||||
|
||||
/**
|
||||
* v1.5 — RRULE string shape check.
|
||||
*
|
||||
@@ -225,6 +239,8 @@ export const createMedicationSchema = z
|
||||
treatmentClass: z.enum(MEDICATION_TREATMENT_CLASS_VALUES).optional(),
|
||||
/** v1.4.25 W4d — doses per pen/vial for inventory tracking. */
|
||||
dosesPerUnit: z.number().int().min(1).max(100).optional(),
|
||||
/** v1.6.0 — route of administration (ORAL | INJECTION | OTHER). */
|
||||
deliveryForm: z.enum(MEDICATION_DELIVERY_FORM_VALUES).optional(),
|
||||
notificationsEnabled: z.boolean().optional(),
|
||||
...courseWindowFields,
|
||||
schedules: z.array(scheduleSchema).min(1, "Mindestens ein Zeitfenster"),
|
||||
@@ -254,6 +270,8 @@ export const updateMedicationSchema = z
|
||||
category: z.enum(MEDICATION_CATEGORY_VALUES).optional(),
|
||||
treatmentClass: z.enum(MEDICATION_TREATMENT_CLASS_VALUES).optional(),
|
||||
dosesPerUnit: z.number().int().min(1).max(100).nullable().optional(),
|
||||
/** v1.6.0 — route of administration (ORAL | INJECTION | OTHER). */
|
||||
deliveryForm: z.enum(MEDICATION_DELIVERY_FORM_VALUES).optional(),
|
||||
active: z.boolean().optional(),
|
||||
notificationsEnabled: z.boolean().optional(),
|
||||
...courseWindowFields,
|
||||
|
||||
Reference in new issue
Block a user