235 lines
13 KiB
Markdown
235 lines
13 KiB
Markdown
## Agent skills
|
|
|
|
### Issue tracker
|
|
|
|
Issues and merge requests (MRs) are tracked in this repository's GitLab instance. See [issue-tracker.md](file:///home/nessar/lmnp-organizer/docs/agents/issue-tracker.md).
|
|
|
|
### Triage labels
|
|
|
|
Use the default triage labels (`needs-triage`, `needs-info`, `ready-for-agent`, `ready-for-human`, `wontfix`). See [triage-labels.md](file:///home/nessar/lmnp-organizer/docs/agents/triage-labels.md).
|
|
|
|
### Domain docs
|
|
|
|
Use the single-context documentation layout. See [domain.md](file:///home/nessar/lmnp-organizer/docs/agents/domain.md).
|
|
|
|
## General engineering practices
|
|
|
|
- Make the smallest change that fully solves the issue.
|
|
- Follow the existing project structure and conventions before introducing new patterns.
|
|
- Prefer simple, explicit code over unnecessary abstraction.
|
|
- Keep classes, components, and functions focused on one responsibility.
|
|
- Extract reusable logic when it is duplicated or independently testable.
|
|
- Avoid unrelated refactoring in feature or bug-fix merge requests.
|
|
- Do not introduce a new dependency when the existing stack can reasonably solve the problem.
|
|
- The application is not in production. Change development contracts and schemas directly when the domain model changes; update all callers and tests together instead of preserving backward compatibility.
|
|
- Add or update tests for changed behavior.
|
|
- Do not commit secrets, tokens, credentials, generated artifacts, or local environment files.
|
|
- Update relevant domain documentation when behavior, architecture, or business rules change.
|
|
|
|
## Frontend: Angular
|
|
|
|
### Components
|
|
|
|
- Keep components small and focused on a single responsibility.
|
|
- Split a component when a section has its own state, behavior, lifecycle, or reusable UI.
|
|
- Keep page-level components focused on orchestration, routing, and layout.
|
|
- Move reusable presentation elements into shared components.
|
|
- Keep feature-specific components inside their feature directory.
|
|
- Prefer composition over components with many configuration flags.
|
|
- Avoid large component files. Components approaching 250 lines should be reviewed for extraction opportunities.
|
|
- Do not place substantial business logic directly in templates or components.
|
|
|
|
### Angular architecture
|
|
|
|
- Organize code by feature rather than only by technical type.
|
|
- Keep domain and business logic independent from Angular when practical.
|
|
- Use services for API access, application coordination, and shared state.
|
|
- Use dependency injection instead of manually constructing services.
|
|
- Keep services focused; avoid catch-all services with unrelated responsibilities.
|
|
- Prefer standalone components where they match the existing project architecture.
|
|
- Lazy-load feature routes where appropriate.
|
|
- Use route guards only for navigation concerns, not as the sole enforcement of security rules.
|
|
- Follow the repository's established state-management approach. Do not introduce another state-management library without justification.
|
|
|
|
### Templates and state
|
|
|
|
- Keep templates readable and free of complex expressions.
|
|
- Move non-trivial calculations into component methods, computed values, pipes, or domain utilities.
|
|
- Do not call expensive or state-changing methods from templates.
|
|
- Prefer Angular signals, observables, or local component state according to the existing codebase conventions.
|
|
- Do not duplicate derived state. Compute values from their source whenever practical.
|
|
- Avoid manual subscriptions when the `async` pipe, signals, or framework lifecycle helpers can manage them.
|
|
- Ensure subscriptions are cleaned up when manual subscription is unavoidable.
|
|
- Use `trackBy` or Angular's equivalent tracking syntax for dynamic lists.
|
|
- Avoid unnecessary change-detection work.
|
|
|
|
### TypeScript
|
|
|
|
- Use strict TypeScript types.
|
|
- Do not use `any` unless integration constraints make it unavoidable and the reason is documented.
|
|
- Define explicit input, output, API, and domain types.
|
|
- Prefer unions and enums over loosely related strings or multiple boolean flags.
|
|
- Use immutable transformations where practical.
|
|
- Do not use regular-expression `.test()` calls unless they are the only valid option and the user has explicitly authorized them; prefer more readable, maintainable validation alternatives.
|
|
- Avoid non-null assertions unless the invariant is guaranteed and clear.
|
|
- Validate data received from external APIs instead of trusting type assertions.
|
|
|
|
### Forms
|
|
|
|
- Prefer reactive forms for complex or business-critical forms.
|
|
- Keep validation rules consistent between the frontend and backend.
|
|
- Display actionable validation messages.
|
|
- Prevent duplicate submissions while a request is pending.
|
|
- Do not rely on frontend validation for security or data integrity.
|
|
|
|
### Styling and user experience
|
|
|
|
- Use Angular Material components by default whenever they cover the UI need.
|
|
- Never use unstyled native buttons or browser-native dialogs; use Angular Material button directives and `MatDialog` instead.
|
|
- Reuse the existing design system, shared components, spacing rules, and design tokens.
|
|
- Avoid duplicating styles already provided by shared components.
|
|
- Keep component styles scoped unless a style is intentionally global.
|
|
- Ensure layouts work across supported viewport sizes.
|
|
- Provide explicit loading, empty, success, and error states.
|
|
- Every user-observable asynchronous frontend operation must expose a truthful loading lifecycle. Prefer content-shaped skeletons for first loads, preserve established content with subtle busy feedback during refreshes, and use operation-local progress for actions so unrelated work remains available; never present pending or failed data as an empty or successful result.
|
|
- Avoid unexpected layout shifts and blocking interactions.
|
|
|
|
### Accessibility
|
|
|
|
- Use semantic HTML before adding ARIA attributes.
|
|
- Use native buttons and links for interactive actions.
|
|
- Ensure all interactive elements are keyboard accessible.
|
|
- Associate form controls with visible or accessible labels.
|
|
- Preserve visible focus indicators.
|
|
- Provide alternative text for meaningful images.
|
|
- Ensure dialogs and overlays manage focus correctly.
|
|
- Do not communicate status or errors through color alone.
|
|
|
|
### Angular testing
|
|
|
|
- Test observable behavior rather than implementation details.
|
|
- Add unit tests for components, services, pipes, guards, and utilities when their behavior changes.
|
|
- Cover important form validation and error states.
|
|
- Mock network boundaries rather than internal implementation details.
|
|
- Add integration or end-to-end coverage for critical user journeys when appropriate.
|
|
|
|
## Backend: Java and Spring Boot
|
|
|
|
### Structure and responsibilities
|
|
|
|
- Keep controllers thin.
|
|
- Controllers should handle HTTP concerns, input validation, authentication context, and response mapping.
|
|
- Put application and business logic in dedicated services or use-case classes.
|
|
- Keep persistence logic in repositories.
|
|
- Do not expose persistence entities directly through public APIs.
|
|
- Use dedicated request and response DTOs at API boundaries.
|
|
- Keep mapping logic explicit and testable.
|
|
- Organize code by domain or feature where possible.
|
|
- Avoid utility classes that accumulate unrelated behavior.
|
|
|
|
### Java practices
|
|
|
|
- Follow the Java version and conventions already configured in the repository.
|
|
- Prefer constructor injection over field injection.
|
|
- Make dependencies explicit and immutable where possible.
|
|
- Use descriptive names and small methods.
|
|
- Avoid deeply nested conditionals; use guard clauses where they improve clarity.
|
|
- Prefer domain-specific types over primitive strings and numbers for important concepts.
|
|
- Use records for immutable data carriers when supported by the project.
|
|
- Use enums for finite domain states.
|
|
- Do not use `Optional` for entity fields, method parameters, or collection elements.
|
|
- Return empty collections instead of `null`.
|
|
- Do not catch broad exceptions unless they are rethrown, translated, or handled meaningfully.
|
|
- Do not silently ignore exceptions.
|
|
|
|
### Spring Boot practices
|
|
|
|
- Use constructor-based dependency injection.
|
|
- Keep configuration externalized through Spring configuration properties.
|
|
- Use typed `@ConfigurationProperties` instead of scattering `@Value` annotations.
|
|
- Keep environment-specific values outside source code.
|
|
- Use profiles only for genuine environment differences.
|
|
- Avoid circular dependencies.
|
|
- Do not use static access to Spring-managed services.
|
|
- Use framework annotations at the application boundary and keep domain code framework-independent where practical.
|
|
|
|
### API design
|
|
|
|
- Follow the repository's existing REST conventions.
|
|
- Use nouns for resource paths and standard HTTP methods.
|
|
- Return appropriate HTTP status codes.
|
|
- Keep request and response contracts coherent with the current model; replace obsolete development contracts rather than adding compatibility layers.
|
|
- Use explicit DTOs instead of generic maps.
|
|
- Validate incoming requests with Jakarta Bean Validation.
|
|
- Return consistent, structured error responses.
|
|
- Do not expose stack traces, internal class names, database details, or sensitive information.
|
|
- Document new or changed endpoints using the project's API documentation approach.
|
|
- Consider pagination for endpoints returning potentially large collections.
|
|
- Make retry-sensitive write operations idempotent when practical.
|
|
|
|
### Persistence and transactions
|
|
|
|
- Keep transaction boundaries in the service layer.
|
|
- Use `@Transactional(readOnly = true)` for read-only service operations when appropriate.
|
|
- Avoid long-running work, remote calls, or user interaction inside database transactions.
|
|
- Prevent N+1 query problems.
|
|
- Fetch only the data required for the use case.
|
|
- Use explicit database migrations for schema changes.
|
|
- Never rely on automatic schema generation in production.
|
|
- Add indexes only when supported by an identified query pattern.
|
|
- Preserve data integrity with database constraints in addition to application validation.
|
|
- Handle concurrent updates explicitly where data consistency requires it.
|
|
|
|
### Security
|
|
|
|
- Enforce authorization on the backend for every protected operation.
|
|
- Never rely on hidden frontend controls or route guards for authorization.
|
|
- Validate and sanitize untrusted input.
|
|
- Use parameterized queries or repository abstractions; never concatenate untrusted input into queries.
|
|
- Do not log passwords, access tokens, session identifiers, personal data, or sensitive request payloads.
|
|
- Store secrets in the configured secret-management or environment mechanism.
|
|
- Use least-privilege access for services and database users.
|
|
- Review new endpoints for authentication, authorization, data exposure, and abuse cases.
|
|
|
|
### Logging and observability
|
|
|
|
- Use structured, meaningful logs.
|
|
- Log identifiers needed to investigate a request without exposing sensitive data.
|
|
- Use appropriate log levels.
|
|
- Do not use `System.out` or print stack traces directly.
|
|
- Avoid duplicate logging of the same exception across multiple layers.
|
|
- Preserve exception causes when translating errors.
|
|
- Add metrics or tracing for important new workflows when the project already supports them.
|
|
|
|
### Spring Boot testing
|
|
|
|
- Add unit tests for domain and service logic.
|
|
- Use integration tests for persistence, security, serialization, transactions, and framework configuration.
|
|
- Prefer focused Spring test slices when the full application context is unnecessary.
|
|
- Use the project's established database test strategy.
|
|
- Do not depend on test execution order.
|
|
- Keep tests deterministic and isolated.
|
|
- Test success, validation failure, authorization failure, and important edge cases.
|
|
- Add regression tests for bug fixes.
|
|
|
|
## 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 for rolling upgrades or backward-compatible deployment until an explicit project decision declares production data must be preserved.
|
|
|
|
## Before finishing
|
|
|
|
- Review the full diff for unrelated changes.
|
|
- Verify that new code follows the existing architecture and naming conventions.
|
|
- Check for oversized components, classes, and methods.
|
|
- Check for duplicated logic and unnecessary abstractions.
|
|
- Run the frontend formatter, linter, type checker, and relevant tests.
|
|
- Run the backend formatter or style checks, static analysis, and relevant tests.
|
|
- Run the project build when practical.
|
|
- Verify API and database changes are reflected in tests and documentation.
|
|
- Verify loading, empty, validation, error, and authorization states.
|
|
- Confirm that no secrets, debug statements, temporary files, or generated artifacts were added.
|
|
- Summarize any command that could not be run and explain why.
|