Community web application for the VEAF (Virtual European Air Force) for DCS World.
Stack: FastAPI (Python 3.12) + Vue.js 3 (TypeScript, Tailwind CSS) + PostgreSQL 16
- Docker and Docker Compose
# Copy and configure environment variables
cp backend/.env.dist backend/.env
# Edit backend/.env with your values (JWT_SECRET, DB, etc.)
# Start the application
./scripts/start.sh
# The application is available at http://veaf.localhost./scripts/stop.sh # Stop
./scripts/upgrade.sh # Update + migrations# Start all services (backend hot-reload, frontend Vite, PostgreSQL)
docker compose upApplication at http://veaf.localhost (Swagger: http://veaf.localhost/api/docs). Nginx reverse proxy routes /api/* to the backend and / to the frontend.
./scripts/dev/fixtures.sh # Reset DB + load fixturesCompte admin par défaut : mitch@localhost.dev / test1234
The scripts/uv.sh script runs uv in the backend container (exec if the container is running, run --rm otherwise).
./scripts/uv.sh sync # Install/sync dependencies
./scripts/uv.sh add httpx # Add a dependency
./scripts/uv.sh add --group dev ruff # Add a dev dependency
./scripts/uv.sh lock # Regenerate the lockfileThe scripts/alembic.sh script runs Alembic in the backend container (exec if the container is running, run --rm otherwise).
./scripts/alembic.sh upgrade head
./scripts/alembic.sh revision --autogenerate -m "description"
./scripts/alembic.sh downgrade -1./scripts/uv.sh run pytest tests/ -v
docker compose exec frontend npm run test./scripts/uv.sh run ruff check .
docker compose exec frontend npm run lintUsers can log in with their Discord account via OAuth2.
- Create an application on the Discord Developer Portal
- Under OAuth2 > General:
- Copy the Client ID and Client Secret
- Add the Redirect URI:
https://your-domain/auth/discord/callback(dev:http://veaf.localhost/auth/discord/callback)
- Set the environment variables in
backend/.env:
DISCORD_CLIENT_ID=123456789012345678
DISCORD_CLIENT_SECRET=your-client-secret
DISCORD_REDIRECT_URI=http://veaf.localhost/auth/discord/callbackThe required scopes (identify and email) are requested automatically by the application.
- If a Discord user has the same email as an existing account, the accounts are automatically linked.
- If no matching account exists, a new account is created using the Discord username.
- Users created via Discord have no local password; they must log in through Discord.
Display active users in Discord voice channels on the website (similar to the TeamSpeak feature).
- Go to the Discord Developer Portal and select your application (or create one)
- Under Bot:
- Click Reset Token to generate a bot token, and copy it
- Enable Privileged Gateway Intents: Server Members Intent and Presence Intent
- Under OAuth2 > URL Generator:
- Select the bot scope
- No special permissions are needed (the bot only reads voice states)
- Open the generated URL to invite the bot to your Discord server
- Copy the Guild ID (server ID) of your Discord server: right-click the server name in Discord > Copy Server ID (requires Developer Mode enabled in Discord settings)
- Set the environment variables in
backend/.env:
DISCORD_BOT_TOKEN=your-bot-token
DISCORD_GUILD_ID=123456789012345678- The backend runs a Discord Gateway bot that receives voice state updates in real-time via WebSocket
- Voice channel presence is cached in memory and exposed via
GET /api/discord-voice/status - The
/discordpage displays active voice channels with connected users - A badge in the navigation menu shows the number of users currently in voice channels
- If
DISCORD_BOT_TOKENorDISCORD_GUILD_IDare not set, the feature is disabled
See backend/.env.dist for the full list. Essential variables:
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection URL (asyncpg) |
JWT_SECRET |
Secret key for JWT tokens |
APP_URL |
Public application URL |
UPLOAD_DIR |
Upload file storage directory |
DISCORD_CLIENT_ID |
Discord OAuth2 application Client ID |
DISCORD_CLIENT_SECRET |
Discord OAuth2 application Client Secret |
DISCORD_REDIRECT_URI |
Discord OAuth2 redirect URI (must match Discord Developer Portal) |
DISCORD_BOT_TOKEN |
Discord bot token (for voice channel display) |
DISCORD_GUILD_ID |
Discord server (guild) ID (for voice channel display) |