# Garage Management System — Documentation

A production-grade Garage Management System for an automotive workshop that handles
**both** routine service/maintenance and accident/repair work, with inventory,
purchasing, insurance claims, invoicing, payments, and reporting all connected into
one system. Built in plain PHP 8 (no framework), PDO, MySQL/MariaDB, and a
dependency-free HTML/CSS/JS frontend so it runs anywhere PHP runs — including fully
offline on a local network.

Every module described below was built and then exercised live against a real
MySQL/MariaDB database during development (not just written and assumed to work) —
records were created, edited, and their side effects (stock levels, invoice
balances, status transitions) verified in the database after each action.

## 1. Technology

- PHP 8+ (no Composer dependencies — a small custom autoloader/router/ORM)
- MySQL 8 / MariaDB 10.4+ via PDO with prepared statements everywhere
- HTML5 / CSS3 / vanilla JavaScript (no build step, no CDN dependencies — the app
  is fully self-contained so it keeps working on a LAN with no internet access)
- Session-based auth, CSRF tokens on every form, bcrypt password hashing

## 2. Architecture

```
app/
  Config/            (none needed — see config/config.php)
  Core/              Router, Database (PDO singleton), Model (base CRUD), Controller,
                     Auth, Session, Csrf, View
  Middleware/        Auth, Guest, Permission
  Controllers/       One per resource (CustomerController, WorkOrderController, ...)
  Models/            One per table, thin data-access classes with the real business
                     logic (stock deduction, status transitions, totals) as methods
  Views/             Plain PHP templates, one layout for the app shell + one for
                     printable documents
  Helpers/           Global helper functions (e(), url(), formatMoney(), ...)
config/config.php     App + database + session + upload settings
routes/web.php        All routes, grouped by Auth/Guest middleware
public/               Web root: index.php front controller, assets, uploaded files
storage/uploads/      Private uploads (vehicle photos/documents) served only via
                     an authenticated, permission-checked route — never directly
database/             schema_phaseN.sql (module-by-module), seed_phaseN.sql,
                     database.sql (consolidated schema + required seed data),
                     demo_data.sql (schema + realistic sample data)
```

There is no ORM magic and no hidden query builder — every query is a plain,
readable, parameterized SQL statement. This is deliberate: it keeps the codebase
auditable and easy to extend without learning framework conventions.

## 3. User Roles

Super Admin, Admin, Manager, Receptionist, Service Advisor, Mechanic, Storekeeper,
Cashier, Accountant. Super Admin implicitly has every permission; every other role's
access is enforced by real, granular permission checks on the server (not just menu
visibility) — verified by logging in as a restricted user and confirming a direct
URL hit to an unauthorized page returns 403, not just that the menu link is hidden.

Permissions are grouped by module (e.g. `workorders.view`, `workorders.manage`,
`inventory.manage`, `insurance.manage`) and are fully editable from **Roles &
Permissions** in the app — an administrator can create new roles and tick exactly
which permissions they get.

## 4. Core Connected Workflows

**Service:** Customer → Vehicle → Appointment/Quick Check-in → Work Order → Parts
(from inventory, stock deducted immediately) + Labor → Invoice → Payment → Service
History entry + next-due schedule recalculated automatically.

