Files
erika/README.md
T

87 lines
3.3 KiB
Markdown

# 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.