Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/alber1802/AvaluoVehicular/llms.txt

Use this file to discover all available pages before exploring further.

Avalúo Vehicular follows a monolithic full-stack architecture — a single Laravel 12 application handles all routing, business logic, and appraisal calculations on the server, while delivering a fully reactive React 19 interface to the browser. There is no separate REST API; instead, Inertia.js acts as the bridge between Laravel controllers and React page components, allowing developers to write server-side PHP code that drives a seamless SPA experience without the overhead of maintaining two independent services.

Inertia.js Pattern

Inertia.js replaces the traditional JSON API + client-side data-fetching pattern with a protocol that lets Laravel controllers render React components directly. The server owns the routing — every URL maps to a Laravel route and a PHP controller method. When the controller is done processing, it calls Inertia::render(), passing the component name and a data array. Inertia serializes that array as JSON props, and the React component receives them as first-class TypeScript props on every page load and navigation.
// app/Http/Controllers/Registro/AvaluoController.php
return Inertia::render('Registro/create/resultado', [
    'vehiculo'          => $vehiculo,
    'valorFinal'        => $valorFinal,
    'factorReposicion'  => $factorReposicion,
    'factorModelo'      => $factor_a,
    'factorKilometraje' => $factor_b,
    'factorInspeccion'  => $factor_c,
    'valorResidual'     => $valorResidualVehiculo,
]);
Subsequent navigations inside the app use Inertia’s client-side router, which makes a lightweight XHR request for the next page’s props rather than doing a full HTML reload — giving users a fast SPA feel while keeping all routing and logic on the server.
Ziggy (tightenco/ziggy) compiles all named Laravel routes into a JavaScript object that is injected on every page. This means you can call route('dashboard') or route('vehiculos.show', { id: 1 }) in React components exactly as you would in a Blade view, with no hardcoded URL strings.

Directory Structure

The project is organized so that the PHP domain and the React domain mirror each other conceptually.
PathPurpose
app/Http/Controllers/Registro/Vehicle registration & appraisal controllers
app/Http/Controllers/Inspeciones/Inspection (faults & technical sections) controllers
app/Http/Controllers/Share/Appraisal sharing & public token controllers
app/Http/Controllers/RolesPermisos/Spatie role & permission management
app/Http/Controllers/User/User profile & administration
app/Http/Controllers/Accesorios/Vehicle accessory management
app/Http/Controllers/Reciclaje/Soft-deleted record recovery
app/Models/Eloquent models (one per database table)
resources/js/pages/React page components (mapped 1:1 to Inertia::render() calls)
resources/js/components/Shared, reusable React components
resources/js/layouts/Top-level page layout wrappers
routes/web.phpAll application routes (no api.php is used)
database/migrations/Ordered schema migrations

Frontend Stack

The React layer is written entirely in TypeScript and uses the following dependencies (from package.json):
PackageVersionRole
react^19.2.3UI framework
@inertiajs/react^2.1.4Inertia adapter for React
tailwindcss^4.0.0Utility-first CSS
@radix-ui/*variousAccessible headless UI primitives (Dialog, Select, Dropdown, Tooltip, etc.)
lucide-react^0.475.0Icon library
recharts^3.5.0Dashboard data visualisation charts
ziggy-js^2.6.0Laravel route helpers in JS
typescript^5.7.2Static typing
class-variance-authority^0.7.1Component variant styling
clsx^2.1.1Conditional class name helper
tailwind-merge^3.0.1Merge Tailwind classes without conflicts

Build Tooling

Assets are compiled with Vite 7, configured via vite.config.ts:
// vite.config.ts
import { wayfinder } from '@laravel/vite-plugin-wayfinder';
import tailwindcss from '@tailwindcss/vite';
import react from '@vitejs/plugin-react';
import laravel from 'laravel-vite-plugin';
import { defineConfig, loadEnv } from 'vite';

export default defineConfig(({ mode }) => {
    const env = loadEnv(mode, process.cwd(), '');
    const skipWayfinder = env.SKIP_WAYFINDER === 'true' || process.env.SKIP_WAYFINDER === 'true';

    return {
        plugins: [
            laravel({
                input: ['resources/css/app.css', 'resources/js/app.tsx'],
                ssr: 'resources/js/ssr.tsx',
                refresh: true,
            }),
            react(),
            tailwindcss(),
            !skipWayfinder && wayfinder({ formVariants: true }),
        ].filter(Boolean),
        esbuild: {
            jsx: 'automatic',
        },
    };
});
The laravel-vite-plugin handles hot-module replacement during development and asset hashing for production. Server-side rendering is supported via ssr.tsx and can be started with php artisan inertia:start-ssr.
Wayfinder (@laravel/vite-plugin-wayfinder) generates fully typed TypeScript functions for every Laravel controller action at build time. Instead of calling route('avaluos.show', id) as a stringly-typed string, you get an auto-completed, type-checked function like AvaluoController.index(id) directly in your React components — with formVariants: true also generating typed form action helpers.

Request Lifecycle

Every user interaction follows the same path through the stack:
Browser
  └─► Nginx (reverse proxy / TLS termination)
        └─► PHP-FPM (process manager)
              └─► Laravel Router (routes/web.php)
                    └─► Middleware pipeline (auth, permissions, etc.)
                          └─► Controller method
                                ├─► Eloquent models / business logic
                                └─► Inertia::render('Page', $props)
                                      └─► React component
                                            (receives $props as TypeScript props)
On the first visit, Laravel sends a full HTML document with the Vite-compiled JS bundle. For subsequent Inertia navigations, only a JSON response containing the new page component name and props is exchanged — the browser never performs a full reload.

Build docs developers (and LLMs) love