Skip to content

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:

  1. getGeneralWheelSpecifications(brandId, modelId, colorId)
  2. Uses WheelManagerInterface::findBy(...) with filters:
  3. active
  4. can be sold
  5. available on webshop
  6. wheel brand/type/color
  7. Uses first matching wheel to return brand/model/color labels + image.
  8. Returns available inch sizes via WheelManagerInterface::getAvailableInchSizes(...).

  9. getAllWheelSpecifications(brandId, modelId, colorId, rimDiameter)

  10. Queries wheel-vehicle compatibility (WheelVehicle) with joins to wheel, chassis, model, and brand.
  11. Applies operational filters:
  12. active webshop-sellable wheel records
  13. active wheel-brand/chassis/model/brand graph
  14. model built within last 10 years
  15. model flags: market=1, popular=1, active=1
  16. Groups by wheel/chassis and builds nested payload:
  17. vehicle brand map
  18. per-model details (build years, image URL, vehicle webpage URL)
  19. 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

  1. OpenAPI shape drift exists for /wheel-specifications/general (spec describes a wrapped specifications array; controller returns one object).
  2. Response DTOs are implicit arrays and not schema-validated at runtime.
  3. Query parameter validation is presence-based only; no typed validation/errors per-field.
  4. Endpoint filters are hardcoded in service/query logic (market/popular/build window) without explicit product contract.
  5. Large /all payloads have no pagination, caching contract, or rate-limit policy in module contract.
  6. No dedicated module-level automated tests are present for endpoint contracts and filter behavior.
  7. 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

  1. Wheel listings are constrained to active + sellable + webshop-visible wheel data.
  2. /general returns one wheel style summary for brand/model/color with available inch sizes.
  3. /all returns vehicle compatibility grouped by vehicle brand/model and includes compatible wheel products.
  4. Returned wheel product rows include technical wheel attributes needed for fitment decisions.
  5. Missing-data outcomes remain explicit and machine-readable.

Required Improvements

  1. Introduce versioned response DTOs and align OpenAPI with actual payloads.
  2. Add strict typed query validation and consistent RFC7807-style error responses.
  3. Externalize compatibility filters (market/popular/build-window) to explicit configuration/policy objects.
  4. Add caching + optional pagination/limits for /all to prevent oversized responses.
  5. Add endpoint contract tests (200/400/404) and service-level query/filter tests.
  6. Centralize URL generation (vehicle/product links) behind a reusable URL builder service.
  7. 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

  1. Should the 404 no-data behavior be preserved or replaced by 200 with empty collections.
  2. Should /all stay a single call or split into paged/batched compatibility resources.
  3. Should market/popularity/build-window filters be tenant-configurable.
  4. Should wheel-spec endpoints stay in Webshop API or move behind a Vehicle Data API boundary.