# 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 visitor counts and server-sent events - Discord OAuth and bot credentials for authentication and role-based access ## Development ```bash bun install bun run dev ``` The development server runs on port `4000`. Useful commands: ```bash 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: ```bash 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 ```bash 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.