I’ve been exploring the O3 Audit Trail frontend project for GSoC, and while working through the current audit logging setup, I reached one part of the project that seems especially important to define properly before implementation: what a patient chart “Change History” view should actually mean in OpenMRS.
From what I’ve seen so far, the current audit logging work gives us a strong base for an admin-facing audit log viewer, but the patient chart side of the problem feels less straightforward.
A lot of meaningful patient-related changes in OpenMRS don’t happen only on the Patient record itself. They often happen through related domain objects such as:
Observations
Encounters
Visits
Orders
and other patient-associated records
So if an O3 patient chart tab called something like “Change History” is added, it seems like the real design question is not just:
“Can we filter audit logs by patient?”
but more fundamentally:
What should count as patient-scoped audit history in a first useful version of this feature?
That feels important because there are different possible interpretations:
a narrow version that only shows directly patient-owned changes
a broader and more useful version that includes common clinically relevant related entities
or a much more complete patient-linked audit timeline, which may go beyond what should reasonably be expected from the frontend scope alone
At the moment, I’m trying to shape the scope in a way that is:
genuinely useful in the patient chart
realistic within the current audit surface
and honest about where frontend scope should stop
My current instinct is that the project should probably prioritize:
an admin-facing O3 audit dashboard as the primary complete audit exploration surface
and a patient-context change history tab as a more intentionally scoped view of patient-relevant changes
But I’d really like to hear from maintainers and anyone familiar with:
the audit logs module
patient chart workflows
or how audit history would actually be expected to work in practice
In particular, I’d love discussion around:
what kinds of audit events would actually be useful to surface inside the patient chart (in order to define the use case of the Patient History tab)
whether separate entity-specific history would be more usable than a full patient-scoped history
and where people feel the right boundary is between patient-context history and full audit exploration
I’m trying to make sure the project reflects a scope that is both implementable and actually worth the impact.
Hey, if you are interested in the O3 Frontend Project for the Audit Trail, you can definitely use this talk post to brainstorm and validate your ideas.
For beginner frontend issues, I’d recommend checking the OpenMRS 3.x space to find topics that are still IN PROGRESS or TO DO and find relevant issues within that feel ambient to you.
Please join our semi-weekly newbie calls on https://om.rs/community for any doubts you have.
To be a part of the frontend related discussions, you can also join https://om.rs/o3coffee.
Find schedules here.
One question on the data-flow side: the openmrs-module-auditlog REST returns flat audit entries per object, but the patient-chart needs them grouped by encounter + diffed field-by-field for the change-history view. A few approaches:
Client-side grouping in an useAuditTrail(patientUuid) SWR hook, with the diff computed in a useMemo over the previousValue/newValue fields.
Backend-side: extend the auditlog REST with an encounter query param + a ?grouped=true response shape.
A thin BFF layer in an esm app (e.g. openmrs-esm-patient-chart/packages/esm-patient-audit-app) that joins auditlog + encounter data.
Option 1 keeps the scope “native O3 frontend” and avoids module changes, but pagination gets awkward for long histories. Do you see this project staying strictly frontend, or is extending the auditlog REST in-scope?
Happy to sketch a skeleton widget in a draft PR this week to make the data shape concrete.
Hey @praneeth622, thanks for the thoughtful breakdown.
I’d gently pump the brakes on the draft PR idea for now though, for a couple of reasons worth keeping in mind.
First, as you can see from this thread, the scope of the patient chart “Change History” piece is still genuinely open. We haven’t landed on answers to the core questions yet, what counts as patient-scoped audit history, where the frontend boundary sits, and what backend surface is actually available. Building a skeleton widget before those are resolved risks pulling the design discussion toward a particular implementation before the community has weighed in.
Second, and this is worth being upfront about: this is a GSoC project idea, which means it may or may not be selected by Google, and even if it is, there’s no guarantee about who gets assigned to it. Investing heavily in draft PRs before results are announced can lead to a lot of effort that doesn’t translate into anything concrete.
The best use of your energy right now is probably: engaging in the scope discussion here (but we can’t do that without the mentor yet), understanding the existing audit module, maybe picking up a small unrelated O3 issue, and contributing to issues around the community’s priority for now.
Fair point @omsrivastava512, makes sense to not bias the design direction before the community lands on scope. Will hold off on the skeleton.
@olewandowski if you get a minute, even a rough lean between frontend-only grouping vs extending the auditlog REST would help me focus my reading. Until then I’ll spend time going through the existing auditlog module internals and previous discussions on this instead
My personal lean is that this should probably be handled on the BE rather than in the FE. As far as I know, there’s also a separate GSoC project around extending/improving the audit log BE, so there may be some overlap here.
Both approaches seem feasible, but my concern with a FE-only solution is that audit history volume will grow over time, which could create performance issues.
@manojll , could you share more details on the audit log BE work here?
Thanks @olewandowski that framing makes sense, and the volume concern is real. Client-side grouping over a growing audit history would get painful, especially for long-stay patients.
Reframing the FE work as a consumer of a BE-driven response shape (rather than doing the join in the browser) actually tightens the scope in a good way the FE becomes a rendering + filtering + UX layer with proper server-driven pagination, and the data contract lives on the BE side.
@manojll while you’re thinking about the BE scope: happy to sketch a consumer against a mocked /audit/patient/{uuid}?grouped=true response shape, so whatever the BE contract ends up being has a FE stub ready to adapt. Would also be useful to know roughly what timeline the BE project is targeting for the contract to stabilise that affects whether the FE side can build against it in-parallel or needs to wait.