Files
fuel-price/.claude/rules/code-style.md
Ovidiu U 4e9b809a10
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
feat: add user geolocation marker and auto-zoom to map based on search radius
2026-04-07 20:21:31 +01:00

48 lines
2.1 KiB
Markdown

# Code Style
## PHP
- PHP 8.2+ features: constructor property promotion, readonly properties, enums, match expressions
- Type declarations on all method parameters and return types — no untyped signatures
- Named arguments for clarity on calls with 3+ parameters
- Enums over string constants: `FuelType::E10`, `Recommendation::Wait`, `NotificationChannel::WhatsApp`
- `final` classes for Services and Jobs — they are not designed for extension
## Laravel conventions
- Route model binding over manual `findOrFail()` in controllers
- Form Requests for any validated input
- `config()` helper over `env()` outside of config files — never call `env()` in app code
- Events + Listeners for side effects (e.g. `PricesUpdatedEvent` triggers scoring)
- Do not use `DB::transaction()` manually — wrap in Service methods where needed
## Naming
- Services: `{Noun}Service` — e.g. `AlertScoringService`
- Jobs: `{Verb}{Noun}Job` — e.g. `SendFuelAlertJob`, `PollFuelPricesJob`
- Events: `{Noun}{PastTense}Event` — e.g. `PricesUpdatedEvent`
- Livewire components: `{Context}/{Feature}` — e.g. `Dashboard/FuelRecommendation`
- Migrations: descriptive, e.g. `create_station_prices_table`, `add_whatsapp_fields_to_users_table`
## Formatting
- 4-space indentation (PSR-12)
- Max line length: 120 characters
- Run `./vendor/bin/pint` before committing (Laravel Pint, default ruleset)
- No commented-out code committed — use git to recover old code
## Security
- Never store raw passwords — Bcrypt via Laravel's Hash facade only
- Validate and sanitise all user input — postcodes, phone numbers, fuel type selections
- Phone numbers: strip non-numeric characters, enforce UK format (07xxx or +447xxx)
- OTP codes: 6 digits, expire in 10 minutes, single use only
- All Stripe webhook payloads verified via Cashier's built-in signature check
## Environment
- Local: Laravel Valet or `php artisan serve`
- Production: IONOS VPS, Nginx + PHP-FPM, MySQL, Redis
- Never commit `.env``.env.example` must stay up to date with all required keys
- Queue driver: `redis` in production, `sync` in testing only