尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Dispatch hero builds calculator
翻译准备中
取自仓库 README
正在加载完整 README。 以下为已保存的摘录。
A fan-made build calculator for the game Dispatch by AdHoc Studio. Plan your Z-Team ahead of time: level heroes, train powers and flight, and mirror your story choices (who was cut in episode 3, who was hired in episode 4), which decide your synergy pairs. Builds persist in your browser and are shareable as URLs — no account needed.
Built with Nuxt 4, Nuxt UI 4, and Tailwind CSS 4. Builds live in the browser and share by URL; signing in with Google saves them to a FastAPI backend on Neon Postgres instead.查看完整 README ↗A fan-made build calculator for the game Dispatch by AdHoc Studio. Plan your Z-Team ahead of time: level heroes, train powers and flight, and mirror your story choices (who was cut in episode 3, who was hired in episode 4), which decide your synergy pairs. Builds persist in your browser and are shareable as URLs — no account needed.
Built with Nuxt 4, Nuxt UI 4, and Tailwind CSS 4. Builds live in the browser and share by URL; signing in with Google saves them to a FastAPI backend on Neon Postgres instead.
The repository holds two applications: a Nuxt front end in web/ and a FastAPI back end in app/. You only need the back end if you want signed-in accounts. Anonymous planning — the whole calculator, local saves, ?build= share links — runs on the front end alone, with no database, no Firebase project and no .env at all.
| Tool | Why | Notes |
|---|---|---|
| Node ≥ 24 | the front end | mise.toml pins Node 24; mise install picks it up |
| pnpm 10 | the only package manager accepted | corepack enable uses the version in packageManager; a preinstall hook rejects npm and yarn |
| uv | the back end | it installs Python 3.14 itself from .python-version — no separate Python needed |
| Docker | back-end integration tests | optional; without it those tests skip loudly rather than fall back to a fake database |
| Firebase CLI | signing in locally | optional; only for the Auth emulator |
pnpm install
pnpm dev # http://localhost:3000
That is genuinely all of it. Sign-in reports itself unavailable and every account query stays switched off, which is the designed behaviour rather than an error state.
Both applications read the same .env at the repository root — Nuxt for its NUXT_PUBLIC_* values, FastAPI for the rest.
cp .env.example .env
Fill in:
DATABASE_URL and DATABASE_URL_DIRECT. From Neon (neon connection-string dev --pooled and neon connection-string dev), or from any local PostgreSQL — point both at it. They are not interchangeable: the pooled endpoint is PgBouncer in transaction mode, where the advisory locks Alembic takes fail silently, so migrations must only ever see the direct one. Spell the driver: postgresql+psycopg://, never a bare postgresql://.FIREBASE_PROJECT_ID, plus either FIREBASE_SERVICE_ACCOUNT_FILE (a service-account key, kept outside this repository — it is public) or FIREBASE_AUTH_EMULATOR_HOST for local work. A deployed host has no file to point at, so it sets FIREBASE_SERVICE_ACCOUNT_JSON to the key's contents instead; the file and the JSON are mutually exclusive. The API refuses to start with no credential and no emulator, and refuses to start with the emulator variable set outside development, because emulator tokens are unsigned.CORS_ALLOW_ORIGINS must list http://localhost:3000. It is deny-by-default: an empty list admits no browser at all.NUXT_PUBLIC_API_BASE_URL=http://localhost:8000/api/v1, and the four NUXT_PUBLIC_FIREBASE_* values from firebase apps:sdkconfig (public — they ship in the browser bundle).Then install, migrate, and run the three processes in their own terminals:
pnpm install
uv sync --locked
uv run alembic upgrade head # direct endpoint only
firebase emulators:start --only auth --project z-team-planner # :9099, for signing in
uv run uvicorn app.main:create_app --factory --reload --port 8000 # the API
pnpm dev # the app, :3000
To sign in against the emulator rather than a real Google account, also set NUXT_PUBLIC_FIREBASE_AUTH_EMULATOR_HOST=localhost:9099; the web SDK then talks to it instead of Google, and the API accepts the tokens it mints.
--project is not optional, and it must match FIREBASE_PROJECT_ID. Without it the emulator mints tokens for demo-no-project, and the API refuses every one of them with a 401 — it checks the audience, so a token for another project never passes.
Check the API is alive with curl localhost:8000/healthz and that it can reach the database with curl localhost:8000/readyz. A suspended Neon compute makes the first /readyz take about a second while it wakes — that is normal, not a fault.
uvicorn app.main:create_app --factoryis not optional. There is no module-levelappobject, deliberately: importing one would read the environment and reconfigure logging as a side effect.
pnpm lint # oxlint uv run ruff check .
pnpm format # oxfmt uv run ruff format .
pnpm typecheck # vue-tsc via nuxt uv run pyright
pnpm test # vitest uv run pytest
pnpm lint:fix # oxlint with its safe fixes applied
pnpm format:check # oxfmt without writing — what CI runs
pnpm test:unit # plain Node unit tests only (test/unit/)
pnpm test:nuxt # Nuxt runtime tests only (test/nuxt/)
pnpm test:watch # vitest in watch mode; every other test script runs once
pnpm test:coverage # the whole suite with a V8 coverage report in coverage/
CI (.github/workflows/ci.yml) runs lint, format check, typecheck and tests for both applications on every push and pull request, Renovate opens dependency PRs on Mondays, and security fixes as soon as an advisory lands; none of them merges without a person.
Optional, and per clone. Three hooks ship in catalyst/tools/hooks/:
pre-commit runs the Catalyst document validator, then the format and lint checks for both applications, and blocks the commit if any of them objects.post-commit and post-merge tag a commit or merge on master that changes VERSION as v<VERSION>. The tag stays local until you push it.sh catalyst/tools/hooks/install.sh # activate all three in .git/hooks
Worth the two seconds because the failure the pre-commit hook catches is invisible locally: oxfmt reflows Markdown tables, so a hand-edited document passes the validator and fails CI. A clone that still has core.hooksPath set from the old .githooks/ folder runs no hooks at all, so clear it first with git config --unset core.hooksPath.
uv run pytest -m "not integration" skips the tests that need Docker. uv run python -m scripts.reset_db --yes drops the development database schema and migrates it back up; it refuses unless APP_ENV is development. pnpm run game-data:export regenerates shared/game-data.json from web/types/hero.ts — the fixture the API validates saved builds against; a test fails if the committed copy has drifted.
app/CLAUDE.md is the orientation map for the service, and web/CLAUDE.md for the app.
Open the repository root, not either sub-directory. On first open the editor offers the recommended extensions from .vscode/extensions.json — accept them: oxc provides lint and format for TypeScript, Vue, CSS and JSON (.vscode/settings.json already sets it as the formatter and turns on format-on-save), Volar handles Vue SFCs, and Better Comments colours the // * and // ! annotation markers this codebase uses throughout.
The Python side is in the same list: the Python extension and its debugger, Ruff as formatter (settings.json makes it the Python formatter and organises imports on save), and Pyright for the editor — anysphere.cursorpyright on Cursor, ms-python.vscode-pylance on VS Code; each editor reports the other as not found, so install the one yours can. mise (hverlin.mise-vscode) picks up the Node pin from mise.toml. settings.json points the interpreter at .venv/bin/python, which uv sync creates.
Build and locally preview:
pnpm build
pnpm preview
Unlike pnpm dev, a production build fails unless the four NUXT_PUBLIC_FIREBASE_* values, NUXT_SITE_URL (the absolute origin, no trailing slash) and NUXT_SITE_ENV are set — they are baked into the bundle, and a build with none of them would ship an app silently pointed at nothing. NUXT_SITE_ENV must be production for search engines to index the site; any other value keeps every page out. NUXT_PUBLIC_API_BASE_URL is the one exception: left empty, the build succeeds as the planner alone, with sign-in unavailable. Development is deliberately exempt so the anonymous planner needs no setup at all.
The planner and the API are live on Vercel at https://z-team-planner.vercel.app, deployed from master as one project with two services: the API answers under /api/v1 on the same origin. vercel.json declares both, and catalyst/operations.md is the runbook.
catalyst/ is this repository's Catalyst rule set — the documents an agent reads before it changes anything here, adopted into this repository from the Catalyst template. They are contracts, not descriptions: catalyst/prime-directive.md says how work runs (task weights, the feature and decision gates, branch and commit discipline), catalyst/architecture.md says what this system may be built from, and catalyst/project-summary.md indexes this project's own features and decisions. Start at catalyst/AGENTS.md — it is the file index, and everything else loads on demand.
The project's own documents are written inside the bundle (catalyst/features/, catalyst/decisions/), never in root-level directories. The rule set is upgraded in place from the Catalyst repository, so catalyst/ is edited deliberately and never reorganized.