Vehicle Data - Wheel Specifications API Module¶
Overview¶
This document specifies the wheel-specifications API/module currently exposed from the API app and consumed as a wheel-to-vehicle compatibility data surface.
Checklist coverage:
- API-007 Wheel specifications APIs
- VD-008 Wheel specifications API module
Primary legacy evidence:
- _api/index.php
- _api/docs/swagger/en.json
- _api/docs/swagger/nl.json
- src/Atraxion/Module/WheelSpecifications/ServiceProvider/WheelSpecificationsServiceProvider.php
- src/Atraxion/Module/WheelSpecifications/Controller/WheelSpecificationsController.php
- src/Atraxion/Module/WheelSpecifications/Service/WheelSpecificationsService.php
- _core/config/service-providers.php
- src/Atraxion/Model/Product/Manager/WheelManagerInterface.php
- _core/config/doctrine/articles.wheels.WheelVehicle.orm.xml
- _core/model/classes/atx/vehicles/VehicleImageService.php
Legacy Capabilities (As-Is)¶
1. Public API Surface (API-007)¶
Routes are mounted in _api/index.php via WheelSpecificationsController::registerRoutes($app) and expose:
- GET /wheel-specifications/general
- GET /wheel-specifications/all
Query contracts:
- /general: brand_id, model_id, color_id (all required)
- /all: brand_id, model_id, color_id, inch (all required)
Current runtime error behavior:
- Missing required query params -> 400 JSON error payload
- No matching data -> 404 JSON error payload
2. Module Composition (VD-008)¶
The module is registered through WheelSpecificationsServiceProvider and wires:
- WheelSpecificationsService
- WheelSpecificationsController
Service-provider registration is active in _core/config/service-providers.php, and route registration is API-app specific in _api/index.php.
3. Data Assembly Logic¶
WheelSpecificationsService exposes two read operations:
getGeneralWheelSpecifications(brandId, modelId, colorId)- Uses
WheelManagerInterface::findBy(...)with filters: - active
- can be sold
- available on webshop
- wheel brand/type/color
- Uses first matching wheel to return brand/model/color labels + image.
-
Returns available inch sizes via
WheelManagerInterface::getAvailableInchSizes(...). -
getAllWheelSpecifications(brandId, modelId, colorId, rimDiameter) - Queries wheel-vehicle compatibility (
WheelVehicle) with joins to wheel, chassis, model, and brand. - Applies operational filters:
- active webshop-sellable wheel records
- active wheel-brand/chassis/model/brand graph
- model built within last 10 years
- model flags: market=1, popular=1, active=1
- Groups by wheel/chassis and builds nested payload:
- vehicle brand map
- per-model details (build years, image URL, vehicle webpage URL)
- compatible wheel products and technical wheel metadata (diameter, width, hole pattern, ET, center bore, stock, pricing, page/image URLs)
Current Gaps And Risks To Resolve In Migration¶
- OpenAPI shape drift exists for
/wheel-specifications/general(spec describes a wrappedspecificationsarray; controller returns one object). - Response DTOs are implicit arrays and not schema-validated at runtime.
- Query parameter validation is presence-based only; no typed validation/errors per-field.
- Endpoint filters are hardcoded in service/query logic (market/popular/build window) without explicit product contract.
- Large
/allpayloads have no pagination, caching contract, or rate-limit policy in module contract. - No dedicated module-level automated tests are present for endpoint contracts and filter behavior.
- Compatibility URLs are built with hardcoded host pattern logic in service code.
Target Migration Specification (Symfony)¶
Scope¶
In-scope: - Wheel-specifications read APIs and response contracts. - Service/query behavior parity for compatibility filtering. - Operational/API contract hardening (validation, schema consistency, observability).
Out-of-scope: - New merchandising strategy for wheel selection. - Simulator frontend UX redesign.
Domain Rules To Preserve¶
- Wheel listings are constrained to active + sellable + webshop-visible wheel data.
/generalreturns one wheel style summary for brand/model/color with available inch sizes./allreturns vehicle compatibility grouped by vehicle brand/model and includes compatible wheel products.- Returned wheel product rows include technical wheel attributes needed for fitment decisions.
- Missing-data outcomes remain explicit and machine-readable.
Required Improvements¶
- Introduce versioned response DTOs and align OpenAPI with actual payloads.
- Add strict typed query validation and consistent RFC7807-style error responses.
- Externalize compatibility filters (market/popular/build-window) to explicit configuration/policy objects.
- Add caching + optional pagination/limits for
/allto prevent oversized responses. - Add endpoint contract tests (200/400/404) and service-level query/filter tests.
- Centralize URL generation (vehicle/product links) behind a reusable URL builder service.
- Add API observability tags/metrics for wheel-spec endpoint volume and failure modes.
Acceptance Scenarios (Gherkin)¶
Feature: Wheel specifications API module
Scenario: General wheel specifications returns summary and inch sizes
Given active webshop-visible wheels exist for brand 1, model 10, color 3
When GET /wheel-specifications/general is called with those params
Then the response status should be 200
And the payload should include brand/model/color labels and inch_sizes
Scenario: Missing required parameters returns a validation error
Given no inch parameter is provided
When GET /wheel-specifications/all is called
Then the response status should be 400
And the payload should describe the missing required parameter
Scenario: Unknown filter combination returns not found
Given no active webshop-visible wheels match brand/model/color
When GET /wheel-specifications/general is called with that combination
Then the response status should be 404
Scenario: All wheel specifications groups compatibility by vehicle brand and model
Given compatible wheel-vehicle mappings exist for inch 19
When GET /wheel-specifications/all is called with matching params
Then the response should contain vehicle_brands keyed by brand id
And each model entry should include products with wheel_info and stock fields
Scenario: Inactive or non-sellable wheels are excluded
Given wheel mappings include inactive and active records
When GET /wheel-specifications/all is called
Then only active, sellable, webshop-visible wheels should be returned
Open Decisions¶
- Should the
404no-data behavior be preserved or replaced by200with empty collections. - Should
/allstay a single call or split into paged/batched compatibility resources. - Should market/popularity/build-window filters be tenant-configurable.
- Should wheel-spec endpoints stay in Webshop API or move behind a Vehicle Data API boundary.