User guide · 9 of 9
Administrator guide
For whoever operates the Perfi server. Deployment itself is covered by the Deployment section of the project README; this page covers day-to-day administration.
Becoming an admin
There is no admin signup. Register normally, then promote the account on the server:
node scripts/promote-admin.mjs <email>
Admin rights are checked against the database on every request, so promoting or demoting takes effect immediately — no re-login needed. Admins get an Admin area (separate layout, "Exit admin" returns to the normal app).
Inviting users
Two kinds of invite code work at registration:
- Minted codes — created in the Invite codes section of
/admin: set an optional label ("for James") and a use count (1–100), and Perfi generates a unique code plus a shareable link (/register?code=…) that arrives with the code prefilled. Each registration consumes one use; exhausted codes stop working automatically, and you can revoke an unused or partly-used code at any time. The table shows every code's uses, status, and creation date, and each user's record remembers which code admitted them. - The shared
INVITE_CODEfrom the server's.env— a master fallback that always works alongside minted codes. To rotate it, change the env value and restart the app; existing users are unaffected.
Prefer minted codes for anyone outside your inner circle: they're individually revocable and you can see exactly who came in on what.
The user directory (/admin)
Sortable table of every registered user: email (admins badged), joined date, last login, number of statement uploads, 90-day spend, and top category. Click an email for the drill-down.
Per-user drill-down (/admin/{user})
- Header: email, joined/last-login, account count.
- Reset password — set a new password (min 8 chars) for a locked-out user. This immediately signs the user out of all their devices and emails them a notice that an administrator reset their password. Tell them the new password through a channel you trust, and ask them to change it in Settings.
- Read-only copies of the user's spending dashboard, investments view (if they have trades), and their statement upload history. The admin view cannot refresh prices or modify user data.
With RESEND_API_KEY set, Perfi sends verification, password-reset, and
admin-reset-notice emails via Resend from EMAIL_FROM. Links in emails
use APP_URL — it must be the public HTTPS URL. Without a key (dev),
emails are printed to the server console instead.
Operational notes
- Rate limiting is in-process; restarting the app resets counters.
- Sessions: revocation works by bumping a user's
tokenVersion(automatic on any password change/reset). RotatingSESSION_SECRETsigns out everyone at once. - Uploads directory self-cleans: PDFs are deleted after import and swept 24 h after upload otherwise. It needs no backup — the database is the system of record; back that up nightly.
- Production boot checks: the app refuses to start in production with
a weak/placeholder
SESSION_SECRETor a missingINVITE_CODE. - Data-protection contact:
DATA_CONTACT_EMAILappears in the footer and privacy policy — make sure it's a mailbox someone reads.