About Expertise Projects Experience Contact
← Back to Projects

VisionIQ — AI Operations Platform

Laravel 10 multi-tenant AI operations platform for brands and branches: AI device fleet, people-counting & traffic analytics, parking sessions & occupancy, violation workflows, facial recognition, and multi-channel notifications—backed by a session dashboard and a token-authenticated REST API.

Laravel 10PHPMySQLMulti-tenantAI DevicesParkingViolationsREST APISpatie

What was broken

Operators needed one system across many brands and branches—not a single-purpose counter app. Leadership wanted trustworthy traffic and parking KPIs by period, security teams needed violation intake with alerts, and integrations required a stable API that matched what the dashboard shows.

How we fixed it

Built and extended a layered Laravel codebase: brand-scoped dashboard under `/dashboard/{brandId}` for analytics, parking live occupancy, violations, facial recognition, AI devices/models, reports, and notification settings; parallel `/api` resources for devices and third parties; Form Requests, policies, services, and repositories so each domain stays reviewable as modules grow.

What made this hard

Multi-tenant scoping must stay correct on every web and API path as modules multiply (counters, parking, violations, FR). Analytics and occupancy questions are unforgiving on timezones, branch filters, and period boundaries. Dashboard and API authorization have to stay aligned so device integrations never drift from what operators see. High-volume ingest (counts, sessions, violation events) needs queue depth, cache freshness, and aggregation jobs so spikes never starve core dashboard and API paths.

How the system is shaped

API Structure

Two surfaces: session dashboard under `/dashboard/{brandId}` (Blade, `Dashboard\*` controllers) with locale, `admin:web`, and `brand.access`; parallel `/api` REST (`auth.token`, tiered rate limits) with `apiResource` routes for brands, branches, AI devices, people counters, parking sessions, violations, facial recognition, roles, and notification settings. Period-based analytics and parking occupancy endpoints share the same branch hierarchy operators use in the panel; reports and notification helpers keep one response envelope for Blade charts and integrations.

Data Flow

Edge AI devices and integrations post counts, parking sessions, violations, and recognition events into API ingest → services/repositories persist and roll up into MySQL aggregates. Operators pick a brand, then use home/comparison, branch statistics (traffic, demographics, time analysis), parking live occupancy, violation queues, and facial recognition admin. Heavier exports and Telegram/email alerts run through queues; hot branch/period slices use tagged cache where configured.

Backend Decisions

Brand and branch context live in session and route parameters before dashboard work runs. Each domain (counters, parking, violations, FR, devices) owns FormRequests and policies—not inline validation scattered in controllers. Service layer owns transactions; controllers orchestrate validate → authorize → service → consistent JSON/Blade responses. Read paths pair staged aggregation with indexing and eager loading so multi-module dashboards stay responsive under load.

Why this stack and shape

Kept one modular monolith with repository/service boundaries per domain instead of splitting microservices early. Spatie-oriented RBAC and Laravel policies gate dashboard and API; PHPStan level 6 and PHPUnit keep refactors safe as parking, violations, and device attribute surfaces expand. Prefer queues, cache tags, and rate limiters over speculative new infrastructure.