This repository contains the solution for the Senior Developer technical test.
I chose the Decorator Pattern for the pricing logic as it allows for horizontal scalability of business rules.
- Open/Closed Principle: We can add new rules (e.g., "Black Friday Bonus") by creating a new
BlackFridayDecoratorclass without touching the existing base service code. - Dynamic Composition: The controller can decide which decorators to apply at runtime (or via DI configuration), offering total flexibility.
I opted for <script setup> and the Composition API over the Options API because:
- Better Type Inference: Native Support for TypeScript.
- Cleaner Code: Less boilerplate (no
this,methodsobject, etc.). - Reusable: Fetch logic could be easily extracted into a
useValuation()composable if the application grows.
The backend development followed a TDD (Test Driven Development) cycle:
- Write a failing test.
- Implement the minimum logic to pass the test.
- Refactor.
This guarantees that each business rule (Brand Bonus, Condition Multiplier, High Season) is isolated and verified.
src/
├── Controller/
│ └── ValuationController.php # API Endpoint
├── Dto/
│ └── ValuationRequest.php # Data Transfer Object (PHP 8.2 Readonly)
└── Service/
└── Valuation/
├── ValuationServiceInterface.php
├── BaseValuationService.php # Base Price
└── Decorator/ # Business Rules
├── AbstractValuationDecorator.php
├── BrandBonusDecorator.php
├── ConditionMultiplierDecorator.php
└── HighSeasonDecorator.php
assets/js/components/
└── ValuationEstimator.vue # Vue 3 Component
You need two terminal windows (or tabs) to run the full stack:
composer install # Only for the first time
php -S 127.0.0.1:8000 -t publicnpm ci # Only for the first time
npm run devThen open your browser at http://localhost:5173.
Although this is a simulation environment, the tests are prepared for PHPUnit.
# Run all backend tests
./bin/phpunit
# Run business logic tests (Unit)
./bin/phpunit tests/Service/Valuation
# Run frontend tests
npm testTo maintain the code standards, you can run the following commands:
# Frontend Linting (ESLint + Prettier)
npm run lint
# Backend Coding Standards (PHP-CS-Fixer)
# Note: Using IGNORE_ENV because the local PHP version (8.5) is newer than the tool's strict requirement.
PHP_CS_FIXER_IGNORE_ENV=1 vendor/bin/php-cs-fixer fixOnce deployed:
curl -X POST https://api.percentil.com/api/v1/valuation/estimate \
-H "Content-Type: application/json" \
-d '{"brand": "Zara", "category": "dresses", "condition": "new"}'- HighSeasonDecorator: Uses
Psr\Clock\ClockInterfaceto test time deterministically, avoiding issues with tests failing depending on the execution date. - Validation: In a real environment, I would add
symfony/validatorto theValuationRequestDTO.