Skip to content

Repository files navigation

SimC Rotation Guides

Live App: https://simc-rotation.app

AI-powered World of Warcraft rotation guides generated directly from SimulationCraft Action Priority Lists (APLs). Each guide is built by feeding the raw .simc APL file into Claude, producing a structured, human-readable rotation guide that stays automatically synchronized with the SimC midnight branch.

Overview

SimC APLs are the authoritative source for optimal rotation logic, but they are written in a domain-specific scripting language that is difficult to read. This app translates those APLs into clear, prioritized rotation guides using Claude.

Every spec across all 13 classes is tracked. When SimC's APL changes (detected via commit SHA), the guide is automatically regenerated. Historical versions are preserved so you can see how a rotation evolved over patches.

Features

  • 40 WoW specs across all 13 classes
  • AI-generated guides from live SimC APLs using claude-sonnet-4-6
  • Auto-sync - daily cron detects APL changes via GitHub commit SHA and regenerates only what changed
  • Guide history - every generated version is archived with its APL commit SHA, generation date, and model used
  • Changelog tracking - each regenerated guide is compared against the previous version by Claude to summarize what changed
  • Ask AI - Q&A chatbot lets you ask questions about any spec's rotation (requires QA API key)
  • Complexity rankings - specs ranked by how many entries their single-target and AoE priority lists contain
  • Dark mode - full dark/light theme toggle with persistent preference
  • Responsive UI with class-colored sidebar, role badges, and priority list rendering

Architecture

Architecture

Getting Started

Prerequisites

  • Node.js 20+
  • npm 10+
  • Anthropic API key - console.anthropic.com. Only needed to generate guides or use Ask AI. The default local dev path seeds placeholder sample guides without one.
  • (Optional) GitHub personal access token for higher API rate limits

Environment Variables

Copy one of the example files to .env in the project root. .env.example.local is the local development template, .env.example documents every supported variable, and .env.example.prod covers the split Railway/Vercel deployment.

cp .env.example.local .env

