feat: add pill weight and taken by fields to medications schema and update related components

This commit is contained in:
Daniel Volz
2025-12-21 12:21:00 +01:00
parent a7fc360457
commit eb3bfea940
7 changed files with 114 additions and 32 deletions
@@ -0,0 +1,2 @@
-- Add pill weight column (in mg)
ALTER TABLE medications ADD COLUMN pill_weight_mg INTEGER;
@@ -0,0 +1,2 @@
-- Add taken_by column for family member tracking
ALTER TABLE medications ADD COLUMN taken_by TEXT;
+3 -1
View File
@@ -7,6 +7,8 @@
{ "idx": 4, "version": 1, "when": 1735000000, "tag": "0004_add_expiry_date", "breakpoint": false },
{ "idx": 5, "version": 1, "when": 1735100000, "tag": "0005_add_notes", "breakpoint": false },
{ "idx": 6, "version": 1, "when": 1735200000, "tag": "0006_add_generic_name", "breakpoint": false },
{ "idx": 7, "version": 1, "when": 1735300000, "tag": "0007_add_intake_reminders", "breakpoint": false }
{ "idx": 7, "version": 1, "when": 1735300000, "tag": "0007_add_intake_reminders", "breakpoint": false },
{ "idx": 8, "version": 1, "when": 1735400000, "tag": "0008_add_pill_weight", "breakpoint": false },
{ "idx": 9, "version": 1, "when": 1735500000, "tag": "0009_add_taken_by", "breakpoint": false }
]
}
+2
View File
@@ -14,12 +14,14 @@ export const medications = sqliteTable("medications", {
id: integer("id").primaryKey({ autoIncrement: true }),
name: text("name", { length: 100 }).notNull().unique(),
genericName: text("generic_name", { length: 100 }),
takenBy: text("taken_by", { length: 100 }),
count: integer("count").notNull().default(0),
strips: integer("strips").notNull().default(0),
packCount: integer("pack_count").notNull().default(1),
stripsPerPack: integer("strips_per_pack").notNull().default(1),
tabsPerStrip: integer("tabs_per_strip").notNull().default(1),
looseTablets: integer("loose_tablets").notNull().default(0),
pillWeightMg: integer("pill_weight_mg"),
usageJson: text("usage_json").notNull().default("[]"),
everyJson: text("every_json").notNull().default("[]"),
startJson: text("start_json").notNull().default("[]"),
+14 -2
View File
@@ -18,10 +18,12 @@ const sliceSchema = z.object({
const medicationSchema = z.object({
name: z.string().trim().min(1).max(100),
genericName: z.string().trim().max(100).nullable().optional(),
takenBy: z.string().trim().max(100).nullable().optional(),
packCount: z.number().int().min(0).default(1),
stripsPerPack: z.number().int().min(1).default(1),
tabsPerStrip: z.number().int().min(1).default(1),
looseTablets: z.number().int().min(0).default(0),
pillWeightMg: z.number().int().min(1).nullable().optional(),
expiryDate: z.string().nullable().optional(),
notes: z.string().max(500).nullable().optional(),
intakeRemindersEnabled: z.boolean().default(false),
@@ -56,6 +58,7 @@ export async function medicationRoutes(app: FastifyInstance) {
id: row.id,
name: row.name,
genericName: row.genericName,
takenBy: row.takenBy,
count: row.count,
strips: row.strips,
stripSize: row.stripSize,
@@ -63,6 +66,7 @@ export async function medicationRoutes(app: FastifyInstance) {
stripsPerPack: row.stripsPerPack ?? row.strips ?? 1,
tabsPerStrip: row.tabsPerStrip ?? row.stripSize ?? 1,
looseTablets: row.looseTablets ?? 0,
pillWeightMg: row.pillWeightMg,
slices: parseSlices(row),
imageUrl: row.imageUrl,
expiryDate: row.expiryDate,
@@ -76,7 +80,7 @@ export async function medicationRoutes(app: FastifyInstance) {
const parsed = medicationSchema.safeParse(req.body);
if (!parsed.success) return reply.status(400).send(parsed.error.format());
const { name, genericName, packCount, stripsPerPack, tabsPerStrip, looseTablets, expiryDate, notes, intakeRemindersEnabled, slices } = parsed.data;
const { name, genericName, takenBy, packCount, stripsPerPack, tabsPerStrip, looseTablets, pillWeightMg, expiryDate, notes, intakeRemindersEnabled, slices } = parsed.data;
const usageJson = JSON.stringify(slices.map((s) => s.usage));
const everyJson = JSON.stringify(slices.map((s) => s.every));
const startJson = JSON.stringify(slices.map((s) => s.start));
@@ -88,6 +92,7 @@ export async function medicationRoutes(app: FastifyInstance) {
.values({
name,
genericName: genericName || null,
takenBy: takenBy || null,
count: derivedCount,
strips: stripsPerPack,
stripSize: tabsPerStrip,
@@ -95,6 +100,7 @@ export async function medicationRoutes(app: FastifyInstance) {
stripsPerPack,
tabsPerStrip,
looseTablets,
pillWeightMg: pillWeightMg || null,
expiryDate: expiryDate || null,
notes: notes || null,
intakeRemindersEnabled: intakeRemindersEnabled ?? false,
@@ -108,6 +114,7 @@ export async function medicationRoutes(app: FastifyInstance) {
id: inserted.id,
name: inserted.name,
genericName: inserted.genericName,
takenBy: inserted.takenBy,
count: inserted.count,
strips: inserted.strips,
stripSize: inserted.stripSize,
@@ -115,6 +122,7 @@ export async function medicationRoutes(app: FastifyInstance) {
stripsPerPack: inserted.stripsPerPack,
tabsPerStrip: inserted.tabsPerStrip,
looseTablets: inserted.looseTablets,
pillWeightMg: inserted.pillWeightMg,
slices,
imageUrl: inserted.imageUrl,
expiryDate: inserted.expiryDate,
@@ -130,7 +138,7 @@ export async function medicationRoutes(app: FastifyInstance) {
const idNum = Number(req.params.id);
if (Number.isNaN(idNum)) return reply.badRequest("Invalid id");
const { name, genericName, packCount, stripsPerPack, tabsPerStrip, looseTablets, expiryDate, notes, intakeRemindersEnabled, slices } = parsed.data;
const { name, genericName, takenBy, packCount, stripsPerPack, tabsPerStrip, looseTablets, pillWeightMg, expiryDate, notes, intakeRemindersEnabled, slices } = parsed.data;
const usageJson = JSON.stringify(slices.map((s) => s.usage));
const everyJson = JSON.stringify(slices.map((s) => s.every));
const startJson = JSON.stringify(slices.map((s) => s.start));
@@ -142,6 +150,7 @@ export async function medicationRoutes(app: FastifyInstance) {
.set({
name,
genericName: genericName || null,
takenBy: takenBy || null,
count: derivedCount,
strips: stripsPerPack,
stripSize: tabsPerStrip,
@@ -149,6 +158,7 @@ export async function medicationRoutes(app: FastifyInstance) {
stripsPerPack,
tabsPerStrip,
looseTablets,
pillWeightMg: pillWeightMg || null,
expiryDate: expiryDate || null,
notes: notes || null,
intakeRemindersEnabled: intakeRemindersEnabled ?? false,
@@ -166,6 +176,7 @@ export async function medicationRoutes(app: FastifyInstance) {
id: result[0].id,
name: result[0].name,
genericName: result[0].genericName,
takenBy: result[0].takenBy,
count: result[0].count,
strips: result[0].strips,
stripSize: result[0].stripSize,
@@ -173,6 +184,7 @@ export async function medicationRoutes(app: FastifyInstance) {
stripsPerPack: result[0].stripsPerPack,
tabsPerStrip: result[0].tabsPerStrip,
looseTablets: result[0].looseTablets,
pillWeightMg: result[0].pillWeightMg,
slices,
imageUrl: result[0].imageUrl,
expiryDate: result[0].expiryDate,