Lotwarden

Technical documentation

How Lotwarden is built.

Laravel 13 and PHP, a MySQL database, the Filament admin, a REST API and a responsive web front end.

Data model

TableWhat it holds
lotsGarages and surface lots: kind, levels, hourly and daily rate, permit only
spacesEvery bay: lot, level, code, kind (standard, accessible, EV), status (free, occupied, held), the car in it, the permit it is allocated to
vehiclesPlate, state, make, model, color, owner
visitsEntry and exit records: vehicle, lot, space, times, source (plate reader, sensor, manual), camera
permit_typesResident, commuter, visitor: price and length
permitsNumber, holder, vehicle, type, lot, start, expiry, status, who issued it
citationsNumber, plate, lot, space, officer, violation, fine, status (unpaid, paid, appealed, void), due date
paymentsReceipt, payer, what it paid for (permit, citation, parking), amount, method, time
alertsPermit expiry, payment and violation alerts for a customer or for staff
feed_eventsEvery plate read and sensor change received
usersUsername, role (administrator, operator, parking officer, customer), API token

Roles

RoleCan
AdministratorEverything, including payments, revenue, rates, permit types and users
OperatorLots, spaces, visits, vehicles, permits, citations, the feed. No payments or users
Parking officerOfficer screen: plate lookup, citations, logging a car in
CustomerOwn vehicles, permits, visitor permits, payments, citations and alerts

Running it

composer install
php artisan migrate --seed
php artisan feed:tick --times=20   # simulated plate reads and sensors
php artisan permits:alerts         # expiry alerts, daily
php artisan test                   # API and role tests

In this prototype the simulated feed also advances while someone has a live map open, and the admin dashboard can pause it.

Integrations

Plate readers and sensors post to the API (see the API). Here a simulated feed stands in for the hardware.

Payments are test payments in this prototype: no card is charged. A live system hands the checkout to a payment processor, so card numbers never touch this server.