Files

8.2 KiB

Court Pilot Agent Instructions

Project purpose

Court Pilot is a badminton umpire rotation and court-assignment application. It manages court officials, waiting queues, active court assignments, and optional service judges.

Technology

  • Angular 22 with standalone components and strict TypeScript
  • Ionic Angular 9 UI components
  • Angular signals and RxJS
  • Dexie 4 / IndexedDB for local persistence
  • Angular CDK drag and drop
  • Tauri 2 for desktop packaging and updates
  • Capacitor configuration is present, but native mobile targets are not currently committed
  • Jasmine and Karma for unit tests
  • SCSS for styling

Important paths

  • src/app/ — Angular application
  • src/app/tab1/ — court rotation and assignments (/tabs/pilot)
  • src/app/tab2/ — court-official management (/tabs/umpires)
  • src/app/tab3/ — settings (/tabs/settings)
  • src/app/services/ — persistence and domain services
  • src/app/i18n/ — typed English and Hungarian translations
  • db.ts — Dexie entities, database declaration, and schema version
  • src/theme/ — Ionic theme variables
  • src-tauri/ — Tauri/Rust desktop wrapper
  • .github/workflows/release.yml — tagged desktop release workflow
  • snap/ — Linux Snap packaging
  • docs/ — architecture and domain documentation

Generated and dependency directories

Do not manually edit generated output or installed dependencies:

  • node_modules/
  • .angular/
  • www/
  • src-tauri/target/
  • src-tauri/gen/
  • snap-root/ when generated by release tooling

Implementation conventions

  • Preserve strict TypeScript and strict Angular template checks.
  • Use standalone Angular components and import Ionic components from @ionic/angular.
  • Prefer inject() for dependency injection, matching current components and services.
  • Keep persistent-data access in services rather than directly in page components.
  • Expose reactive Dexie queries through signals when following an existing service pattern.
  • Use readonly for injected dependencies, signals, and derived state when reassignment is unnecessary.
  • Use computed() for state derived from signals.
  • Keep page-specific templates and SCSS beside their page component.
  • Component selectors use the app- prefix and kebab-case.
  • Component classes end in Page or Component.
  • Directive selectors use the app prefix and camelCase.
  • Format touched source and documentation files with Prettier. The root .prettierrc is the shared configuration; do not override it with personal formatting preferences.
  • Avoid formatting unrelated files or lines as part of a focused change.
  • Do not add dependencies unless the task clearly requires one.

Domain and persistence rules

  • Treat changes to db.ts as database migrations, not ordinary interface edits.
  • Never change an existing Dexie schema version in place after release. Add a new db.version(...) declaration and document migration behavior.
  • “Court official” is the umbrella term; “umpire” and “service judge” are roles.
  • Every official must be in exactly one state: not on duty, waiting as umpire, waiting as service judge, assigned as umpire, or assigned as service judge.
  • Preserve FIFO queue ordering by numeric order; the lowest order is assigned next.
  • After a court rotation with service judges enabled, the former umpire joins the service-judge queue and the former service judge joins the umpire queue.
  • When the court count is reduced, remove assignments on eliminated court numbers so those officials become not on duty.
  • Confirm any other uncertain rotation rule with the maintainer; do not infer business rules solely from UI behavior.

Localization

  • Do not hardcode new user-facing text when it should be translated.
  • Write both the English and Hungarian copy for every new user-facing string.
  • Add every translation key to both en and hu in src/app/i18n/translations.ts.
  • Use TranslatePipe in templates and TranslationService in TypeScript.
  • Keep placeholders consistent between languages.

Platform-specific behavior

  • Guard Tauri APIs with isTauri() when code may execute in a browser.
  • Linux updates are delivered through Snap; the in-app Tauri updater is intentionally skipped on Linux.
  • Desktop updater changes must account for Windows and macOS release artifacts and the CrabNebula endpoint.
  • Browser, Windows, macOS, and Linux Snap are supported targets.
  • Android and iOS are not supported or planned at this stage; Capacitor configuration is retained only for possible future use.

Commands

  • Node.js must use the lts/jod NVM alias, as declared in .nvmrc.
  • Documented commands target Bash on Linux, macOS, or Windows WSL. Use Bash explicitly for agent commands; fish's nvm.fish is unavailable in Bash.
  • Initialize Bash NVM once at the start of each shell session: export NVM_DIR="${NVM_DIR:-$HOME/.nvm}"; . "$NVM_DIR/nvm.sh" && nvm use from the project root. nvm use reads lts/jod from .nvmrc. Reuse that initialized shell for subsequent npm commands. If a tool starts a fresh shell for each execution, initialize each new shell or use a persistent shell; environment changes do not carry between independent shells. Stop if initialization fails. Do not rely on .bashrc loading in noninteractive shells or fall back to system Node.
  • If ${NVM_DIR:-$HOME/.nvm}/nvm.sh is missing, ask the user for permission before installing Bash NVM. Follow docs/development.md#shell-and-nvm-setup after approval. Keep existing fish NVM separate.
  • Install exact dependencies: npm ci
  • Start the Ionic development server: npm start
  • Build the web application: npm run build
  • Run unit tests: npm test
  • Run linting: npm run lint
  • Run Tauri CLI commands: npm run tauri -- <command>

Tauri development intentionally uses port 8103. src-tauri/tauri.conf.json expects that port, so its beforeDevCommand starts the project's Angular CLI with serve --host=0.0.0.0 --port=8103. Keep the command aligned with devUrl. Verify the full npm run tauri dev flow before claiming it works.

Release versioning

For every release, keep the same semantic version in:

  • package.json (and the generated root package entry in package-lock.json)
  • src-tauri/tauri.conf.json
  • src-tauri/Cargo.toml (and the generated root package entry in src-tauri/Cargo.lock)
  • snap/snapcraft.yaml

The version displayed in the Settings UI must match these values. Before editing them, inspect Conventional Commits since the latest release tag and recommend the appropriate SemVer bump. If messages are ambiguous, inspect the code/configuration diff since that tag. Present the recommendation and reasoning, allow the developer to enter a different version, and wait for confirmation before changing files. Follow the manual checklist in docs/development.md; do not introduce release automation unless requested.

During release version confirmation, ask whether to run the test suite or skip it. Running tests is the default; skip them only when the developer explicitly chooses to skip. Record any skipped tests in the release validation report. Lint, build, and Cargo checks still apply.

After the confirmed version is synchronized, committed, and validated, create the matching lightweight local tag with GIT_EDITOR=true git tag v<version>. Never tag uncommitted version changes. Do not push the tag without explicit permission because pushing it triggers the release workflow.

Validation expectations

Choose checks based on the affected area:

  1. Run focused or related unit tests for behavior changes where practical.
  2. Run npm run lint for TypeScript/template changes.
  3. Run npm run build for application or build-configuration changes.
  4. For Rust changes, run cargo check from src-tauri/.
  5. For Tauri configuration or release changes, explain which platform-specific builds were not available locally.
  6. Report commands actually run and any pre-existing failures; never claim unrun checks passed.

Working practices

  • Read the relevant page, service, and tests before changing behavior.
  • Make focused changes and preserve unrelated user work.
  • Update tests and documentation when changing behavior, data models, workflows, or commands.
  • Prefer root-cause fixes over UI-only workarounds.
  • Ask for clarification when a change depends on an undocumented tournament or rotation rule.