mirror of
https://github.com/temetro/temetro.git
synced 2026-08-21 07:26:45 +00:00
feat: activity audit log written from all resource routes
Add the activity_log table, a best-effort recordActivity() service and a GET /api/activity feed, and write entries on create/update/delete of patients, notes, appointments, prescriptions and tasks. The Activity page now shows the real audit trail (actor, action, patient context, time); the fabricated signing hashes / approval badges are gone — that vision stays deferred. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import { index, pgTable, text, timestamp, uuid } from "drizzle-orm/pg-core";
|
||||
|
||||
import type { ActivityEntityType } from "../../types/activity.js";
|
||||
import { organization, user } from "./auth.js";
|
||||
|
||||
// One row per record change, scoped to a clinic (organization). Written
|
||||
// best-effort from the resource routes (patients / notes / appointments /
|
||||
// prescriptions / tasks). `actorName` is denormalized so the feed renders even
|
||||
// after the user is removed (FK is set null).
|
||||
export const activityLog = pgTable(
|
||||
"activity_log",
|
||||
{
|
||||
id: uuid("id").primaryKey().defaultRandom(),
|
||||
organizationId: text("organization_id")
|
||||
.notNull()
|
||||
.references(() => organization.id, { onDelete: "cascade" }),
|
||||
actorId: text("actor_id").references(() => user.id, {
|
||||
onDelete: "set null",
|
||||
}),
|
||||
actorName: text("actor_name").notNull(),
|
||||
action: text("action").notNull(),
|
||||
entityType: text("entity_type").$type<ActivityEntityType>().notNull(),
|
||||
entityId: text("entity_id"),
|
||||
patientName: text("patient_name"),
|
||||
patientFileNumber: text("patient_file_number"),
|
||||
createdAt: timestamp("created_at").defaultNow().notNull(),
|
||||
},
|
||||
(t) => [index("activity_org_created_idx").on(t.organizationId, t.createdAt)],
|
||||
);
|
||||
@@ -4,3 +4,4 @@ export * from "./notes.js";
|
||||
export * from "./appointments.js";
|
||||
export * from "./prescriptions.js";
|
||||
export * from "./tasks.js";
|
||||
export * from "./activity.js";
|
||||
|
||||
Reference in New Issue
Block a user