Skip to content
PT
All projects
Web platformLive · staff sign-inSep 2026 – present

The Camp StaffHub

Staff and member platform for a 330K-member Discord community.

Public landing page. The tools need staff sign-in.

Community
330K+ members
In voice
100+ at a time
Hosting
Self-managed VPS
Live since
Sep 2026

The Camp bills itself as the most active voice server on Discord. Its staff needed one place to log moderation reports and appeals, manage ranks and see who is actually doing the work, instead of spreadsheets and pasted messages.

I designed, built and run that platform end to end: the schema, sign-in, admin tools, the integration with the community's Discord bot, hosting, backups and deploys. It later grew a member-facing side with points, levels and collectible profile cards.

The Camp SH staff dashboard in a dark theme. A sidebar lists Home, Staff List, Watchlist, Staff on Leave, History Logs, Moderation Guide, Moderation Support, Admin and Tools. Counters show 21 active staff, 3 on leave and 629 total reports.
Staff home: roster, leave and report counts at a glance, with every tool one click away.
The Camp landing page: logo, 'Most Active Voice Server', and live member counts.
The public landing page, which reads live counts from Discord.
How a request moves through the system

Staff

  1. Discord sign-in

    whitelist-gated

  2. nginx

    TLS, rate limits

  3. Next.js on PM2

    App Router, cluster

  4. PostgreSQL

    Prisma

Bot

  1. Discord bot

    ?card, ?rank, role changes

  2. Bot API

    points, levels, cards

  3. Chromium renderer

    PNG or animated GIF

  4. Cache

    saved card versions

What it does

The parts worth talking about

Reports and appeals

Staff file reports and appeals through validated forms that post formatted embeds to the right Discord channels via webhooks, with an excuse-note system and a searchable, point-based rules checklist beside them.

Moderator accountability

Mod points, a leaderboard for any month or year, and a Mod Audit tool that exports a day-by-day calendar workbook (.xlsx), replacing a manual Excel-tallying routine.

A member economy

Points, chat and voice XP, levels with role rewards, achievements, a card shop and a sticker draw. XP boosts stack without ever touching points, and a test script checks that the points paid are identical with and without them.

Profile cards rendered on demand

The bot asks the site for a member's card and a warm headless Chromium renders it to a PNG or an animated GIF, then caches it. A layout checker measures every card across nine themes; it found 12 layout problems and now reports none.

A two-way bot bridge

The bot polls the site's API for points and levels, while a loopback-only HTTP bridge lets the site call into the bot, so changing an Internal Affairs status grants or revokes the matching Discord role almost instantly.

Operations I own

PM2 cluster behind nginx with rate limiting, Let's Encrypt, nightly AES-256 encrypted backups to the VPS and Google Drive with a tested restore, and BBR congestion control that fixed stalled image downloads for members in the Philippines.

What went wrong

Incidents that changed how I work

Each of these reached production. Each one is now a rule or an automated check.

A reload that only reloaded one app

A combined `pm2 reload a b` restarted just the first process, so the bot's API ran day-old code for about 34 hours. The deploy script now restarts each app as its own command and checks that every process has a fresh uptime.

The silent CSS 404

The card renderer is its own `next start` process and kept serving references to hashed stylesheets that a newer build had deleted. The site looked fine; only card images lost their layout. The renderer is now restarted by every deploy and a check fetches its CSS.

A deploy that deleted files

An rsync flag deleted files it shouldn't have. Deploys now ship `git archive HEAD` through a plain tar extract that never deletes anything on the server, behind a clean-tree check and a database backup.

Stack

Built with

  • Next.js 16
  • React 19
  • TypeScript
  • Tailwind CSS 4
  • Prisma 7
  • PostgreSQL
  • Auth.js (Discord OAuth)
  • Playwright
  • sharp
  • ExcelJS
  • zod
  • PM2
  • nginx