Welcome, AI assistant. Follow these guidelines when contributing to this repository.
php artisan boost:add-skill pentiminax/ux-datatables
Save this content to: AGENTS.md
# AI Contribution Guidelines
Welcome, AI assistant. Follow these guidelines when contributing to this repository.
## Project Overview
UX DataTables is a third-party Symfony UX bundle that integrates DataTables.net with Symfony
applications. It supports client-side tables, Doctrine-backed server-side processing, Ajax actions,
optional API Platform column discovery, and optional Mercure updates.
**Requirements:** PHP 8.3+, Symfony 7.x/8.x, Symfony StimulusBundle 2.x/3.x
**PHP namespace:** `Pentiminax\UX\DataTables\` maps to `src/`
**Test namespace:** `Pentiminax\UX\DataTables\Tests\` maps to `tests/`
## General Rules
- Use American English for code, comments, documentation, commits, and branches.
- Use single quotes for PHP and TypeScript strings unless interpolation or escaping makes double
quotes clearer.
- Keep changes focused, reviewable, and backward compatible.
- Treat Ajax data and mutation endpoints as security boundaries. Preserve authorization, CSRF
validation, table-purpose validation, output escaping, and safe error handling.
- Do not assume a table token authenticates or authorizes a user. Applications must protect the
bundle's Ajax routes with their Symfony Security configuration.
- Add dependencies only when the task explicitly requires them.
- Look for an existing helper before writing one, and share it instead of keeping private copies
(for example `RowIdNormalizer`, `EnumChoices`, `ColumnTranslator`, `isRecord()` in
`assets/src/functions/htmlUtils.ts`, `postRowRequest.ts`).
### Do Not Edit Directly
- `vendor/`, any `node_modules/` directory, and `var/` are managed dependencies or runtime output.
- `docs/dist/` and `docs/.astro/` are generated by Astro.
- `assets/dist/` is generated but versioned. Change `assets/src/`, then rebuild it with
`npm run build` from `assets/`; never hand-edit compiled files or source maps.
- Update lock files only through their package manager. Keep the tracked
`assets/package-lock.json` and `docs/package-lock.json` synchronized with their
`package.json` files.
## Architecture
### Core Data Flow
```text
Twig render_datatable()
-> DataTablesExtension
-> AbstractDataTable + RenderingPreparer
-> Stimulus controller (assets/src/controller.ts)
-> DataTables.net and optional extensions
Server-side Ajax
-> DataTableRuntime + DataTableRequest
-> DataTableQueryIntent + QueryFilterPipeline
-> DataProvider
-> RowMapper / RowProcessingPipeline
-> JsonResponse
Mutations
-> Ajax controller
-> CSRF + permission + table-purpose checks
-> EntityMutator
-> optional Mercure publication
```
Client-side tables embed prepared row data in the rendered configuration. Server-side tables fetch
rows through Ajax and apply pagination, search, and ordering through the query pipeline.
### Main Boundaries
- **User configuration** (`src/Model/`, `src/Column/`, `src/Filter/`): `AbstractDataTable` and fluent
column, filter, action, and extension APIs are the primary user-facing surface.
- **Contracts** (`src/Contracts/`): extension points for data providers, row mapping, query filters,
columns, and integrations.
- **Runtime and Ajax** (`src/Runtime/`, `src/Controller/`, `src/Ajax/`): table initialization,
rendering state, requests, responses, and registered-table validation.
- **Query processing** (`src/Query/`, `src/DataProvider/`): request intent creation, filters, search
strategies, Doctrine queries, and in-memory data.
- **Rendering** (`src/RowMapper/`, `templates/`): row stages, Twig rendering, and modal templates.
Payload preparation lives in `src/Runtime/RenderingPreparer.php`.
- **Optional integrations** (`src/ApiPlatform/`, `src/Mercure/`, `src/Maker/`): keep optional
dependencies isolated and guard their use with availability checks.
- **Frontend** (`assets/src/`): the Stimulus controller, renderers, modal adapters, style adapters,
and lazy-loaded DataTables.net extensions.
### Public API and Backward Compatibility
Treat documented entry points and downstream-consumed behavior as public contracts. This includes
interfaces in `src/Contracts/`, `AbstractDataTable`, fluent builders, columns, filters, extensions,
attributes, Ajax routes, Twig functions, serialized frontend options, and published JavaScript
imports.
- Prefer additive, backward-compatible changes.
- Deprecate an existing path before removing it, and document its replacement. Tag it
`@deprecated since X.Y, use Z instead. Removed in 2.0.` in PHP and TypeScript, where X.Y is the
first release that ships the deprecation (check the last tag with `git show <tag>:<path>`), and
keep the deprecated export covered by a test until 2.0.
- Do not expose internal runtime objects or implementation details through user configuration.
- Keep fluent configuration consistent: static `new()` factories where established and chainable
methods returning `static`.
- Consider payload shape and generated JavaScript exports when changing PHP or TypeScript APIs.
## Commands
Use the repository manifests and CI workflows as the source of truth.
### Setup
```bash
composer install
cd assets
npm install
cd ../docs
npm ci
```
### PHP
```bash
composer audit
composer fix
vendor/bin/phpunit
vendor/bin/phpunit tests/Unit/Path/To/TestFile.php
vendor/bin/phpunit --filter=test_name
```
`composer fix` rewrites PHP files. Review its diff before committing.
### Frontend
Run from `assets/`:
```bash
npm run lint
npm run typecheck
npm test
npm run build
```
### Documentation
Run from `docs/`:
```bash
npm run lint
npm run build
```
### Before Creating a Pull Request
Run the relevant checks for every changed area:
| Changed area | Required checks |
| --- | --- |
| PHP source, config, or tests | `composer fix`, `composer audit`, `vendor/bin/phpunit` |
| TypeScript or frontend tests | `npm run lint`, `npm run typecheck`, `npm test`, `npm run build` in `assets/` |
| Twig templates or serialized payloads | Relevant PHPUnit tests and affected frontend tests |
| Translations | Keep English and French catalog keys synchronized; run relevant tests |
| Astro/MDX documentation | `npm run lint`, `npm run build` in `docs/` |
| Contribution documentation | `git diff --check` and a manual diff review |
## PHP Code Standards
PHP-CS-Fixer (`.php-cs-fixer.dist.php`) is the formatting source of truth. Its rules include PSR-12,
Symfony conventions, strict types, single quotes, ordered imports, native function invocation, and
snake_case PHPUnit method names.
- Add `declare(strict_types=1);` to PHP files.
- Use PHP 8.3+ syntax and native types. Prefer constructor property promotion where it improves
clarity.
- Register bundle services explicitly in PHP configuration files; do not introduce implicit
autowiring assumptions.
- Prefer enums over groups of constants for closed sets of values.
- Return or throw early instead of nesting control flow.
- Handle exceptions explicitly; never add silent catches.
- Start exception messages with a capital letter and end them with a period.
- Prefer clear, self-explanatory code over long explanatory comments: make the behavior obvious
through names and structure, and keep a comment only for a non-obvious constraint or decision.
Do not use comments as section separators. Keep docblocks to a line or two, and mark internal
methods with a bare `@internal` instead of naming their callers, which go stale.
- Keep properties before methods, then order methods public, protected, and private.
- Use PHPDoc for useful generic, iterable, array-shape, or behavioral information; avoid repeating
native type declarations.
## TypeScript and Frontend Standards
Biome (`assets/biome.json`) is the frontend formatting and linting source of truth.
- Use TypeScript and ES modules.
- Use 4-space indentation, single quotes, no semicolons, ES5 trailing commas, and a 100-character
line width.
- Use `camelCase` for variables and functions and `UpperCamelCase` for classes and types.
- Prefer clear, self-explanatory code over long explanatory comments, as in the PHP standards: keep
a comment only for a non-obvious constraint or decision.
- Keep optional DataTables.net extensions lazy-loaded.
- Preserve the adapter boundaries for modal and column-style implementations.
- Add or update Vitest coverage for behavior changes.
- Rebuild and commit `assets/dist/` whenever published frontend source changes.
## Twig and Translations
- Keep Twig auto-escaping enabled. Use raw HTML only when the value is intentionally trusted and
already sanitized by the relevant rendering boundary.
- Use semantic HTML, labels, and appropriate `aria-*` attributes for interactive controls.
- Reuse existing modal and collector templates before adding new variants.
- Put user-facing bundle text in the translation catalogs instead of hardcoding it.
- Keep `translations/DataTables.en.xlf` and `translations/DataTables.fr.xlf` keys aligned. Use
English as a temporary value when a French translation is not yet available.
## Documentation
Documentation lives in `docs/` and uses Astro with MDX.
- Write concise American English for an international audience.
- Prefer realistic Symfony and DataTables examples over placeholder code.
- Include imports and relevant configuration context in code examples.
- Keep security-sensitive examples aligned with the documented Ajax route protections.
- Let ESLint and Prettier enforce the documentation style.
## Git and Pull Requests
- Keep commits small and focused on one decision.
- Follow the repository's Lore Commit Protocol: lead with intent and record meaningful constraints,
rejected alternatives, confidence, scope risk, directives, and verification in trailers.
- Document completed checks with `Tested:` and any known gaps with `Not-tested:`.
- Do not introduce a project-specific branch naming scheme in this file.
Welcome, AI assistant. Follow these guidelines when contributing to this repository.
UX DataTables is a third-party Symfony UX bundle that integrates DataTables.net with Symfony applications. It supports client-side tables, Doctrine-backed server-side processing, Ajax actions, optional API Platform column discovery, and optional Mercure updates.
Requirements: PHP 8.3+, Symfony 7.x/8.x, Symfony StimulusBundle 2.x/3.x
PHP namespace: Pentiminax\UX\DataTables\ maps to src/
Test namespace: Pentiminax\UX\DataTables\Tests\ maps to tests/
RowIdNormalizer, EnumChoices, ColumnTranslator, isRecord() in
assets/src/functions/htmlUtils.ts, postRowRequest.ts).vendor/, any node_modules/ directory, and var/ are managed dependencies or runtime output.docs/dist/ and docs/.astro/ are generated by Astro.assets/dist/ is generated but versioned. Change assets/src/, then rebuild it with
npm run build from assets/; never hand-edit compiled files or source maps.assets/package-lock.json and docs/package-lock.json synchronized with their
package.json files.Twig render_datatable()
-> DataTablesExtension
-> AbstractDataTable + RenderingPreparer
-> Stimulus controller (assets/src/controller.ts)
-> DataTables.net and optional extensions
Server-side Ajax
-> DataTableRuntime + DataTableRequest
-> DataTableQueryIntent + QueryFilterPipeline
-> DataProvider
-> RowMapper / RowProcessingPipeline
-> JsonResponse
Mutations
-> Ajax controller
-> CSRF + permission + table-purpose checks
-> EntityMutator
-> optional Mercure publication
Client-side tables embed prepared row data in the rendered configuration. Server-side tables fetch rows through Ajax and apply pagination, search, and ordering through the query pipeline.
src/Model/, src/Column/, src/Filter/): AbstractDataTable and fluent
column, filter, action, and extension APIs are the primary user-facing surface.src/Contracts/): extension points for data providers, row mapping, query filters,
columns, and integrations.src/Runtime/, src/Controller/, src/Ajax/): table initialization,
rendering state, requests, responses, and registered-table validation.src/Query/, src/DataProvider/): request intent creation, filters, search
strategies, Doctrine queries, and in-memory data.src/RowMapper/, templates/): row stages, Twig rendering, and modal templates.
Payload preparation lives in src/Runtime/RenderingPreparer.php.src/ApiPlatform/, src/Mercure/, src/Maker/): keep optional
dependencies isolated and guard their use with availability checks.assets/src/): the Stimulus controller, renderers, modal adapters, style adapters,
and lazy-loaded DataTables.net extensions.Treat documented entry points and downstream-consumed behavior as public contracts. This includes
interfaces in src/Contracts/, AbstractDataTable, fluent builders, columns, filters, extensions,
attributes, Ajax routes, Twig functions, serialized frontend options, and published JavaScript
imports.
@deprecated since X.Y, use Z instead. Removed in 2.0. in PHP and TypeScript, where X.Y is the
first release that ships the deprecation (check the last tag with git show <tag>:<path>), and
keep the deprecated export covered by a test until 2.0.new() factories where established and chainable
methods returning static.Use the repository manifests and CI workflows as the source of truth.
composer install
cd assets
npm install
cd ../docs
npm ci
composer audit
composer fix
vendor/bin/phpunit
vendor/bin/phpunit tests/Unit/Path/To/TestFile.php
vendor/bin/phpunit --filter=test_name
composer fix rewrites PHP files. Review its diff before committing.
Run from assets/:
npm run lint
npm run typecheck
npm test
npm run build
Run from docs/:
npm run lint
npm run build
Run the relevant checks for every changed area:
| Changed area | Required checks |
|---|---|
| PHP source, config, or tests | composer fix, composer audit, vendor/bin/phpunit |
| TypeScript or frontend tests | npm run lint, npm run typecheck, npm test, npm run build in assets/ |
| Twig templates or serialized payloads | Relevant PHPUnit tests and affected frontend tests |
| Translations | Keep English and French catalog keys synchronized; run relevant tests |
| Astro/MDX documentation | npm run lint, npm run build in docs/ |
| Contribution documentation | git diff --check and a manual diff review |
PHP-CS-Fixer (.php-cs-fixer.dist.php) is the formatting source of truth. Its rules include PSR-12,
Symfony conventions, strict types, single quotes, ordered imports, native function invocation, and
snake_case PHPUnit method names.
declare(strict_types=1); to PHP files.@internal instead of naming their callers, which go stale.Biome (assets/biome.json) is the frontend formatting and linting source of truth.
camelCase for variables and functions and UpperCamelCase for classes and types.assets/dist/ whenever published frontend source changes.aria-* attributes for interactive controls.translations/DataTables.en.xlf and translations/DataTables.fr.xlf keys aligned. Use
English as a temporary value when a French translation is not yet available.Documentation lives in docs/ and uses Astro with MDX.
Tested: and any known gaps with Not-tested:.How can I help you explore Laravel packages today?