**Repair:** Customer → Vehicle → Work Order (type=repair) → Inspection checklist →
Insurance Claim → Survey → Approval (sets the claim's receivable) → Supplement
requests (never touch the receivable until explicitly approved) → Invoice →
Payment.

**Purchasing:** Supplier → Purchase Order → Receive (stock increases for every
linked part, recorded as an `inventory_transactions` row) → Payment tracking.

These aren't just described — the end-to-end chain was clicked through in a real
browser session with the resulting database rows inspected after each step.

## 5. Modules

### Foundation
- Authentication: login, logout, forgot/reset password (LAN-safe: since there's no
  mail server assumed, the reset link is shown directly on screen instead of
  silently failing to send an email), change password, session security, CSRF.
- Branding & Settings: garage identity, logo/favicon/login-logo upload, brand
  colors (applied live everywhere via CSS variables, including printed documents),
  currency, tax, document numbering prefixes, workshop/alert thresholds.
- Users & Roles: full CRUD, role-permission matrix editor.
- Customers: individual/company/fleet/insurance types, profile with vehicles,
  balance, and history.
- Vehicles: full profile with service history timeline, preventive-maintenance
  schedule, and linked work orders.

### Service & Maintenance
- Service Categories (15 seeded, e.g. Oil Change, Brake Service, AC Service) with
  default mileage/day intervals.
- Service Packages with itemized included parts/labor/services and a price.
- Appointments with a status workflow (scheduled → confirmed → arrived → in
  service → completed/cancelled/no-show).
- **Quick Service Check-in**: a fast, single-screen flow for returning customers —
  search the vehicle, record mileage/complaint, assign a mechanic, and a work order
  is created immediately.
- Work Orders: unified for both service and repair (`wo_type`), full status
  workflow (received → inspection → estimate → waiting approval/parts → in
  progress → QC → ready → completed → delivered/cancelled), with a full status
  history audit trail.
- Job Cards per mechanic with estimated/actual hours.
- **Workshop Visual Board**: a kanban-style view of every open work order grouped
  by status, flagging vehicles that have been in the shop longer than the
  configured threshold.
- Preventive maintenance: completing a service work order automatically writes a
  service-history entry and recalculates that vehicle's next-due mileage/date for
  that category — verified live (oil change at 62,000km → next due correctly
  computed as 67,000km / +180 days).
- Service Due report: vehicles approaching or past their next-due mileage/date,
  configurable thresholds.

### Accident / Repair & Insurance
- Vehicle intake fields (fuel level, visible damage notes) captured on the work
  order.
- Structured vehicle inspection checklist (11 areas: exterior, interior, engine,
  electrical, brakes, tires, suspension, transmission, cooling, AC, other) with a
  condition rating and notes per area.
- Vehicle photos (categorized: front/rear/left/right/interior/engine/damage/other)
  and documents, uploaded and served through a permission-checked route (not a
  public URL).
- Insurance Companies, Claims (with a proper claim-number sequence and full status
  workflow), Surveys, Approvals, and **Supplements** — supplementary requests
  never add to the claim's approved/insurance-contribution total until explicitly
  approved, which was specifically tested (pending supplement left the claim
  balance untouched; approving it correctly added the amount).
- Insurance Receivables report (amount owed by insurer minus amount paid).

### Inventory & Purchasing
- Part Categories, Parts (SKU auto-generated, cost/selling price, min/max stock,
  supplier, location).
- Every stock change (purchase receipt, service/repair usage, manual adjustment,
  return, damage) is recorded as a signed `inventory_transactions` row — there is
  a full, auditable movement history per part.
- **Service/repair ↔ inventory connection**: on a work order, "Use Part from
  Inventory" deducts stock atomically and links the line item to the part; "Remove
  & Restock" reverses it exactly. This is deliberately kept separate from the
  freeform parts/labor line-item editor so that inventory-linked lines can never
  be silently dropped or double-counted by a bulk save (verified live).
- Suppliers with purchase history and outstanding balance.
- Purchase Orders: create with multiple line items, receive (stock increases for
  every linked part in one atomic transaction), track payment status.
- Low-stock / out-of-stock alerts, inventory valuation report, most-used-parts
  report.

### Financials
- Estimates: itemized, status workflow (draft → sent → approved/rejected/expired),
  and **convert an approved estimate directly into a work order** with the same
  line items pre-filled.
- Invoices: generated directly from a work order's actual parts/labor items (tax
  applied per the configured rate), status auto-recalculates from payments
  (unpaid → partial → paid).
- Payments: cash/bank transfer/mobile money/card/other, recorded against an
  invoice, auto-numbered receipts, full payment history per invoice.
