feat: delete controls across add-pages (lab, dispense, rx, inventory, tasks)

Backend:
- DELETE /api/patients/:fileNumber/labs (remove one lab result, lab:write)
- DELETE /api/dispenses/:id (void a ledger entry, inventory:write)

Frontend (all guarded by ConfirmDialog):
- lab "Recent results" rows: delete result
- pharmacy "Recently dispensed" rows: delete record
- prescriptions/tasks detail sheets + inventory detail dialog gain a delete
  action (prescription delete stays off the shared Pharmacy sheet)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Khalid Abdi
2026-06-17 19:23:41 +03:00
parent 96bda1b902
commit d37a4e9425
15 changed files with 467 additions and 10 deletions
+12 -1
View File
@@ -1,4 +1,4 @@
import { desc, eq } from "drizzle-orm";
import { and, desc, eq } from "drizzle-orm";
import { db } from "../db/index.js";
import { dispenses } from "../db/schema/dispenses.js";
@@ -59,3 +59,14 @@ export async function createDispense(
.returning();
return toDispense(row!);
}
export async function deleteDispense(
orgId: string,
id: string,
): Promise<boolean> {
const deleted = await db
.delete(dispenses)
.where(and(eq(dispenses.organizationId, orgId), eq(dispenses.id, id)))
.returning({ id: dispenses.id });
return deleted.length > 0;
}
+35
View File
@@ -566,6 +566,41 @@ export async function appendLabs(
return getPatient(orgId, fileNumber);
}
// Remove a single lab result from a patient, identified by its
// name/value/takenAt (the frontend has no row id). Scoped to the org via the
// owning patient. Returns the reloaded patient, or null when the chart is gone.
export async function deleteLab(
orgId: string,
fileNumber: string,
match: { name: string; value: string; takenAt: string },
): Promise<Patient | null> {
const [existing] = await db
.select({ id: patients.id })
.from(patients)
.where(
and(
eq(patients.organizationId, orgId),
eq(patients.fileNumber, fileNumber),
),
);
if (!existing) return null;
await db
.delete(labs)
.where(
and(
eq(labs.patientId, existing.id),
eq(labs.name, match.name),
eq(labs.value, match.value),
eq(labs.takenAt, match.takenAt),
),
);
await db
.update(patients)
.set({ updatedAt: new Date() })
.where(eq(patients.id, existing.id));
return getPatient(orgId, fileNumber);
}
export async function deletePatient(
orgId: string,
fileNumber: string,