Files
fuel-price/.claude/rules/architecture.md
Ovidiu U d5fb7f85bd
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 Filament admin panel with migrations and design spec
- Add AdminPanelProvider mounting panel at `/admin` with `is_admin` auth guard
- Add `is_admin` boolean column to users table
- Add brent_prices and price_predictions tables with appropriate indexes
- Add comprehensive admin design spec covering resources, dashboard, navigation, and build order
- Configure default panel with amber primary color and standard middleware stack
- Add compiled Filament assets (actions.js, app.css)
2026-04-04 13:40:56 +01:00

58 lines
2.8 KiB
Markdown

# Architecture
## Core principle: fat Services, thin everything else
All business logic lives in Service classes. Controllers, Livewire components,
and console commands are thin orchestrators — they call Services and return results.
This keeps the app API-extractable later without a rewrite.
## Directory structure
```
app/
├── Console/Commands/ # Scheduler commands (PollFuelPrices, PredictOilPrices, RunScoringEngine)
├── Http/Controllers/ # Minimal — auth + Stripe webhook only
├── Livewire/ # Classic two-file Livewire components
├── Models/ # Eloquent models
├── Notifications/ # Laravel Notification classes (multi-channel)
├── Services/ # ALL business logic lives here
│ ├── FuelPriceService.php # Fuel Finder API polling + storage
│ ├── AlertScoringService.php # Fill-up timing recommendation engine
│ ├── StationTaggingService.php # Supermarket brand detection
│ ├── NotificationDispatchService.php # Tier-aware notification routing
│ ├── SubscriptionService.php # Cashier/tier helpers
│ ├── PostcodeService.php # Resolves postcodes/outcodes/place names → lat/lng
│ ├── OilPriceService.php # FRED fetch + EWMA/LLM Brent crude prediction
│ ├── LocationResult.php # DTO returned by PostcodeService
│ └── ApiLogger.php # Wraps all outbound HTTP calls, logs to api_logs
└── Jobs/ # Queued jobs (dispatch notifications per user)
resources/views/
├── livewire/ # Livewire Blade templates
└── emails/ # Mailable templates
routes/
├── web.php # All web routes (Livewire pages)
└── api.php # Empty for now — API added later if needed
```
## Service class conventions
- Constructor injection only — no facade usage inside Services
- Services are bound in AppServiceProvider if they need interfaces
- Each Service has one responsibility — do not merge concerns
- Return typed DTOs or Eloquent collections — never raw arrays from Services
- Services never dispatch jobs directly — that's the controller/command's job
## No API yet
`routes/api.php` stays empty for v1. Do not create API controllers or Sanctum
token auth. The app is Livewire-only until subscriber count justifies a native app.
When the API is added later, it will reuse the same Service classes.
## Livewire components (classic only)
Use two-file classic Livewire components. Do NOT use Volt single-file syntax.
Volt files from the starter kit (auth screens) are left as-is — do not convert them.
New components go in `app/Livewire/` with corresponding Blade in `resources/views/livewire/`.