- Expenses: categorized, with an optional PDF/image attachment.
- Coupons: percentage or fixed discount, expiry, usage limit, minimum order
  amount, and usage tracking. **Known gap:** coupon validation/redemption logic
  exists in the model (`Coupon::validateForAmount`, `Coupon::recordUsage`) but is
  not yet wired into the invoice-creation UI — coupons can be created and viewed,
  but applying one to a specific invoice is not yet a button in this build.

### Reporting, Search & Operations
- Reports: Financial (revenue by method, expenses by category, outstanding),
  Service & Repair (jobs/revenue by category, status breakdown, repeat
  customers), Inventory (valuation, movement, most-used parts), Customers (new,
  top spenders, inactive).
- Global Search: one box in the top bar searches customers, vehicles, work
  orders, invoices, estimates, insurance claims, and parts by SKU/number.
- Audit Log: every create/update/delete/status-change/login records who, what,
  when, and from which IP, with a dedicated filterable page (not just a dashboard
  widget).
- Notifications: computed live from real data (low/out-of-stock parts, vehicles
  due for service, invoices overdue 14+ days, insurance claims awaiting approval)
  rather than a separate stored feed — so it can never drift out of sync with
  what's actually happening.
- QC & Delivery: a work order can only be marked "Delivered" from "Ready" status,
  and delivery requires an explicit customer-confirmation checkbox plus final
  mileage, which updates the vehicle's mileage on record.
- Printable documents (branded with your logo/colors, print-to-PDF via the
  browser's print dialog): Invoice, Estimate, Work Order / Repair Order.

## 6. Database

40+ tables across 5 phase files under `database/`, consolidated into
`database.sql` (schema + required seed data only) and `demo_data.sql` (schema +
realistic sample business data). Every foreign key, index, and unique constraint
is real and enforced — not just documented. See `database/schema_phase*.sql` for
the annotated, phase-by-phase originals if you want to see how the schema grew
with the feature set.

Multi-step operations that touch money or stock (recording a payment, receiving a
purchase, using/removing an inventory part, completing a service work order,
converting an estimate) are wrapped in real PDO transactions, with a
nested-transaction guard (`$db->inTransaction()` check) so that a transactional
method can safely be called from inside another one without PDO's "already an
active transaction" error — a real bug that surfaced during testing (estimate →
work order conversion calling `WorkOrder::changeStatus()`) and was fixed.

## 7. Security

- All queries are parameterized (PDO prepared statements) — no string-concatenated
  SQL anywhere.
- CSRF token required and verified on every state-changing (POST) request.
- Passwords hashed with bcrypt (`password_hash`/`password_verify`), never stored
  or logged in plain text.
- Session cookies are HttpOnly, SameSite=Lax.
- File uploads are validated by extension and size, renamed to a random filename
  on disk, and — for vehicle photos/documents — served through an authenticated,
  permission-checked controller route rather than a public path.
- Every permission check happens server-side in the controller, not just in the
  menu; verified live by hitting a restricted URL directly as a low-privilege user
  and confirming a 403.

## 8. What Was Deliberately Scoped Out of This Build

Given the size of the full specification, the following were consciously not
built to this depth, to keep everything that *is* built real, tested, and
correct rather than spreading thin over more surface area:

- Coupon redemption is not wired into the invoice UI (see Financials above).
- Notifications are a computed page, not a persistent per-user read/unread feed
  or a push/email/SMS system.
- There's no separate "Vehicle Intake" screen distinct from the work-order form —
  intake fields (fuel level, damage notes, photos) live on the work order itself,
  which serves the same purpose with less duplication.
- No multi-language / i18n.
- No automated test suite (PHPUnit) — verification was done by exercising the
  running application against the real database and inspecting results, which is
  documented throughout this file and was done for every module.

None of the above are fake buttons or stubs; they're simply not present, and any
UI you see performs a real, working action against the real database.
