## Car Repairs Shop — AI agent working notes This repo is a Laravel 12 app with Livewire (Volt + Flux UI), Tailwind, and Vite. The UI is primarily Livewire pages; a few classic controllers exist for resource routes. Tests use in-memory SQLite. ### Architecture map - **Workflow-driven design**: The app implements an 11-step automotive repair workflow from vehicle reception to delivery with status tracking, inspections, estimates, and customer notifications. - Core domains live in `app/Livewire/**` and `app/Models/**` (Customers, Vehicles, Inventory, JobCards, Estimates, Diagnosis, WorkOrders, Timesheets, Users, Reports, CustomerPortal). - **WorkflowService** (`app/Services/WorkflowService.php`) orchestrates the complete repair process with methods for each workflow step. - **InspectionChecklistService** (`app/Services/InspectionChecklistService.php`) manages standardized vehicle inspections and comparison logic. - Routes are in `routes/web.php`: - Root decides destination based on `auth()->user()->isCustomer()` → customers go to `/customer-portal`, admins/staff to `/dashboard`, guests to `/login`. - Admin/staff area uses `admin.only` + `permission:*` middleware. Customer portal uses `auth` only. - Volt pages registered via `Volt::route('settings/...', 'settings.something')`. - Middleware aliases are registered in `bootstrap/app.php`: - `admin.only`, `role`, `permission` point to custom classes in `app/Http/Middleware`. Route `permission:` strings are the canonical auth gates in this app. - Settings use Spatie Laravel Settings (`app/Settings/**`, `config/settings.php`), e.g., `app(\App\Settings\GeneralSettings::class)` for shop phone/email in views. - Blade components: anonymous components live under `resources/views/components/**`. Example: `` is backed by `resources/views/components/layouts/customer-portal.blade.php`. ### 11-Step Workflow Implementation The system follows a structured automotive repair workflow: 1. **Vehicle Reception** → `JobCard::STATUS_RECEIVED` - Basic data capture, unique sequence numbers by branch (`ACC/00212`, `KSI/00212`) 2. **Initial Inspection** → `JobCard::STATUS_INSPECTED` - Standardized checklist via `InspectionChecklistService` 3. **Service Assignment** → `JobCard::STATUS_ASSIGNED_FOR_DIAGNOSIS` - Assign to Service Coordinator 4. **Diagnosis** → `JobCard::STATUS_IN_DIAGNOSIS` - Full diagnostic with timesheet tracking 5. **Estimate** → `JobCard::STATUS_ESTIMATE_SENT` - Detailed estimate with email/SMS notifications 6. **Approval** → `JobCard::STATUS_APPROVED` - Customer approval triggers team notifications 7. **Parts Procurement** → `JobCard::STATUS_PARTS_PROCUREMENT` - Inventory management and sourcing 8. **Repairs** → `JobCard::STATUS_IN_PROGRESS` - Work execution with timesheet tracking 9. **Final Inspection** → `JobCard::STATUS_COMPLETED` - Outgoing inspection with discrepancy detection 10. **Delivery** → `JobCard::STATUS_DELIVERED` - Customer pickup and satisfaction tracking 11. **Archival** - Document archiving and job closure ### Conventions and patterns - **Status-driven workflow**: Use `JobCard::getStatusOptions()` for consistent status handling. Each status corresponds to a workflow step. - **Role hierarchy**: Service Supervisor → Service Coordinator → Technician. Use role helper methods like `$user->isServiceCoordinator()`. - Livewire pages reside under `app/Livewire/{Area}/{Page}.php` with views under `resources/views/{area}/{page}.blade.php` (Volt routes may point directly to views). - Authorization: - Use `admin.only` to gate admin/staff routes. - Use `permission:domain.action` strings on routes (e.g., `permission:customers.view`, `inventory.create`). Keep naming consistent with existing routes. - **Branch-specific operations**: All job cards have `branch_code`. Use `JobCard::byBranch($code)` scope for filtering. - Customer Portal layout requires a `jobCard` prop. When using ``, pass it explicitly: - Example: ` ... ` - **Inspection system**: Use `InspectionChecklistService` for standardized checklists. Incoming vs outgoing inspections are compared automatically. ### Developer workflows - Install & run (common): - PHP deps: `composer install` - Node deps: `npm install` - Generate key & migrate: `php artisan key:generate && php artisan migrate --seed` - Dev loop (servers + queue + logs + Vite): `composer dev` (runs: serve, queue:listen, pail, vite) - Asset build: `npm run build` - Testing: - Run tests: `./vendor/bin/phpunit` (uses in-memory SQLite per `phpunit.xml`) - Alternative: `composer test` (clears config and runs `artisan test`) - Debugging: - Logs via Laravel Pail are included in `composer dev`. Otherwise: `php artisan pail`. ### Routing and modules (examples) ### Data Flow and State Management - **Status-Driven Design**: Each workflow step corresponds to a specific JobCard status. Always use status constants from the model. - **Service Dependencies**: WorkflowService orchestrates the complete flow, InspectionChecklistService handles standardized vehicle inspections. - **Customer Communication**: Auto-notifications at each step keep customers informed of progress. - **Quality Control**: Built-in inspection comparisons and quality alerts ensure consistent service delivery. - Admin resources (with permissions): - `Route::resource('customers', CustomerController::class)->middleware('permission:customers.view');` - Inventory area pages are Livewire classes under `app/Livewire/Inventory/**` and grouped under `Route::prefix('inventory')` with `permission:inventory.*`. - Customer portal routes: - `Route::prefix('customer-portal')->middleware(['auth'])->group(function () { Route::get('/status/{jobCard}', \\App\\Livewire\\CustomerPortal\\JobStatus::class)->name('customer-portal.status'); });` ### Testing notes (project-specific) - Tests use in-memory SQLite; avoid relying on factories that don’t exist. Prefer lightweight stubs or create the minimal model records needed. - For Blade/Livewire views using a layout slot, render the page view (not the layout) and pass required data. Example: `View::make('livewire.customer-portal.job-status', ['jobCard' => $jobCard])->render();` ### Guardrails for agents - When adding new admin routes, wire `admin.only` and appropriate `permission:*` middleware, and register Volt pages via `Volt::route` when applicable. - Keep anonymous Blade components under `resources/views/components/**` and pass required props explicitly. - Use `app(\App\Settings\GeneralSettings::class)` for shop metadata instead of hardcoding. - Follow existing permission key patterns (`domain.action`). If anything above is unclear or you need deeper details (e.g., settings schema, specific Livewire page conventions), propose a short diff or ask for a quick pointer to the relevant file.