41367a8b27273bc1fa0b3c5ddacf6720941d3a68
Prabhupāda Says — Admin
A separate Next.js 16 + Tailwind v4 admin panel that talks to the existing Go
BFF. It reuses the BFF's cookie session (no separate auth system) and every
action is gated server-side by the new /api/v1/admin/* endpoints, which
require role = "admin".
Features
- Email/password login (with the BFF's OTP step when required) + forgot/reset password
- Users — search, paginate, send a notification to an individual user
- Posts — search, paginate
- Collections — search, paginate
- Feedback — paginate, filter (all/open/resolved), reply (emails the submitter)
- Reports — posts / comments / accounts tabs, search, paginate, resolve
Prerequisites
The BFF must be running with migration 0038_admin_panel applied (it runs
automatically on BFF startup) and these env vars set on the BFF:
ADMIN_URL=http://localhost:3001 # this app's origin — added to CORS
# (production: ADMIN_URL=https://admin.prabhupadasays.org)
Without ADMIN_URL, the browser's credentialed requests from this origin are
blocked by CORS.
Setup
cd spsays-admin
cp .env.example .env.local # set NEXT_PUBLIC_BFF_URL
yarn install
yarn dev # http://localhost:3001
Make yourself an admin
The panel only admits users whose role is admin. Promote your account once,
directly in Postgres:
UPDATE users SET role = 'admin' WHERE email = 'you@example.com';
Then sign in at /login with that account's email + password.
Production notes
- Deploy on its own subdomain, e.g.
admin.prabhupadasays.org, and setADMIN_URLon the BFF to that origin. The session cookie is shared because the BFF sets it on.prabhupadasays.org. - The app sets
robots: noindexand should additionally be access-restricted at the edge if desired — the BFF'sRequireAdminis the real security boundary, but defense in depth doesn't hurt.
How it maps to the BFF
| Screen | Endpoint |
|---|---|
| Login | POST /auth/login (+ verify-login-otp) |
| Forgot/Reset | POST /auth/forgot-password / reset-password |
| Users | GET /admin/users, POST /admin/users/{id}/notify |
| Posts | GET /admin/posts |
| Collections | GET /admin/collections |
| Feedback | GET /admin/feedback, POST /admin/feedback/{id}/reply |
| Reports | GET /admin/reports?type=, POST /admin/reports/{type}/{id}/resolve |
Languages
TypeScript
99.1%
CSS
0.7%
JavaScript
0.2%