Files
erika/README.md
T

3.3 KiB

Erika

Erika is a Next.js application for a creator landing page, Discord-authenticated forms, admin form management, submission results, Discord notifications, and XP/voice leaderboards.

Requirements

  • Bun 1.3+
  • PostgreSQL
  • Redis for follower-count caching and server-sent events
  • Discord OAuth and bot credentials for authentication and role-based access

Development

bun install
bun run dev

The development server runs on port 4000.

Useful commands:

bun run lint          # ESLint
bunx tsc --noEmit     # Type checking
bun test              # Unit and domain tests
bun run db:generate   # Generate a Drizzle migration
bun run db:migrate    # Apply migrations

Environment

Create .env.local for local development. The application uses these groups of variables:

  • DATABASE_URL — primary PostgreSQL connection
  • LEADERBOARD_DATABASE_URL — optional read-only leaderboard database
  • REDIS_URL — Redis connection for counters and SSE
  • NEXTAUTH_URL, NEXTAUTH_SECRET — authentication configuration
  • DISCORD_CLIENT_ID, DISCORD_CLIENT_SECRET — Discord OAuth
  • DISCORD_BOT_TOKEN, DISCORD_GUILD_ID — Discord role and profile lookups
  • SHARE_BOT_SECRET — bearer secret for private Discord bot share uploads
  • ADMIN_DISCORD_IDS — comma-separated Discord IDs allowed into admin tools
  • BASE_URL — canonical public URL used in links and OAuth callbacks
  • platform credentials used by follower-count integrations

Never commit .env or .env.local, and never expose credentials through NEXT_PUBLIC_ variables. Before deployment, run:

bun run secrets:scan

Main areas

  • / — public profile and links
  • /form — public form listing and submission
  • /admin — protected administration dashboard
  • /leaderboard/xp — XP leaderboard
  • /leaderboard/vc — voice activity leaderboard
  • /sse/[topic] — authenticated realtime updates
  • /api/upload — authenticated image uploads stored in PostgreSQL
  • /share — Discord-authenticated text publishing with public share pages
  • /api/share — private bearer-authenticated Discord bot publishing endpoint
  • /admin/upload — admin video publishing workspace for YouTube and TikTok

Forms use server actions for authorization, persistence, validation, Discord webhooks, and cache invalidation. Public form drafts are stored locally in the browser.

Docker

bun run up
bun run logs
bun run down

The application listens on port 3000 inside the container. nginx shares the application network namespace and provides the public port configured in docker-compose.yml, including SSE proxy settings.

The production image is built in separate dependency, build, and runner stages. Runtime environment variables are injected by Compose rather than copied into the image.

Security notes

  • Admin server actions require the authenticated Discord ID to be in ADMIN_DISCORD_IDS.
  • Form access checks allowed and denied Discord roles.
  • Uploaded image contents are checked against their declared image type before storage.
  • TikTok OAuth is a private setup utility and requires an admin session plus verified OAuth state.
  • Video files are stored under /nfs/erika; configure VIDEO_UPLOAD_DIR only if the mounted path differs.
  • Rotate credentials if an environment file, build cache, logs, or deployment host may have been exposed.