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_CODE from 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.

Email

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). Rotating SESSION_SECRET signs 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_SECRET or a missing INVITE_CODE.
  • Data-protection contact: DATA_CONTACT_EMAIL appears in the footer and privacy policy — make sure it's a mailbox someone reads.