10 KiB
10 KiB
Agent skills
- Issues and merge requests use GitLab. For tracker operations, read issue-tracker.md.
- Use the default triage labels (
needs-triage,needs-info,ready-for-agent,ready-for-human,wontfix); see triage-labels.md. - Use the single-context domain layout: root
CONTEXT.mdanddocs/adr/. Before exploring a domain, read domain.md and relevant accepted ADRs.
General engineering practices
- Make the smallest complete change; follow existing structure and conventions, keep responsibilities focused, and avoid unrelated refactoring.
- Prefer simple, explicit code and composition. Extract logic when duplicated or independently testable; do not add abstractions or dependencies when the existing stack reasonably solves the problem.
- Add or update tests for changed behavior, and relevant domain documentation for changed behavior, architecture, or business rules.
- Preserve unrelated user changes. Never commit secrets, credentials, local environment files, debug output, temporary files, or generated artifacts.
Development data lifecycle
- The application is not in production; development and test data are disposable and should be deleted or reseeded when the model changes.
- Do not create data migrations, compatibility adapters, dual-read or dual-write paths, or legacy schema support.
- Replace obsolete schemas, reference data, API contracts, and development documents directly, then update every caller and test in the same change.
- Do not plan rolling upgrades or backward-compatible deployment until an explicit project decision declares production data must be preserved. Any future production schema management must be explicit, not automatic schema generation.
Frontend: Angular
Architecture and state
- Organize by feature. Keep pages focused on orchestration, routing, and layout; keep feature-specific components in their feature and reusable presentation in shared components.
- Split sections that own state, behavior, lifecycle, or reusable UI. Review components approaching 250 lines for extraction; keep substantial business logic outside components and templates and independent of Angular when practical.
- Use focused, injected services for API access, coordination, and shared state. Follow existing standalone-component and state-management conventions; justify any new state library. Lazy-load feature routes where appropriate.
- Keep templates readable: move non-trivial calculations to methods, computed values, pipes, or domain utilities. Do not call expensive or state-changing methods from templates.
- Compute derived state rather than duplicating it. Prefer existing signals, observables, or local state; use
asyncor lifecycle helpers over manual subscriptions and clean up unavoidable subscriptions. - Track dynamic lists with
trackByor equivalent syntax and avoid unnecessary change-detection work. - Route guards address navigation only; backend authorization remains mandatory.
TypeScript and forms
- Use strict types and explicit input, output, API, and domain contracts. Use
anyonly for unavoidable integration constraints with a documented reason. - Prefer unions/enums over loosely related strings or boolean flags, and immutable transformations where practical. Avoid non-null assertions unless the invariant is guaranteed and clear.
- Do not use regular-expression
.test()calls unless they are the only valid option and the user has explicitly authorized them; prefer readable, maintainable validation alternatives. - Validate external API data instead of trusting assertions. Prefer reactive forms for complex or business-critical forms, keep validation consistent with the backend, and show actionable messages.
- Prevent duplicate pending submissions. Frontend validation is not a security or integrity boundary.
Styling, loading, and accessibility
- Use Angular Material by default where it covers the UI need. Use Material button directives on native buttons and
MatDialogfor dialogs; never use unstyled native buttons or browser-native dialogs. - Keep all frontend color tokens and Material mappings in
frontend/src/_palette.scss. Use its semantic CSS custom properties elsewhere; no raw hex, RGB, HSL, or OKLCH colors outside that file. - Keep component styles in
.scss, use Sass@usefor shared styles, and do not introduce new.csscomponent styles. - Reuse
frontend/src/_tokens.scssfor spacing, radius, breakpoint, and container-query helpers. Prefer Sass nesting, maps, functions, and mixins over repeated responsive or token-fallback declarations. - Reuse shared components and styles; scope component styles unless intentionally global. Support the required viewport sizes and avoid layout shifts or blocking interactions.
- Provide explicit loading, empty, success, and error states. Every user-observable asynchronous operation must expose a truthful loading lifecycle. Prefer content-shaped skeletons for first loads, preserve content with subtle busy feedback for refreshes, and use operation-local progress for actions so unrelated work remains available. Never present pending or failed data as empty or successful.
- Use semantic HTML before ARIA, native buttons/links for actions, keyboard access, accessible form labels, visible focus, meaningful image alternatives, and correct dialog/overlay focus management. Never communicate status or errors through color alone.
Testing
- Test observable behavior, not implementation details, for changed components, services, pipes, guards, and utilities.
- Cover important form validation, loading, and error states. Mock network boundaries, not internal implementation details; use integration/end-to-end coverage for critical journeys where appropriate.
Backend: Java and Spring Boot
Responsibilities and configuration
- Organize by domain or feature. Keep controllers thin: HTTP, input validation, authentication context, and response mapping. Put application/business logic in services or use cases and persistence in repositories.
- Use explicit, testable mapping and dedicated API request/response DTOs, not persistence entities or generic maps.
- Follow the configured Java version. Prefer constructor injection with explicit immutable dependencies; avoid field injection, circular dependencies, and static access to Spring-managed services.
- Keep domain code framework-independent where practical, with framework annotations at application boundaries.
- Externalize configuration through typed
@ConfigurationProperties, not scattered@Valuefields. Keep environment-specific values out of source and use profiles only for genuine environment differences. - Use domain-specific types, records for immutable data where supported, and enums for finite states. Keep methods focused and use guard clauses where they improve clarity.
- Do not use
Optionalfor entity fields, parameters, or collection elements; return empty collections instead ofnull. - Never silently ignore exceptions. Catch broad exceptions only when meaningfully handling, translating, or rethrowing them, and preserve their causes.
API, persistence, and transactions
- Follow existing REST conventions: resource nouns, standard HTTP methods and appropriate status codes. Validate requests with Jakarta Bean Validation and return consistent structured errors.
- Document endpoint changes using the existing API documentation approach. Consider pagination for large collections. Make retry-sensitive write operations idempotent when practical.
- Keep transaction boundaries in services; use
@Transactional(readOnly = true)for read operations where appropriate. Keep remote calls, long-running work, and user interaction outside transactions. - Fetch only needed data and prevent N+1 queries. Add indexes for identified query patterns, enforce integrity with database constraints as well as validation, and handle concurrent updates where consistency requires it.
- Apply the development data lifecycle above to schema and API changes.
Security and observability
- Enforce backend authorization on every protected operation; hidden controls and route guards are insufficient.
- Validate and sanitize untrusted input. Use parameterized queries or repositories, never query concatenation with untrusted input.
- Store secrets through configured environment/secret management and apply least privilege to services and database users.
- Do not expose stack traces, internal class names, database details, or sensitive information in API responses.
- Use structured logs with appropriate levels and useful non-sensitive identifiers. Do not log passwords, access tokens, session identifiers, personal data, or sensitive payloads.
- Do not use
System.out, print stack traces directly, or duplicate exception logging across layers. Add metrics/tracing for important workflows where already supported. - Review new endpoints for authentication, authorization, data exposure, and abuse cases.
Testing
- Unit-test domain and service behavior. Use integration tests for persistence, security, serialization, transactions, and framework configuration, preferring focused Spring slices when sufficient.
- Follow the established database test strategy. Keep tests deterministic, isolated, and order-independent.
- Cover success, validation and authorization failures, important edge cases, and regressions for bug fixes.
Before finishing
- Review the full task diff for unrelated changes, architectural/naming consistency, oversized units, duplicated logic, unnecessary abstractions, and secret/debug/generated-file leakage.
- For affected frontend behavior, run the formatter, linter, type checker, and relevant tests. For affected backend behavior, run formatting/style checks, static analysis, and relevant tests. Run the project build when practical.
- For instruction, configuration, or helper changes, run their relevant validation and behavioral checks; application suites are needed when application behavior is affected.
- Verify API/database changes are reflected in tests and documentation, and check loading, empty, validation, error, and authorization states where relevant.
- Report checks run and any command not run or unavailable, with the reason.