Skip to content

Commit aa74ebf

Browse files
committed
base of ai structure and contexes
1 parent 2c43de1 commit aa74ebf

File tree

100 files changed

+5602
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+5602
-0
lines changed

.ai/CONTEXT.md

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
# PrestaShop — AI Context (Root)
2+
3+
> For folder structure and navigation, see [STRUCTURE.md](STRUCTURE.md).
4+
> For cross-domain naming traps and identity gotchas, see [GOTCHAS.md](GOTCHAS.md).
5+
> For multi-store scoping (ShopConstraint, AbstractMultistoreConfiguration), see [MULTISTORE.md](MULTISTORE.md).
6+
7+
## Project overview
8+
9+
PrestaShop is an open-source e-commerce platform built on Symfony. It follows a progressive migration from a legacy architecture (ObjectModel, legacy controllers) toward a modern Domain-Driven Design approach (CQRS, Symfony controllers, Doctrine).
10+
11+
## Architecture layers
12+
13+
| Layer | Location | Role |
14+
|-------|----------|------|
15+
| Core Domain | `src/Core/Domain/` | Business logic: Commands, Queries, Handlers, ValueObjects, Exceptions |
16+
| Core Components | `src/Core/` (non-Domain) | Shared infrastructure: Grid, Form, Hook, Translation, etc. |
17+
| Adapter | `src/Adapter/` | Bridges between Core and legacy code or external systems |
18+
| PrestaShopBundle | `src/PrestaShopBundle/` | Symfony bundle: controllers, form types, Twig extensions, DI config |
19+
| Legacy | `classes/`, `controllers/` | Legacy ObjectModel classes and controllers — do not extend, migrate instead |
20+
| Admin front-end | `admin-dev/themes/new-theme/` | Back-office UI: Vue.js components, JavaScript, SCSS |
21+
| Front-office themes | `themes/` | Customer-facing Smarty templates |
22+
| Modules | `modules/` | Native and third-party modules |
23+
| Tests | `tests/` | PHPUnit (unit/integration), Behat (behavior), Playwright (UI) |
24+
25+
## Coding standards
26+
27+
- Every PHP file: `declare(strict_types=1);`
28+
- Classes `final` by default; all parameters, return types, and properties must be typed
29+
- No ObjectModel in new code — use Doctrine entities or CQRS commands
30+
- All services defined in YAML; no `new` in controllers
31+
- No `Db::getInstance()` in new code — use Doctrine repositories
32+
- No business logic in controllers — delegate to Handlers
33+
- Catch specific domain exceptions, not generic `\Exception`
34+
35+
## CQRS pattern
36+
37+
- **Commands** — write intentions dispatched via `CommandBus`
38+
- **Queries** — read intentions dispatched via `QueryBus`
39+
- **Handlers** — implement logic; never call other handlers (compose at controller level)
40+
- Handler interfaces in `src/Core/Domain/{Domain}/CommandHandler|QueryHandler/`
41+
- Concrete implementations in `src/Adapter/{Domain}/CommandHandler|QueryHandler/`
42+
43+
## Testing
44+
45+
| Type | Framework | Location |
46+
|------|-----------|----------|
47+
| Unit | PHPUnit | `tests/Unit/` |
48+
| Integration | PHPUnit | `tests/Integration/` |
49+
| Behavior | Behat | `tests/Integration/Behaviour/` |
50+
| UI | Playwright | `tests/UI/` |
51+
52+
## Skills
53+
54+
| Skill | Path | Trigger |
55+
|-------|------|---------|
56+
| `create-skill` | [skills/create-skill/SKILL.md](skills/create-skill/SKILL.md) | "create a skill for …" |
57+
| `domain-context-generator` | [skills/domain-context-generator/SKILL.md](skills/domain-context-generator/SKILL.md) | "generate context for [Domain]" |
58+
| `component-context-generator` | [skills/component-context-generator/SKILL.md](skills/component-context-generator/SKILL.md) | "generate context for [Component]" |
59+
| `create-form` | [skills/create-form/SKILL.md](skills/create-form/SKILL.md) | "create a form for [Entity]" |
60+
61+
## Domain contexts
62+
63+
All 57 domains under `src/Core/Domain/` have a context file. Read the relevant one before working in a domain.
64+
65+
| Domain | Context |
66+
|--------|---------|
67+
| Address | [Domain/Address/CONTEXT.md](Domain/Address/CONTEXT.md) |
68+
| Alias | [Domain/Alias/CONTEXT.md](Domain/Alias/CONTEXT.md) |
69+
| ApiClient | [Domain/ApiClient/CONTEXT.md](Domain/ApiClient/CONTEXT.md) |
70+
| Attachment | [Domain/Attachment/CONTEXT.md](Domain/Attachment/CONTEXT.md) |
71+
| AttributeGroup | [Domain/AttributeGroup/CONTEXT.md](Domain/AttributeGroup/CONTEXT.md) |
72+
| Carrier | [Domain/Carrier/CONTEXT.md](Domain/Carrier/CONTEXT.md) |
73+
| Cart | [Domain/Cart/CONTEXT.md](Domain/Cart/CONTEXT.md) |
74+
| CartRule | [Domain/CartRule/CONTEXT.md](Domain/CartRule/CONTEXT.md) |
75+
| CatalogPriceRule | [Domain/CatalogPriceRule/CONTEXT.md](Domain/CatalogPriceRule/CONTEXT.md) |
76+
| Category | [Domain/Category/CONTEXT.md](Domain/Category/CONTEXT.md) |
77+
| CmsPage | [Domain/CmsPage/CONTEXT.md](Domain/CmsPage/CONTEXT.md) |
78+
| CmsPageCategory | [Domain/CmsPageCategory/CONTEXT.md](Domain/CmsPageCategory/CONTEXT.md) |
79+
| Combination | [Domain/Combination/CONTEXT.md](Domain/Combination/CONTEXT.md) — code lives under `src/Core/Domain/Product/Combination/`, not a standalone domain |
80+
| Configuration | [Domain/Configuration/CONTEXT.md](Domain/Configuration/CONTEXT.md) |
81+
| Contact | [Domain/Contact/CONTEXT.md](Domain/Contact/CONTEXT.md) |
82+
| Country | [Domain/Country/CONTEXT.md](Domain/Country/CONTEXT.md) |
83+
| CreditSlip | [Domain/CreditSlip/CONTEXT.md](Domain/CreditSlip/CONTEXT.md) |
84+
| Currency | [Domain/Currency/CONTEXT.md](Domain/Currency/CONTEXT.md) |
85+
| Customer | [Domain/Customer/CONTEXT.md](Domain/Customer/CONTEXT.md) |
86+
| CustomerMessage | [Domain/CustomerMessage/CONTEXT.md](Domain/CustomerMessage/CONTEXT.md) |
87+
| CustomerService | [Domain/CustomerService/CONTEXT.md](Domain/CustomerService/CONTEXT.md) |
88+
| Discount | [Domain/Discount/CONTEXT.md](Domain/Discount/CONTEXT.md) |
89+
| Employee | [Domain/Employee/CONTEXT.md](Domain/Employee/CONTEXT.md) |
90+
| Feature | [Domain/Feature/CONTEXT.md](Domain/Feature/CONTEXT.md) |
91+
| Hook | [Domain/Hook/CONTEXT.md](Domain/Hook/CONTEXT.md) |
92+
| ImageSettings | [Domain/ImageSettings/CONTEXT.md](Domain/ImageSettings/CONTEXT.md) |
93+
| Language | [Domain/Language/CONTEXT.md](Domain/Language/CONTEXT.md) |
94+
| MailTemplate | [Domain/MailTemplate/CONTEXT.md](Domain/MailTemplate/CONTEXT.md) |
95+
| Manufacturer | [Domain/Manufacturer/CONTEXT.md](Domain/Manufacturer/CONTEXT.md) |
96+
| Meta | [Domain/Meta/CONTEXT.md](Domain/Meta/CONTEXT.md) |
97+
| Module | [Domain/Module/CONTEXT.md](Domain/Module/CONTEXT.md) |
98+
| Notification | [Domain/Notification/CONTEXT.md](Domain/Notification/CONTEXT.md) |
99+
| Order | [Domain/Order/CONTEXT.md](Domain/Order/CONTEXT.md) |
100+
| OrderMessage | [Domain/OrderMessage/CONTEXT.md](Domain/OrderMessage/CONTEXT.md) |
101+
| OrderReturn | [Domain/OrderReturn/CONTEXT.md](Domain/OrderReturn/CONTEXT.md) |
102+
| OrderReturnState | [Domain/OrderReturnState/CONTEXT.md](Domain/OrderReturnState/CONTEXT.md) |
103+
| OrderState | [Domain/OrderState/CONTEXT.md](Domain/OrderState/CONTEXT.md) |
104+
| Position | [Domain/Position/CONTEXT.md](Domain/Position/CONTEXT.md) |
105+
| Product | [Domain/Product/CONTEXT.md](Domain/Product/CONTEXT.md) |
106+
| Profile | [Domain/Profile/CONTEXT.md](Domain/Profile/CONTEXT.md) |
107+
| Search | [Domain/Search/CONTEXT.md](Domain/Search/CONTEXT.md) |
108+
| SearchEngine | [Domain/SearchEngine/CONTEXT.md](Domain/SearchEngine/CONTEXT.md) |
109+
| Security | [Domain/Security/CONTEXT.md](Domain/Security/CONTEXT.md) |
110+
| Shipment | [Domain/Shipment/CONTEXT.md](Domain/Shipment/CONTEXT.md) |
111+
| Shop | [Domain/Shop/CONTEXT.md](Domain/Shop/CONTEXT.md) |
112+
| ShowcaseCard | [Domain/ShowcaseCard/CONTEXT.md](Domain/ShowcaseCard/CONTEXT.md) |
113+
| SqlManagement | [Domain/SqlManagement/CONTEXT.md](Domain/SqlManagement/CONTEXT.md) |
114+
| State | [Domain/State/CONTEXT.md](Domain/State/CONTEXT.md) |
115+
| Store | [Domain/Store/CONTEXT.md](Domain/Store/CONTEXT.md) |
116+
| Supplier | [Domain/Supplier/CONTEXT.md](Domain/Supplier/CONTEXT.md) |
117+
| Tab | [Domain/Tab/CONTEXT.md](Domain/Tab/CONTEXT.md) |
118+
| Tag | [Domain/Tag/CONTEXT.md](Domain/Tag/CONTEXT.md) |
119+
| Tax | [Domain/Tax/CONTEXT.md](Domain/Tax/CONTEXT.md) |
120+
| TaxRulesGroup | [Domain/TaxRulesGroup/CONTEXT.md](Domain/TaxRulesGroup/CONTEXT.md) |
121+
| Theme | [Domain/Theme/CONTEXT.md](Domain/Theme/CONTEXT.md) |
122+
| Title | [Domain/Title/CONTEXT.md](Domain/Title/CONTEXT.md) |
123+
| Webservice | [Domain/Webservice/CONTEXT.md](Domain/Webservice/CONTEXT.md) |
124+
| Zone | [Domain/Zone/CONTEXT.md](Domain/Zone/CONTEXT.md) |
125+
126+
## Component contexts
127+
128+
All 22 shared infrastructure components have a context file.
129+
130+
| Component | Context |
131+
|-----------|---------|
132+
| BackOfficeHelp | [Component/BackOfficeHelp/CONTEXT.md](Component/BackOfficeHelp/CONTEXT.md) |
133+
| Configuration | [Component/Configuration/CONTEXT.md](Component/Configuration/CONTEXT.md) |
134+
| Console | [Component/Console/CONTEXT.md](Component/Console/CONTEXT.md) |
135+
| Context | [Component/Context/CONTEXT.md](Component/Context/CONTEXT.md) |
136+
| Cookie | [Component/Cookie/CONTEXT.md](Component/Cookie/CONTEXT.md) |
137+
| CQRS | [Component/CQRS/CONTEXT.md](Component/CQRS/CONTEXT.md) |
138+
| Database | [Component/Database/CONTEXT.md](Component/Database/CONTEXT.md) |
139+
| Export | [Component/Export/CONTEXT.md](Component/Export/CONTEXT.md) |
140+
| FacetedSearch | [Component/FacetedSearch/CONTEXT.md](Component/FacetedSearch/CONTEXT.md) |
141+
| Forms | [Component/Forms/CONTEXT.md](Component/Forms/CONTEXT.md) |
142+
| GlobalJS | [Component/GlobalJS/CONTEXT.md](Component/GlobalJS/CONTEXT.md) |
143+
| Grid | [Component/Grid/CONTEXT.md](Component/Grid/CONTEXT.md) |
144+
| Hook | [Component/Hook/CONTEXT.md](Component/Hook/CONTEXT.md) |
145+
| Import | [Component/Import/CONTEXT.md](Component/Import/CONTEXT.md) |
146+
| Link | [Component/Link/CONTEXT.md](Component/Link/CONTEXT.md) |
147+
| Locale | [Component/Locale/CONTEXT.md](Component/Locale/CONTEXT.md) |
148+
| MailTemplate | [Component/MailTemplate/CONTEXT.md](Component/MailTemplate/CONTEXT.md) |
149+
| PositionUpdater | [Component/PositionUpdater/CONTEXT.md](Component/PositionUpdater/CONTEXT.md) |
150+
| Router | [Component/Router/CONTEXT.md](Component/Router/CONTEXT.md) |
151+
| Smarty | [Component/Smarty/CONTEXT.md](Component/Smarty/CONTEXT.md) |
152+
| TinyMCE | [Component/TinyMCE/CONTEXT.md](Component/TinyMCE/CONTEXT.md) |
153+
| Twig | [Component/Twig/CONTEXT.md](Component/Twig/CONTEXT.md) |
154+
155+
## Generated indexes
156+
157+
Regenerate with `bash bin/generate-ai-index.sh`. **Read these before grepping** — they are pre-built snapshots faster than filesystem searches. **Regenerate after:** adding Commands/Queries, adding routes, adding hooks, or merging domain changes.
158+
159+
| File | Contents | When to use |
160+
|------|----------|-------------|
161+
| [generated/cqrs.md](generated/cqrs.md) | All Commands + Queries grouped by domain | Before adding a Command/Query — check it doesn't already exist |
162+
| [generated/routes.md](generated/routes.md) | Symfony admin/API routes | Before adding a route or looking up a controller action |
163+
| [generated/entities.md](generated/entities.md) | Doctrine entity columns and relations | Before writing a query or migration |
164+
| [generated/hooks.md](generated/hooks.md) | Hook names discovered in source | Before dispatching or listening to a hook |
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# BackOfficeHelp Component
2+
3+
## Purpose
4+
5+
Generates contextual documentation links for the back-office sidebar help panel pointing to the PrestaShop DevDocs for the current page and language. Does not provide inline tooltips or help text.
6+
7+
## Layers
8+
9+
| Layer | Path |
10+
|-------|------|
11+
| Core | `src/Core/Help/``Documentation` class builds versioned doc URLs |
12+
| Adapter | `src/Adapter/Shop/Url/HelpProvider.php` — wraps `Documentation` with runtime context |
13+
| Twig | `src/PrestaShopBundle/Twig/Extension/DocumentationLinkExtension.php` — exposes links to templates |
14+
15+
## Non-obvious patterns
16+
17+
- `Documentation` is a plain concrete class with no interface — not the usual Core pattern
18+
- `HelpProvider` implements `UrlProviderInterface`, not a help-specific contract
19+
20+
## Canonical examples
21+
22+
- `src/Core/Help/Documentation.php`
23+
24+
## Related
25+
26+
- [Router Component](../Router/CONTEXT.md)`HelpProvider` uses the router for sidebar URLs
27+
- [Context Component](../Context/CONTEXT.md) — language ISO code comes from `LanguageContext`

