Files
fuel-price/architecture.md
Ovidiu U 02d4c9d888
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
Add comprehensive project documentation and architecture guidelines
Establishes core rules and conventions for the FuelAlert Laravel application: architecture patterns (fat services, thin controllers), database schema with partitioned station_prices table, multi-tier notification system with Vonage and OneSignal, 4-signal scoring engine for fuel price recommendations, Stripe subscription tiers, Livewire classic component structure, and Pest testing standards.
2026-04-03 16:49:19 +01:00

2.4 KiB

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, 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
└── 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/.