Skip to content

fix(sharing): page the access log instead of stopping silently at twenty - #545

Open
MOHITKOURAV01 wants to merge 1 commit into
ishita2740:mainfrom
MOHITKOURAV01:fix/issue-540-web-access-log-paging
Open

fix(sharing): page the access log instead of stopping silently at twenty#545
MOHITKOURAV01 wants to merge 1 commit into
ishita2740:mainfrom
MOHITKOURAV01:fix/issue-540-web-access-log-paging

Conversation

@MOHITKOURAV01

Copy link
Copy Markdown
Contributor

Closes #540.

The Sharing screen's second card is the patient's own audit trail — "when a provider read your records". It showed the first 20 entries and stopped, with nothing on screen to say so.

const [nextConsents, log] = await Promise.all([
  fetchConsents(),
  fetchAccessLog().catch(() => null),
]);
setAccessLog(log?.entries ?? []);

One call, limit = 20 by default, and log.page — which carries hasMore and nextOffset — discarded. Then .map with no footer: no "load more", no count, no "showing 20 of N".

This was the odd one out on the page. The consent list directly above it follows the envelope to the end (fetchConsents walks nextOffset until hasMore is false), and ProviderDashboardPage renders an explicit "Load more". Only the audit log stopped silently.

Why the truncation is worse here than on an ordinary list

The list is newest-first, so what falls off the end is the oldest history — and the question a patient opens this screen to answer is "has anyone been looking at my records, and since when". An unmarked window reads as a complete history: "the earliest access shown is 3 August" and "the earliest of the twenty we felt like sending" are indistinguishable to her.

Twenty rows is not a lot. patient_summaries_page writes one row per patient per dashboard render, so a clinician refreshing her roster four times in a morning has already written four rows against every patient on it. A patient reaches the ceiling in days.

It also made the screen contradict itself. viewCount on each consent row comes from summary_for_patient, computed over every record, unpaged — so a row could read "viewed 34 times" while the list under it showed 20 and offered no way to reach the other 14.

What this does

  • Follows page.hasMore / page.nextOffset, with a "Load more" button, the way ProviderDashboardPage does. Entries are appended, and nextOffset comes off the server's envelope rather than being computed client-side — the server is the only party that knows whether a short page means the history ended.
  • Says how many are shown while more remain, so the visible list is never mistakable for the whole history.
  • Reports a failed "load more" without discarding what is already on screen. A patient who can see fourteen entries and cannot load the fifteenth should keep her fourteen.
  • The first fetch stays non-fatal, as it is today. A patient who cannot load her history must still be able to revoke, which is the more urgent of the two actions — the existing .catch(() => null) and the comment explaining it are unchanged.
  • PAGE_SIZE is a named constant matching access_log_service.DEFAULT_ACCESS_LOG_PAGE, next to the one ProviderDashboardPage already declares against DEFAULT_PATIENTS_PAGE.

New i18n keys — sharing.accessLogLoadMore, sharing.accessLogShowing, sharing.accessLogLoadMoreError — added to every locale file that has a sharing block, carrying the English string exactly as the surrounding sharing.* entries in those files already do.

bn.json and gu.json have no sharing block at all. That is a pre-existing gap tracked elsewhere (#297, #299) and not one worth half-filling from here — i18next falls back to en for the whole namespace either way, which is what those two files already do for every other string on this screen.

Tests

web/src/pages/SharingPage.test.tsx gains an access log paging group:

  • a first page reporting hasMore renders the "Load more" button; one that does not, does not
  • clicking it requests offset = nextOffset — the server's value, not entries.length
  • the second page is appended, not replaced, and the button disappears when the last page arrives
  • a failed "load more" shows an error and keeps the entries already loaded
  • the count line appears only while more remain
  • the consent list still loads when the access-log fetch fails outright, and revoke still works — the existing guarantee, asserted so the new code cannot quietly take it away

Existing SharingPage tests are unchanged. Eight of the nine new cases fail against main.

Full web suite: 593 tests across 35 files, npm run lint and npm run build clean.

The Sharing screen's second card is the patient's own audit trail — when a
provider read her records. It took `log.entries` and discarded `log.page`:

    fetchAccessLog().catch(() => null)
    ...
    setAccessLog(log?.entries ?? []);

One call, `limit = 20` by default, `hasMore` and `nextOffset` thrown away,
and then `.map` with no footer. No "load more", no count, no "showing 20
of N".

Truncating this list is worse than truncating an ordinary one, and in the
wrong direction. It is newest-first, so what falls off the end is the
*oldest* history — and the question she opens this screen to answer is
"has anyone been looking at my records, and since when". An unmarked
window reads as a complete history: "the earliest access shown is 3
August" and "the earliest of the twenty we felt like sending" are
indistinguishable to her.

Twenty rows is not a lot. `patient_summaries_page` writes one row per
patient per dashboard render, so a clinician who refreshes her roster four
times in a morning has already written four rows against everyone on it.

It also made the screen contradict itself. `viewCount` on each consent row
comes from `summary_for_patient`, computed over every record and unpaged,
so a row could read "viewed 34 times" above a list of 20 with no way to
reach the other 14.

This was the odd one out on the page: the consent list above it already
walks `nextOffset` to the end, and the provider dashboard already renders
a "Load more". Only the audit log stopped without saying so.

- Follows `page.hasMore` / `page.nextOffset` behind a "Show earlier views"
  button, appending. `nextOffset` comes off the server's envelope rather
  than being computed from `accessLog.length` — the server is the only
  party that knows whether a short page means the history ended.
- Says how many are shown while more remain.
- A failed "load more" reports itself and keeps what is already on screen.
  A patient who can see twenty rows and cannot fetch the twenty-first
  should keep her twenty.
- The first fetch stays non-fatal, unchanged: a patient who cannot load
  her history must still be able to revoke.

Three new `sharing.*` keys, added to every locale file that has a
`sharing` block, carrying English as those files already do for this
namespace. `bn.json` and `gu.json` have no `sharing` block at all — a
pre-existing gap tracked separately, and not one to half-fill here.
@vercel

vercel Bot commented Aug 27, 2026

Copy link
Copy Markdown

@MOHITKOURAV01 is attempting to deploy a commit to the ishita2740's projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Web] The Sharing screen shows the first 20 access-log entries and stops — no paging, no count, and the consent row above it says "viewed 34 times"

1 participant