.ai/Component/CQRS/CONTEXT.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# CQRS Component
2+
3+
## Purpose
4+
5+
Command Bus and Query Bus infrastructure (built on Symfony Messenger) that decouples controllers from business logic. Does not define any business commands or queries — those live in each domain's `Command/` and `Query/` directories.
6+
7+
## Layers
8+
9+
| Layer | Path |
10+
|-------|------|
11+
| Bus interface | `src/Core/CommandBus/CommandBusInterface.php` |
12+
| Handler attributes + compiler pass | `src/PrestaShopBundle/DependencyInjection/Compiler/CommandAndQueryRegisterPass.php` |
13+
| Domain interfaces (per domain) | `src/Core/Domain/{Domain}/CommandHandler/` + `QueryHandler/` |
14+
| Concrete handlers (per domain) | `src/Adapter/{Domain}/CommandHandler/` + `QueryHandler/` |
15+
16+
## Non-obvious patterns
17+
18+
- Both buses share the same `CommandBusInterface` — differentiated only by the message type passed, not separate interfaces
19+
- `#[AsCommandHandler]` / `#[AsQueryHandler]` attributes on adapter classes auto-register via the compiler pass; it infers the handled message type from the handler method's first parameter type hint
20+
- Grid query builders are **not** dispatched through the bus — they query the DB directly
21+
- `ExecutedCommandRegistry` tracks all dispatched commands with backtraces in debug mode
22+
23+
## Canonical examples
24+
25+
- `src/Core/CommandBus/CommandBusInterface.php`
26+
- `src/Adapter/Hook/CommandHandler/UpdateHookStatusCommandHandler.php`
27+
- `src/PrestaShopBundle/Controller/Admin/PrestaShopAdminController.php``dispatchCommand()` / `dispatchQuery()` helpers
28+
29+
## Related
30+
31+
- [Forms Component](../Forms/CONTEXT.md)`FormDataHandler` implementations dispatch commands via `CommandBusInterface`
32+
- [Grid Component](../Grid/CONTEXT.md) — grids dispatch queries for data fetching
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Configuration Component
2+
3+
## Purpose
4+
5+
Typed, multi-store-aware abstraction over PrestaShop's key-value configuration store (`ps_configuration`). Handles reading and writing shop settings across all-shops, shop-group, and single-shop scopes. Does not manage Symfony container parameters.
6+
7+
## Layers
8+
9+
| Layer | Path |
10+
|-------|------|
11+
| Core contracts | `src/Core/Configuration/``DataConfigurationInterface`, `AbstractMultistoreConfiguration`, `IniConfiguration`, `UploadSizeConfiguration` |
12+
| Adapter | `src/Adapter/Configuration.php` — main adapter wrapping legacy `Configuration` ObjectModel |
13+
| Domain configs | `src/Adapter/Configuration/*Configuration.php` + 20+ in `src/PrestaShopBundle/` — one per "Configure" settings page |
14+
15+
## Non-obvious patterns
16+
17+
- `AbstractMultistoreConfiguration` automatically handles per-shop override checkboxes and `ShopConstraint` scoping — extend it for any new multi-store-aware settings page
18+
- `Configuration` adapter extends `ParameterBag` and falls back to PHP constants if a key is defined as one
19+
- `DataConfigurationInterface` is the settings-page equivalent of `FormDataHandlerInterface` — every "Configure" section implements it
20+
21+
## Canonical examples
22+
23+
- `src/Core/Configuration/AbstractMultistoreConfiguration.php`
24+
- `src/Adapter/Configuration.php`
25+
26+
## Related
27+
28+
- [Context Component](../Context/CONTEXT.md)`ShopConstraint` from `ShopContext` scopes config writes
29+
- [Forms Component](../Forms/CONTEXT.md) — settings pages use `DataConfigurationInterface` instead of `FormDataHandlerInterface`

.ai/Component/Console/CONTEXT.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Console Component
2+
3+
## Purpose
4+
5+
CLI infrastructure for PrestaShop: a custom Symfony Application wrapper supporting multi-kernel execution, a base class for running commands programmatically, and 25+ concrete administrative commands. Does not handle HTTP requests.
6+
7+
## Layers
8+
9+
| Layer | Path |
10+
|-------|------|
11+
| Application wrapper | `src/PrestaShopBundle/Console/PrestaShopApplication.php` |
12+
| Programmatic runner | `src/PrestaShopBundle/Service/Command/AbstractCommand.php` |
13+
| Commands | `src/PrestaShopBundle/Command/` — 25+ commands registered via `#[AsCommand]` |
14+
15+
## Non-obvious patterns
16+
17+
- `PrestaShopApplication` adds `--app-id` to switch between kernels (`admin`, `admin_api`, `front`) at CLI level
18+
- `AbstractCommand` allows running Symfony commands **from PHP code** (not CLI) with buffered output — used by module installers and upgrade scripts
19+
20+
## Canonical examples
21+
22+
- `src/PrestaShopBundle/Console/PrestaShopApplication.php`
23+
- `src/PrestaShopBundle/Command/ModuleCommand.php`
24+
25+
## Related
26+
27+
- [CQRS Component](../CQRS/CONTEXT.md) — some commands dispatch CQRS commands via `CommandBus`

.ai/Component/Context/CONTEXT.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Context Component
2+
3+
## Purpose
4+
5+
Immutable, injectable representations of the current execution environment: active shop, language, currency, country, and authenticated employee. Replaces the legacy `Context::getContext()` singleton. Does not perform authentication or session management.
6+
7+
## Layers
8+
9+
| Layer | Path |
10+
|-------|------|
11+
| Value objects | `src/Core/Context/``ShopContext`, `LanguageContext`, `CurrencyContext`, `CountryContext`, `EmployeeContext`, `LegacyControllerContext`, `ApiClientContext` |
12+
| Builders | `src/Core/Context/*Builder.php` — one builder per context object, all implement `LegacyContextBuilderInterface` |
13+
| Subscribers | `src/PrestaShopBundle/EventListener/Admin/Context/` — populate contexts from HTTP request on each Symfony event |
14+
15+
## Non-obvious patterns
16+
17+
- All context objects are `readonly` — built once per request by subscribers, never mutated
18+
- Each builder has `buildLegacyContext()` to sync the old `Context::getContext()` global — necessary during the migration period
19+
- `LanguageContext` implements both `LanguageInterface` **and** `LocaleInterface` — it can format numbers and prices directly
20+
21+
## Canonical examples
22+
23+
- `src/Core/Context/ShopContext.php`
24+
- `src/Core/Context/ShopContextBuilder.php`
25+
26+
## Related
27+
28+
- [Configuration Component](../Configuration/CONTEXT.md)`ShopContext::getShopConstraint()` scopes config writes
29+
- [Locale Component](../Locale/CONTEXT.md)`LanguageContext` wraps `LocaleInterface` for formatting

