# Project Checklist (tidy & current) Below are the implemented features and current status as reflected in the repository. Items marked [x] are implemented and wired; unchecked items are pending. ## Backend - [x] Basic Express server and project setup - [x] Discord OAuth2 endpoints - [x] API endpoints for servers, channels, roles, leave, settings - [x] Persist encrypted data to `db.json` ## Frontend - [x] Login page - [x] Dashboard page - [x] Backend connectivity for APIs - [x] UI components using MUI - [x] Server-specific settings pages - [x] Persist user data (localStorage + backend) - [x] Logout - [x] Responsive UI and improved styling - [x] Theme switching (light, dark, Discord grey) - [x] User settings menu - [x] Commands section in Server Settings (per-command toggles) - [x] Commands list sorted alphabetically in Server Settings - [x] Help → renamed to 'Commands List' and moved to dedicated page - [x] NavBar redesigned (single-hamburger, title 'ECS - EHDCHADSWORTH') - [x] Invite button on dashboard and server cards (with pre-invite check) - [x] Invite button on dashboard (single action below the server title) and server cards (with pre-invite check) - [x] Invite management UI in Server Settings (create/list/delete invites) ## Invite Management (implemented) - [x] Backend endpoints: GET/POST/DELETE `/api/servers/:guildId/invites` - [x] Backend endpoints: GET/POST/DELETE `/api/servers/:guildId/invites` (supports optional `INVITE_API_KEY` or short-lived invite tokens via `/api/servers/:guildId/invite-token`) - [x] Frontend: invite creation form (channel optional, expiry, max uses, temporary), labels added, mobile-friendly layout - [x] Frontend: invite list with Copy and Delete actions and metadata - [x] Frontend: invite list with Copy and Delete actions and metadata (copy/delete fixed UI handlers) - [x] Discord bot commands: `/create-invite`, `/list-invites` and interaction handlers for copy/delete - [x] Invites persisted in encrypted `db.json` ## Security - [x] Invite DELETE route now requires a short-lived invite token issued by `/api/servers/:guildId/invite-token` and sent in the `x-invite-token` header. The old `INVITE_API_KEY` header is no longer used. - [x] Invite delete UI now shows a confirmation dialog before deleting an invite. ## Theme & UX - [x] Theme changes persist immediately (localStorage) and are applied across navigation - [x] Theme preference priority: local selection > server preference > default (default only used on first visit) ## Discord Bot - [x] Bot with event & command handlers - [x] Slash command registration and runtime enable/disable mechanism - [x] `/help` and `/manage-commands` (manage persists toggles to backend) - [x] Invite-related slash commands implemented (`/create-invite`, `/list-invites`) ## Features - [x] Welcome/Leave messages (frontend + backend + bot integration) - [x] Autorole (frontend + backend + bot integration) ## Pending / Suggested improvements - [ ] Consider stronger auth for invite delete (e.g., require user auth or signed requests); currently an optional API key is supported via `INVITE_API_KEY`. ## Deployment notes (VPS / Tailscale) Quick guidance to run the backend, frontend and bot on a VPS or make the API accessible over a Tailscale network: - Environment variables you'll want to set (backend `.env`): - `PORT` (e.g. 3002) - `HOST` the bind address (e.g. `100.x.y.z` Tailscale IP for the VPS or `0.0.0.0` to bind all interfaces) - `CORS_ORIGIN` origin allowed for cross-origin requests (e.g. `http://100.x.y.z:3000` or `*` during testing) - `INVITE_API_KEY` (optional) secret to protect invite DELETE requests - `DISCORD_CLIENT_ID`, `DISCORD_CLIENT_SECRET`, `DISCORD_BOT_TOKEN`, `ENCRYPTION_KEY` (existing bot secrets) - Frontend config: - Build the frontend (`npm run build`) and serve it with a static server (nginx) or host separately. - Configure `REACT_APP_API_BASE` before building to point to your backend (e.g. `http://100.x.y.z:3002`). Current local dev hosts used in this workspace (update these values in your `.env` files if you change ports): - Frontend dev server: `http://100.70.209.56:3001` (set in `frontend/.env` as HOST=100.70.209.56 and PORT=3001) - Backend server: `http://100.70.209.56:3002` (set in `backend/.env` as HOST=100.70.209.56 and PORT=3002) Discord Developer Portal settings (must match your BACKEND_BASE and FRONTEND_BASE): - OAuth2 Redirect URI to add: `http://100.70.209.56:3002/auth/discord/callback` - OAuth2 Allowed Origin (CORS / Application Origin): `http://100.70.209.56:3001` - Tailscale notes: - Ensure the VPS has Tailscale installed and is in your Tailnet. - Use the VPS Tailscale IP (100.x.y.z) as `HOST` or to reach the API from other machines on the tailnet. - For convenience and security, only expose ports on the Tailscale interface and avoid opening them to the public internet. - Example systemd service (backend) on VPS (/etc/systemd/system/ecs-backend.service): - Set `Environment=` entries for your `.env` or point to a `.env` file in the service unit, and run `node index.js` in the `backend` folder. Where to change host/port and base URLs - Backend: edit `backend/.env` (or set the environment variables) — key entries: - `HOST` — bind address (e.g., your Tailscale IP like `100.x.y.z` or `0.0.0.0`) - `PORT` — port the backend listens on (e.g., `3002`) - `BACKEND_BASE` — optional fully-qualified base URL (defaults to `http://HOST:PORT`) - `FRONTEND_BASE` — used for OAuth redirect to frontend (e.g., `http://100.x.y.z:3000`) - Frontend: set `REACT_APP_API_BASE` in `frontend/.env` before running `npm run build` (or export at runtime for development). Example: - `REACT_APP_API_BASE=http://100.x.y.z:3002` I've added `backend/.env.example` and `frontend/.env.example` as templates — copy them to `.env` and fill in values for your environment. - Example nginx (reverse proxy) snippet if you want to expose via a domain (optional): - Proxy `https://yourdomain.example` to the backend (or to the frontend build directory) with TLS termination at nginx. If you'd like, I can: - Add a small `deploy.md` with exact steps and example `systemd` unit and `nginx` config. - Update frontend to read a runtime-config file (useful when you don't want to rebuild to change API base). - [ ] Add unit/integration tests for invite endpoints and ThemeContext behavior - [ ] Accessibility improvements (ARIA attributes, focus styles) across the settings forms - [ ] Small UI polish (spacing/visuals) for invite list items and commands list If you'd like, I can immediately: - Pin protected commands (e.g., `help`, `manage-commands`) to the top of the Commands list while keeping the rest alphabetical. - Add ARIA labels and keyboard navigation tweaks for the invite dropdowns. - Add tests for ThemeContext. UI tweaks applied: - Server cards on the Dashboard have been updated to enforce exact identical size per breakpoint (fixed heights), images are cropped uniformly (object-fit: cover) so icons are the same visible area across cards, and long server names are clamped to two lines to prevent layout differences. - Mobile spacing, paddings, and typography adjusted for better legibility on small screens. - Mobile fix: Title clamping and CardContent overflow were tightened so cards no longer expand on mobile; images use a background-image approach and white background to keep visible areas identical. - Dashboard action buttons moved: Invite/Leave action now appears below the server title with a left label 'Invite:' or 'Leave:' and the action button to the right. - [x] Browser tab now shows `ECS - ` (e.g., 'ECS - Dashboard', 'ECS - Server Settings') for each page.