Complete PrestaShop module development workflow using modern architecture and best practices. Use when: creating new PrestaShop modules, updating legacy modules to modern code, implementing hooks and actions, setting up module configuration pages, adding front office features, handling database operations…
Create the PHP feature context class that implements step definitions for a domain, and register it in behat.yml. Covers the PHP implementation side of Behat tests. Trigger: "create behat context for {Domain}".
Write the Gherkin feature file and all scenarios for a domain: CRUD, bulk actions, filters, and error cases. Covers the .feature file side of Behat tests. Read Component/Behat/CONTEXT.md for conventions. Trigger: "write behat scenarios for {Domain}".
Create bulk action commands and their handlers. All bulk handlers extend AbstractBulkCommandHandler, catch errors per item, and report failures via BulkCommandExceptionInterface. Trigger: "create bulk commands for {Domain}".
Set up the full domain layer for a CQRS entity: identity value object, additional value objects, exception hierarchy, commands (Add, Edit, Delete, Toggle, sub-resource, or any custom domain action), and handler interfaces. Covers everything in src/Core/Domain/{Domain}/. Trigger: "create CQRS commands for {Domain}"…
Create the read-side CQRS layer: queries, result DTOs, and query handler interfaces. Covers Get{Domain}ForEditing (single entity for edit form) and optionally Get{Domain}sForListing (grid data source). Trigger: "create queries for {Domain}", "set up read side for {Domain}".
Create the repository in the Adapter layer. This is the ONLY class that touches the database — all handlers delegate to it. Covers multistore patterns with ShopConstraint when the entity requires it. Trigger: "create repository for {Domain}".
Implement all command and query handlers in the Adapter layer. Each handler delegates to the repository for persistence — no direct SQL or ObjectModel access. Handlers use #[AsCommandHandler] / #[AsQueryHandler] attributes for auto-registration. Trigger: "implement handlers for {Domain}".
Register all domain handlers and the repository in the Symfony DI container. Handlers are auto-discovered via #[AsCommandHandler] / #[AsQueryHandler] attributes. Trigger: "register CQRS services for {Domain}".
Create the form page actions in the admin controller: create (add) and edit, plus any entity-specific actions. Uses FormBuilder/FormHandler pattern — never builds commands directly. Trigger: "create form actions for {Domain}", "create add/edit for {Domain}".
Create the listing page actions in the admin controller: index (grid with filters), delete, toggle status, and any bulk actions the entity requires. Trigger: "create listing for {Domain}", "create index action for {Domain}".
Register the domain's feature flag in featureflag.xml. This entry populates the psfeatureflag table at install/upgrade and enables the flag-based routing between legacy and Symfony controllers.
Create the form data flow layer: DataProvider (loads entity data for edit form), DataHandler (dispatches commands on create/update), error handling, and service registration. This bridges the form layer with the CQRS layer. Read Component/Forms/CONTEXT.md for conventions. Trigger: "create form data handling for…
Create a multi-tab form layout using PrestaShop's NavigationTabType. This is a specific pattern for complex forms with many fields organized by tabs — NOT the default form layout. Most forms do not need tabs. Trigger: "create tab layout for {Domain} form", "add tabs to {Domain} form".
Create the Symfony form type for an entity's add/edit form. Covers standard field types, translatable fields, money fields, file uploads, and choice providers. For multi-tab layout with NavigationTabType, see create-form-tab-layout. Trigger: "create form type for {Domain}".
Create the grid definition for an entity listing: columns, row actions, bulk actions, filters class, and service registration. Covers everything needed to define the grid structure. The query builder is a separate skill (create-grid-query-builder). Trigger: "create grid definition for {Domain}".
Create the Doctrine DBAL QueryBuilder that fetches grid rows, and optionally a GridDataFactory decorator for post-processing. The column aliases must exactly match the column IDs in the Grid Definition. Trigger: "create grid query builder for {Domain}".
Documents how to add drag-and-drop row reordering to a PrestaShop grid. Requires a PositionColumn in the definition, a dedicated update-position route, and position handling in the repository.
Create the TypeScript entry point files for a new admin page. Covers the directory structure, listing and form entry points, and webpack registration. References init-js-components and init-grid-extensions for component/extension details. Trigger: "create JS entry point for {Domain}".
Integrate a Vue 3 component into a Symfony admin page for complex UX sections. This is an exception pattern — most pages use initComponents with standard components. Vue is only needed when a section requires rich interactivity that standard form types cannot provide (e.g. combination listing, dynamic range tables).…
Enable JavaScript grid extensions for a listing page. Extensions add sorting, filtering, bulk actions, column toggling, position reordering, and other interactive behaviors to the grid. Trigger: "add grid extensions for {Domain}", "enable grid extensions for {Domain}", "initialize grid JS for {Domain}".
Initialize and use PrestaShop's global JS components via initComponents(). Covers TranslatableInput, ChoiceTree, TinyMCEEditor, TaggableField, and all other available components. Components activate based on data- attributes in the DOM. Trigger: "initialize components for {Domain}", "enable components for {Domain}"…