Common commands
Frontend layout
The React app is an Inertia SPA served by Laravel. Everything lives under resources/js:
Controllers render pages by name, so Inertia::render('Visibility') maps to
resources/js/pages/Visibility.tsx. Route helpers come from Ziggy, so named Laravel routes
are callable from TypeScript as route('prompts.show', id).
Prettier runs with prettier-plugin-organize-imports and prettier-plugin-tailwindcss.
Both rewrite code, so run npm run format rather than hand-sorting imports or class lists
— otherwise CI’s format:check will disagree with you.
Backend layout
Routes are split by concern in routes/: web.php holds the dashboard shell and requires
campaigns.php, onboarding.php, settings.php, billing.php, admin.php,
notifications.php and auth.php.
Working with the queue
Almost all provider work is queued. QUEUE_CONNECTION defaults to database, so a worker
must be running for prompt batches, sentiment fetches and traffic imports to make progress:
composer dev already starts one. When a job fails, failed_jobs holds the exception —
php artisan queue:retry all re-dispatches after a fix.
Tests
Tests are written with Pest (tests/Pest.php) and split into tests/Unit and
tests/Feature.
phpunit.xml intends to pin the test environment to in-memory SQLite
(DB_DATABASE=:memory:), an array cache/session and the sync queue driver. The sync
queue means jobs run inline, so a test that dispatches a prompt batch executes it during the
assertion rather than leaving it queued.
Feature tests extend Tests\TestCase and use RefreshDatabase (wired up in
tests/Pest.php). TestCase::registerSqliteRegexpFunction() registers a userland regexp()
function on SQLite connections, because production runs MySQL and queries such as
App\Queries\TrafficQueries rely on the REGEXP operator that SQLite does not implement
natively.
The SQLite pinning does not currently take effect. On a machine whose .env sets
DB_CONNECTION=mysql, the suite connects to that MySQL database instead of in-memory
SQLite — RefreshDatabase then migrates against your development database, and the run
fails during migration with SQLSTATE[42000] ... 1071 Specified key was too long. Setting
DB_CONNECTION/DB_DATABASE as shell variables and adding a .env.testing both fail to
override it, so something in the boot path is pinning the connection.Until this is tracked down, do not assume the suite is isolated from your development
database. Point .env at a throwaway database before running the tests locally.