Do not copy .env.example verbatim for local work: it ships production values (CORS_ORIGIN=https://simc-rotation.app, DB_PATH=/app/data/db.sqlite) that will block requests from http://localhost:5173.

Variable Required Default Description
ANTHROPIC_API_KEY For generation and Q&A -- Anthropic API key for Claude
ADMIN_SECRET Production Auto-generated in dev Bearer token for admin endpoints
NODE_ENV No Unset (production in the backend image) production makes ADMIN_SECRET mandatory (startup fails without it) and suppresses the dev QA key
PORT No 3001 Backend HTTP port
DB_PATH No packages/backend/data/db.sqlite Path to SQLite database file
ANTHROPIC_MODEL No claude-sonnet-4-6 Claude model to use
PROMPT_VERSION No 1.0.0 Logged alongside generated guides
GITHUB_TOKEN No -- GitHub PAT (avoids 60 req/hr rate limit)
CRON_SCHEDULE No 0 3 * * * Cron schedule (default: 3 AM UTC daily)
CORS_ORIGIN No http://localhost:5173 Allowed CORS origin
VITE_API_BASE_URL Frontend Unset (requests go to relative /api) Backend origin, appended with /api. Set this for split deployments such as Vercel.

Additional optional configuration (see .env.example for full list):

Variable Default Description
RATE_LIMIT_GENERAL 120 Requests per minute for public API
RATE_LIMIT_ADMIN 10 Requests per minute for admin endpoints
RATE_LIMIT_QA 5 Requests per minute for Q&A endpoints
QA_MAX_LENGTH 1000 Max character length for Q&A questions
CHANGELOG_CACHE_TTL_MS 3600000 Changelog cache TTL (default 1 hour)
SIMC_REPO simulationcraft/simc SimulationCraft GitHub repository
SIMC_BRANCH midnight SimC branch to track
SIMC_APL_PATH ActionPriorityLists/default APL directory within the SimC repo
PROJECT_REPO Brandon82/SimCRotationGuides This project's GitHub repo (for changelog)

Local Development

# 1. Install all workspace dependencies
npm install

# 2. Start the backend (http://localhost:3001)
npm run dev:backend

# 3. Start the frontend (http://localhost:5173)
npm run dev:frontend

On first start the backend creates the SQLite file and, if the guides table is empty, seeds placeholder sample guides for all 40 specs. That content comes from role-based templates rather than real APL analysis, so no Anthropic API key is required for this path. Unless NODE_ENV=production, the seed also creates a QA API key labelled dev and prints it to the console for testing Ask AI (skipped if an active dev key already exists). To re-run the sample seed manually, use npm run seed:sample; it skips any spec that already has a current guide.

Full seed (optional): To generate fresh guides from the live SimC APLs using your own API key, run npm run seed --workspace packages/backend instead. Estimated cost is $1-5 depending on APL length and model pricing.

Docker Deployment

docker-compose up
  • Backend: http://localhost:3001 (image runs with NODE_ENV=production and DB_PATH=/app/data/db.sqlite)
  • Frontend: http://localhost:5173 (nginx serves the built SPA on container port 80)
  • Database persisted in the named volume db_data, mounted at /app/data

Compose passes ANTHROPIC_API_KEY, ADMIN_SECRET (falls back to dev-secret), GITHUB_TOKEN, ANTHROPIC_MODEL, and PROMPT_VERSION through from your root .env. VITE_API_BASE_URL is a frontend build arg (default http://localhost:3001), so pointing the UI at a different backend requires rebuilding the frontend image.

API Endpoints

Public

Method Path Description
GET /api/health Health check
GET /api/specs All classes and specs with hasGuide flag
GET /api/guides All guide entries, current and historical (metadata only)
GET /api/guides/:specName Current guide for a spec
GET /api/guides/:specName/history Historical guide list
GET /api/guides/:specName/history/:id A specific historical guide
GET /api/rankings Current guides ranked by how many entries their single_target and aoe priority lists contain (two separate rankings)
GET /api/changelog Paginated commit history for this repo (?page defaults to 1, ?per_page defaults to 20 and is capped at 100)

Q&A

Method Path Description
GET /api/qa/validate Validate the X-QA-Key header. Always returns 200 with { "valid": true } or { "valid": false }, even when the header is absent
POST /api/qa/ask Ask a question about a spec's rotation. Requires a valid X-QA-Key header (401 otherwise)

POST /api/qa/ask body:

{ "specName": "warrior_arms", "question": "When should I use Mortal Strike?" }
// Both fields are required. "question" is capped at QA_MAX_LENGTH (1000) characters.

Admin (requires Authorization: Bearer <ADMIN_SECRET> header)

Method Path Description
POST /api/admin/refresh Trigger guide generation
DELETE /api/admin/guides/history Delete old (non-current) guide versions
POST /api/admin/backfill-changelog Generate changelogs for past guides
DELETE /api/admin/changelogs Clear all changelogs
POST /api/admin/qa-keys Create a QA API key
GET /api/admin/qa-keys List all QA API keys
DELETE /api/admin/qa-keys/:id Deactivate a QA API key

POST /api/admin/refresh body:

{ "spec": "warrior_arms" }                    // Single spec
{ "class": "warrior" }                        // All specs in a class (takes precedence over "spec")
{ "spec": ["warrior_arms", "warrior_fury"] }  // Multiple specs
{ "spec": "all" }                             // All 40 specs
{ "spec": "warrior_arms", "force": true }     // Skip SHA check; combines with any form above

DELETE /api/admin/guides/history body:

{}                                            // All specs
{ "spec": "warrior_arms" }                    // One spec only

POST /api/admin/backfill-changelog body:

{ "spec": "warrior_arms" }                    // Single spec, current guide only ("mode" defaults to "current")
{ "spec": "warrior_arms", "mode": "all" }     // Single spec, all history
{ "spec": "all" }                             // All specs (runs in background; "mode" applies here too)

spec is required; a request without it returns 400.

POST /api/admin/qa-keys body:

{ "label": "Brandon" }                        // Returns { id, apiKey, label }

Rate Limiting

Defaults (configurable via env vars):

Tier Limit Endpoints
General 120 req/min specs, guides, rankings, changelog
Admin 10 req/min all /api/admin/* routes
Q&A 5 req/min all /api/qa/* routes, including /validate

Limits are per IP over a 60 second window. /api/health sits outside all three tiers and is not rate limited.

Frontend Routes

Path Page
/ Home - class selector and spec grid
/guide/:specName Spec guide with changelog and version history
/rankings Specs ranked by priority list length (ST and AoE)
/history Filterable table of all generated guides
/ask-ai Q&A chatbot for asking about spec rotations
/changelog Project commit history pulled from GitHub
* Not Found page for any unmatched path

Adding / Modifying Specs

All spec definitions live in packages/backend/src/data/specs.ts. Each entry is a class with a name, label, Blizzard class color, and a specs array. Each spec in that array has its own name (the API and DB key, e.g. warrior_arms), label, and role (dps, healer, or tank). An optional per-spec aplName overrides the SimC filename, which otherwise defaults to the spec's name plus .simc, for cases where SimC doesn't follow that convention (e.g. death_knight_blood maps to deathknight_blood).

After adding a new spec, trigger its first guide generation via the admin API.

Prompt Engineering

LLM prompts live in packages/backend/src/prompts/:

File Purpose
guidePrompt.ts Main APL-to-guide generation. Instructs Claude to translate SimC conditions into plain English and output structured JSON with sections: overview, talent_notes, precombat, single_target, aoe, items_and_racials
qaPrompt.ts Q&A answering. Provides the guide content and raw APL as context for answering user questions about rotations. Output is short conversational markdown, explicitly not JSON
changelogPrompt.ts Changelog generation. Compares old and new guide versions and outputs a bare JSON array of 3-8 bullet-point strings describing what changed

The PROMPT_VERSION env var is stored alongside each guide for traceability when the prompt is updated.

Scripts

Root npm scripts:

Script Description
npm run dev:backend Backend dev server (tsx watch)
npm run dev:frontend Frontend dev server (Vite)
npm run build:backend Compile the backend with tsc
npm run build:frontend Type-check and Vite-build the frontend
npm run build Both builds, backend first
npm run lint ESLint over the frontend workspace
npm run seed:sample Re-run the sample data seed

Backend-only scripts, run with --workspace packages/backend: start (serve the compiled build), seed (full generation from live APLs), generate (regenerate a single spec), create-qa-key (issue a QA key against the local database).

Helper scripts live in the scripts/ directory:

Script Description
dev.sh Starts both backend and frontend dev servers in parallel (kills both on Ctrl+C)
dev-backend.sh Starts the backend dev server only
dev-frontend.sh Starts the frontend dev server only
admin_api_helper.sh Interactive admin CLI for managing the deployed backend (see below)

Admin API Helper

scripts/admin_api_helper.sh is an interactive Bash script for managing the deployed backend without crafting raw curl commands. It prompts for your Railway URL and admin secret, then presents a menu, runs the one action you pick, and exits:

Action Description
Refresh guides Regenerate one spec, multiple specs, an entire class, or all 40 specs (with optional force flag to skip SHA check)
Delete old guides Purge non-current historical guide versions for one or all specs
Backfill changelogs Generate changelogs for existing guides that are missing them (one spec or all; current guide only or the full history)
Delete all changelogs Clear every changelog entry (asks for confirmation first)
Create a QA key Issue a new API key for the Ask AI feature
List QA keys Show every QA key, active and revoked, including its ID, label, full key value, and last-used date
Revoke a QA key Deactivate a specific QA key by ID
bash scripts/admin_api_helper.sh

About

AI-generated World of Warcraft rotation guides, derived from SimulationCraft APLs and updated automatically when APLs change.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages