Add carrier endpoints#147
Conversation
| Questions | Answers | ------------- | ------------------------------------------- | Description? | Add GetRequiredFieldsForAddress CQRS endpoint | Type? | new feature | BC breaks? | no | Deprecations? | no | Fixed ticket? | N/A | Sponsor company | @PrestaShopCorp | How to test? | Ask a dev
|
Hello @luigimassa! This is your first pull request on ps_apiresources repository of the PrestaShop project. Thank you, and welcome to this Open Source community! |
Expose ToggleCarrierStatusCommand and ToggleCarrierIsFreeCommand via
PUT /carriers/{carrierId}/toggle-status and
PUT /carriers/{carrierId}/toggle-is-free endpoints with carrier_write scope.
Add integration tests for both toggle endpoints.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add BulkCarriers API resource with PUT /carriers/bulk-set-status endpoint that maps to BulkToggleCarrierStatusCommand, following the same pattern used for taxes and zones bulk status toggle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Without this constraint, passing carrierId=0 causes a CarrierConstraintException thrown during command construction (before the command bus), which bypasses the exceptionToStatus mapping and returns 500 instead of a proper error. The Assert\All([Assert\Positive()]) constraint catches invalid IDs during Symfony validation phase and returns a 400 Bad Request with details. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nd instantiation CQRSCommand/CQRSUpdate automatically sets input to the CQRS command class, causing CQRSApiNormalizer to instantiate BulkToggleCarrierStatusCommand directly during the DeserializeListener phase. This bypasses the DTO and passes raw string values from JSON to the command constructor, where (int) cast on non-numeric strings produces 0, triggering CarrierConstraintException. Setting input: BulkCarriers::class forces the deserialization to use the DTO class, letting the CommandProcessor handle command instantiation with proper type handling. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rmalizer flow Removing input: BulkCarriers::class lets CQRSCommand auto-set input to BulkToggleCarrierStatusCommand, so CQRSApiNormalizer validates BulkCarriers constraints (Assert\Positive on carrierIds) before applying CQRSCommandMapping ([enabled] -> [expectedStatus]) and instantiating the command. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Non-numeric values (e.g. strings) in carrierIds array were bypassing Assert\Positive and causing CarrierConstraintException during command instantiation, resulting in HTTP 500 instead of 422. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ping Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add DELETE /carriers/{carrierId} endpoint
| CarrierNotFoundException::class => Response::HTTP_NOT_FOUND, | ||
| ], | ||
| )] | ||
| class CarrierList |
There was a problem hiding this comment.
I think we need a test for this endpoint.
Replace individual property assertions with a single assertEquals on the entire carrier array, following the project test conventions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use property names instead of getter method names in QUERY_MAPPING, and only map properties where names differ between QueryResult and API. Remove TODO.md as it should not be committed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Claude Code — ps_apiresourcesThe conventions, architecture, and Do/Don't list for this repository When the user asks to add, expose, or wire up a new Admin API endpoint, |
📋 Summary of changesThis PR exposes the Carrier domain via the Admin API: ⏱️ Estimated review time30–40 minutes — multiple resource classes, field-mapping concerns, test coverage gaps, and a deliberately broken endpoint to evaluate. 🎯 Scope
|
📋 Summary of changesThis PR exposes the Carrier domain via the Admin API: ⏱️ Estimated review time30–40 minutes — multiple resource classes, field-mapping concerns, test coverage gaps, and a deliberately broken endpoint to evaluate. 🎯 Scope
🧱 API Platform / CQRS architecture compliance🔴 BLOCKER — `$active` must be `$enabled` (Carrier.php, CarrierList.php)
🔴 BLOCKER (CI-enforced) — `float` instead of `DecimalNumber`
🔴 BLOCKER — `QUERY_MAPPING` direction inverted in `CarrierRanges.php`The mapping currently reads:
The 🔴 MAJOR CONCERN — Shipping a deliberately non-functional endpoint
🟠 Multi-shop — `$associatedShopIds` should be `$shopIds`
🟠 Property naming — `$idTaxRuleGroup` should be `$taxRuleGroupId`
🟡 `BulkCarriers` — `$carrierIds` absent from `CQRSCommandMapping`Only 🟡 `AddressRequiredFields` — no identifier; consider `CQRSGetCollection`No 🟢 URI conventionsAll URIs are plural, lowercase, kebab-case. 🟢 Scopes
🟢 Exception mapping
🟡 `TODO.md` in ItalianThe project is English-language. Content belongs in a GitHub issue; if the file is kept, translate to English. 💡 Improvement suggestions
✅ Pre-review checklistURI & routing
Operations & scopes
API Resource properties
CQRS mapping
Forbidden practices (CI-enforced)
Exception handling & validation
Multi-shop
Listing field alignment (CarrierList)
Integration test
|
|
@luigimassa CI is red, could you have a look please? |
GET /carriers/{carrierId}/rangesthat exposes carrier shipping ranges via theGetCarrierRangesCQRS query. The response contains the list of zones, each with its price ranges (from/to/price as decimal strings). Note: This endpoint is currently non-functional due to a known limitation inCarrierRangeRepository::assertShopConstraint()(core), which only acceptsShopConstraint::allShops()while the API framework always passes a shop-specific constraint. Until the core is fixed, the endpoint returns HTTP 422 with message "Shop constraint isn't supported yet." The resource definition and mapping are ready and will work automatically once the core limitation is resolved.carrier_readscope. 3. Obtain an OAuth2 Bearer token. 4.GET /admin-api/carriers/{id}/ranges(e.g./carriers/2/ranges) — currently returns HTTP 422 due to core limitation inCarrierRangeRepository(seeTODO.md). 5.GET /admin-api/carriers/999/ranges— should return HTTP 404.