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.
This commit is contained in:
53
architecture.md
Normal file
53
architecture.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# 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/`.
|
||||
Reference in New Issue
Block a user