Official website, member portal, and admin tools for Pascack Hills High School Hack Club.
This repo powers:
- The public club site
- A member portal for projects and devlogs
- A gallery for approved work
- Admin tools for meetings, attendance, announcements, verification, and email
- A PM2-managed reminder worker that emails admins when a meeting summary still needs to be filled out
| Layer | Technology |
|---|---|
| Framework | Next.js App Router |
| UI | React + TypeScript |
| Database | PostgreSQL |
| ORM | Prisma |
| File storage | MinIO |
| Auth | Hack Club OAuth + JWT session cookies |
| Nodemailer | |
| Markdown | react-markdown, remark-gfm, rehype-raw |
| Process manager | PM2 |
- Home, about, events, meetings, gallery, members, donate, contact, mailing list, and leaderboard pages
- Public meeting schedule with past-meeting summaries and materials
- Public gallery for approved projects
- Member profile pages and directory
- Hack Club sign-in
- Project drafts and submissions
- Devlog drafts and submissions
- Markdown editing and preview
- Image uploads through MinIO
- Optional Hackatime project linking
- Verification approval
- Submission review
- Member management
- Meeting scheduling
- Meeting summaries and materials
- Attendance tracking and reporting
- Announcement publishing and email sending
- General admin email tools
- Site modal management
phhs-site-meeting-summary-workerruns under PM2- Polls the internal reminder endpoint once per minute
- Sends summary reminder emails after 5:00 PM America/New_York on meeting days
- Uses
summaryReminderSentAtto avoid duplicate sends
src/
app/
admin/ admin pages
api/ route handlers
portal/ member portal pages
... public routes
components/ shared UI and client components
lib/ auth, Prisma, email, storage, and utilities
prisma/
schema.prisma
migrations/
public/
scripts/
meeting-summary-reminder-worker.mjs
docs/
plans/
- Node.js 22+
- Docker and Docker Compose
- PostgreSQL and MinIO containers from
docker compose
npm installdocker compose up -dDefault local ports:
- App:
3007 - Postgres:
5434 - MinIO API:
9002 - MinIO Console:
9003
cp .env.example .envFill in the OAuth, SMTP, admin, and JWT values before using the full app.
npx prisma migrate deploy
npx prisma generateIf you are creating a new local migration during development:
npx prisma migrate dev --name your_change_namenpm run devOpen http://localhost:3007.
See .env.example for the full template.
DATABASE_URL=postgresql://phhs:password@localhost:5434/phhs_hack_clubMINIO_ENDPOINT=localhost
MINIO_PORT=9002
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
MINIO_BUCKET=phhs-uploads
MINIO_USE_SSL=false
MINIO_PUBLIC_URL=http://localhost:9002/phhs-uploadsHACKCLUB_CLIENT_ID=
HACKCLUB_CLIENT_SECRET=
HACKCLUB_REDIRECT_URI=http://localhost:3007/api/auth/callbackHACKATIME_CLIENT_ID=
HACKATIME_CLIENT_SECRET=
HACKATIME_REDIRECT_URI=http://localhost:3007/api/auth/hackatime/callbackSMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=
CONTACT_EMAIL_TO=
ADMIN_EMAIL=JWT_SECRET=change-me
NEXT_PUBLIC_URL=https://your-site.com
OPENROUTER_API_KEY=
CRON_SECRET=CRON_SECRET protects the internal meeting-summary reminder endpoint and is required for the PM2 worker.
npm run dev
npm run build
npm run start
npm run lint
npm run prisma:generateUseful Prisma commands:
npx prisma migrate dev --name your_change_name
npx prisma migrate deploy
npx prisma generate
npx prisma studioProduction uses PM2 with ecosystem.config.js.
Build and restart the web app:
npm run buildStart both the site and the worker:
pm2 start ecosystem.config.jsReload both with updated env:
pm2 startOrReload ecosystem.config.js --update-envSave the current PM2 process list:
pm2 saveInspect worker logs:
pm2 logs phhs-site-meeting-summary-workerMain Prisma models:
MemberProjectDevlogImageVerificationRequestSiteModalAttendanceRecordMeetingEventMailingListEntryAnnouncement
Relevant enums:
RoleSubmissionStatusVerificationStatus
There is no automated test suite yet. Before shipping changes, run:
npm run lint
npm run buildManual verification matters most for:
- Auth flows
- Project and devlog submission
- Image uploads
- Admin approval flows
- Attendance tracking
- Meeting summary editing
- Reminder email delivery
npm run buildrunsnext buildand then restartsphhs-sitethrough PM2- The reminder scheduler is implemented as a separate PM2 worker, not a system cron job
- Prisma migration history in
prisma/migrations/must stay intact