A full-stack Rust application to predict concert setlists and create playlists on streaming services.
- README.md: Quick start, local dev (Trunk), Docker/CI build, and testing entry points.
- AGENTS.md: Contributor rules and architecture constraints.
- TESTING.md: Playwright E2E setup and usage.
- TEST_PLAN.md: Test coverage matrix and goals.
- docs/ROADMAP.md: Product roadmap and prioritization.
User (Browser) -> Leptos (SSR) -> Axum Server -> [Setlist.fm / Spotify / Deezer]
graph LR
User[User Browser] -- HTTP/WASM --> Axum[Axum Server]
Axum -- SSR --> Leptos[Leptos App]
Axum -- API --> SetlistFM[Setlist.fm API]
Axum -- API --> Spotify[Spotify API]
Axum -- API --> Deezer[Deezer API]
- Rust (latest stable)
- Cargo
- Docker (optional)
- Go to Setlist.fm API.
- Login or create an account.
- Request an API Key in your profile settings or API section.
- Copy the key to
SETLIST_FM_KEYin.env.
- Go to the Spotify Developer Dashboard.
- Log in with your Spotify account.
- Click "Create App".
- Enter an App Name (e.g., "Concert Playlist Builder") and Description.
- In the Redirect URIs field, enter
http://127.0.0.1:8080/auth/spotify/callback(and your production URL, e.g.https://app.encoreprophet.com/auth/spotify/callback, plus QA if used:https://qa.encoreprophet.com/auth/spotify/callback). - Save the app.
- Go to Settings (or look at the dashboard overview for the app).
- Copy the Client ID and Client Secret.
- Paste them into
SPOTIFY_CLIENT_IDandSPOTIFY_CLIENT_SECRETin your.envfile.
You can configure Deezer using either the official API (if you have an existing app) or the ARL Token workaround (if you cannot create a new app).
Method 1: Official API
- Go to the Deezer Developers Portal.
- Get your Application ID (App ID) and Secret Key.
- Paste them into
DEEZER_APP_IDandDEEZER_SECRET_KEYin your.envfile.
Method 2: ARL Token Workaround (Use this if you cannot create a new App due to Deezer's suspension)
- Login to Deezer in your web browser.
- Open Developer Tools (F12) -> Application (tab) -> Cookies ->
https://www.deezer.com. - Find the cookie named
arl. - Copy its value.
- Paste it into
DEEZER_ARLin your.envfile.
- Copy
.env.exampleto.env:cp .env.example .env
- Fill in the API keys obtained above.
Use Trunk for the fastest dev loop. It serves the frontend and proxies /api to the Axum server.
- Install Trunk:
cargo install trunk
- Run the Backend (API):
The server listens on
# Must be run from root. Server config loader checks 'server/Cargo.toml' cargo run --bin serverhttp://127.0.0.1:8080. - Run the Frontend (Trunk):
The app will be available at
trunk serve --port 8081
http://127.0.0.1:8081. Trunk will rebuild automatically on changes.
The CI/CD pipeline builds via Docker. This sequence mirrors the Dockerfile locally and requires node, npm, and wasm-pack.
mkdir -p target/site/pkg
npx tailwindcss -i style/main.css -o style/output.css
cp style/output.css target/site/pkg/app.css
cd app
wasm-pack build --target web --out-dir ../target/site/pkg --out-name app --no-typescript --features hydrate
cd ..
cp -R assets target/site/
cargo run --bin serverRun the full test suite (ensure SSR feature is enabled for app tests):
cargo test --workspace --all-featuresSee TESTING.md for Playwright setup, configuration, and usage.
This project uses Chainguard images for a secure, minimal footprint. The Docker build produces a full-stack container running the Axum server with SSR.
docker build -t concert-playlist-builder .- Builder:
cgr.dev/chainguard/rust:latest-dev - Runner:
cgr.dev/chainguard/glibc-dynamic
To run the container, you must provide the .env file containing your API keys. The server listens on port 8080.
docker run -p 8080:8080 --env-file .env concert-playlist-builderThe application will be available at http://127.0.0.1:8080.
If you are running the application behind a reverse proxy (like Nginx or a tunneling service like ngrok), you must set the LEPTOS_SITE_URL environment variable to the public-facing URL. This is required for Leptos's CSRF protection to work correctly.
For example, if your application is accessible at https://myapp.com, you should set the environment variable as follows:
export LEPTOS_SITE_URL="https://myapp.com"When running with Docker, you can pass the environment variable with the -e flag:
docker run -p 8080:8080 --env-file .env -e LEPTOS_SITE_URL="https://myapp.com" concert-playlist-builderThis project includes a GitHub Actions workflow for continuous deployment to Google Cloud Run.
Note: CI currently deploys on main and does not run PR checks. Add PR test gates to block merges on failures.
- Add PR checks for
cargo test --workspace --all-features. - Add a Playwright smoke job against a deployed preview or local server.
- Block merges when CI checks fail.
- See
docs/ROADMAP.mdfor broader DevOps planning.
The deployment workflow is defined in .github/workflows/deploy.yml and is triggered on every push to the main branch. It performs the following steps:
- Authentication: Authenticates with Google Cloud using a service account.
- Infrastructure & Build: Automatically creates the Artifact Registry repository (if missing), builds the Docker image, and pushes it to the repository.
- Deploy: Deploys the new image to the
concert-playlist-builderservice on Google Cloud Run.
The workflow requires the following secrets to be set in the GitHub repository's settings:
GCP_SA_KEY: The JSON key for the Google Cloud service account. This service account must have the following IAM roles:- Artifact Registry Administrator (
roles/artifactregistry.admin) - Required to create the repository and push/pull images. - Cloud Run Admin (
roles/run.admin) - Required to deploy and manage the Cloud Run service. - Service Account User (
roles/iam.serviceAccountUser) - Required to allow the GitHub Actions workflow to act as the Cloud Run service identity.
- Artifact Registry Administrator (
GCP_PROJECT_ID: The ID of your Google Cloud project.SPOTIFY_CLIENT_ID: Your Spotify application's Client ID.SPOTIFY_CLIENT_SECRET: Your Spotify application's Client Secret.SPOTIFY_REDIRECT_URI: Full Spotify OAuth redirect URL (e.g.https://app.encoreprophet.com/auth/spotify/callbackorhttps://qa.encoreprophet.com/auth/spotify/callback). In GitHub Actions deploys, this is set based on branch (main vs non-main).SETLIST_FM_KEY: Your Setlist.fm API key.DEEZER_ARL: Your Deezer ARL token.