Anonymous by default
Public data uses stable aliases instead of raw names, and private transaction text is withheld from unrecognized viewers.
Personal finance utility Personalized access
A privacy-conscious dashboard for tracking personal loans among friends and family, with anonymous aggregate comparisons, individualized balance views, payment history, and staff-only tools for issuing personalized access links.
Informal loans are easy to lose track of, but publishing a shared spreadsheet would expose names, descriptions, balances, and payment information. Each person needs a clear view of their own history without receiving everyone else's private details.
The dashboard publishes anonymous aggregate information by default and recognizes a person only after their browser receives a valid invitation fragment. That recognized viewer sees their own rows as “You,” while free-text details and payment information remain restricted to the appropriate viewer or staff tools.
Public data uses stable aliases instead of raw names, and private transaction text is withheld from unrecognized viewers.
A one-time fragment enrolls one browser without placing the identity token in the initial page request or ordinary referrer headers.
A recognized viewer can see their own balance and history while aggregate reporting remains anonymized.
Full-detail data and invitation management live behind independently checked staff-only routes and APIs.
The choices that shaped how the project works.
Authentication adds only the viewer's own context instead of turning the public endpoint into a full-detail feed.
Invitation identity lives in a URL fragment, which the browser handles after the generic page shell loads.
Staff access does not change the public API's privacy behavior, and sensitive responses remain uncacheable.
React · Vite · Django · Google Sheets · HMAC-derived invitations
The anonymous dashboard is public. Portfolio screenshots show the real interface with fictional data; individual balances and payment details appear only after a recipient opens their personalized invitation link.
Open the working app, or continue browsing the rest of the portfolio.