7.3 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 20 with standalone components and strict TypeScript
- Ionic Angular 8 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 applicationsrc/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 servicessrc/app/i18n/— typed English and Hungarian translationsdb.ts— Dexie entities, database declaration, and schema versionsrc/theme/— Ionic theme variablessrc-tauri/— Tauri/Rust desktop wrapper.github/workflows/release.yml— tagged desktop release workflowsnap/— Linux Snap packagingdocs/— 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/standalone. - 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
readonlyfor 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
PageorComponent. - Directive selectors use the
appprefix and camelCase. - Format touched source and documentation files with Prettier. The root
.prettierrcis 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.tsas 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
enandhuinsrc/app/i18n/translations.ts. - Use
TranslatePipein templates andTranslationServicein 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/jodNVM alias, as declared in.nvmrc. - Before every npm command, run
nvm use lts/jodin the same shell session. Agent terminal calls do not share shell state, so combine this with the npm command when necessary (for example,nvm use lts/jod && npm run build). - 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 must start Ionic on 8103; the current npm start script does not explicitly select it. 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 inpackage-lock.json)src-tauri/tauri.conf.jsonsrc-tauri/Cargo.toml(and the generated root package entry insrc-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.
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:
- Run focused or related unit tests for behavior changes where practical.
- Run
npm run lintfor TypeScript/template changes. - Run
npm run buildfor application or build-configuration changes. - For Rust changes, run
cargo checkfromsrc-tauri/. - For Tauri configuration or release changes, explain which platform-specific builds were not available locally.
- 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.