.ai/Component/Cookie/CONTEXT.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Cookie Component
2+
3+
## Purpose
4+
5+
Encrypted HTTP cookie handling for front- and back-office: writing/reading encrypted key-value payloads, session token storage, and SameSite/Secure policy constants. Does not manage Symfony sessions — it is the lower-level transport they are stored in.
6+
7+
## Layers
8+
9+
| Layer | Path |
10+
|-------|------|
11+
| Legacy core | `classes/Cookie.php` — magic `__get`/`__set` over an encrypted payload |
12+
| Modern constants | `src/Core/Http/CookieOptions.php``SAMESITE_*` constants and `MAX_COOKIE_VALUE` |
13+
14+
## Non-obvious patterns
15+
16+
- The **entire cookie payload is encrypted** as a single string with `PhpEncryption` — there is no plain-text cookie key
17+
- `session_id` and `session_token` are stored **inside** the encrypted cookie payload, not as separate cookies
18+
- No modern DI wrapper exists — `Cookie` is still instantiated directly in legacy bootstrap
19+
20+
## Canonical examples
21+
22+
- `classes/Cookie.php`
23+
24+
## Related
25+
26+
- [Context Component](../Context/CONTEXT.md)`EmployeeContext` is built after cookie-based session validation

0 commit comments

Comments
 (0)