Development

This guide covers the development workflow, tests, demo mode, project structure, and deployment process for the Web App Template.

Development Commands

Server & Assets

# PHP server, queue listener, Pail logs, and Vite together
composer dev

Database

php artisan migrate

Custom Artisan Commands

# Creates view/create/update/delete permissions for the models listed in the command
php artisan app:add-permissions-to-new-modules

Testing & Code Quality

The PHP suite uses Pest 4 on an in-memory SQLite database (phpunit.xml). Tests live in tests/Feature and tests/Unit.

composer test

composer test clears the config cache and runs php artisan test. GitHub Actions run Pint, the frontend format and lint scripts, and the test suite on pushes and pull requests to develop and main.

Debugging

php artisan pail

Demo Mode

Demo mode turns an instance into a public, resettable live demo. It exists on the feature/demo-mode branch and is off unless DEMO_MODE=true.

What It Does

  • Banner — A bar at the top of the panel (login page included) reads "Live demo — data resets every night" and links to the product page set in DEMO_PRODUCT_URL.
  • Demo accounts — demo:seed creates two accounts: an admin (admin@demo.omega-studio-software.com, role Super Admin) and a user (user@demo.omega-studio-software.com, no role). Their shared password is defined in config/demo.php.
  • Sample data — Tops up to 12 non-demo users and 20 email log records using factories, and seeds roles and permissions if missing.
  • Guarded credentials — Demo accounts cannot have their password or email changed, from the profile page or from the Users resource, and cannot be deleted. Other fields such as the name stay editable.
  • Mail — The mail driver is forced to log, so no real email is sent.
  • Uploads — Demo::uploadMaxKilobytes() caps uploads at 2 MB when demo mode is on.
  • Live Stripe key warning — demo:seed warns when STRIPE_SECRET starts with sk_live_. Demo instances must use test keys.

Commands

# Seeds demo data and the demo accounts (idempotent)
php artisan demo:seed

Both commands fail when DEMO_MODE is off. They also refuse to run unless APP_URL has a host starting with demo-, or DEMO_ALLOW_RESET=true is set. This protects real databases from an accidental wipe. When demo mode is on and the host allows it, demo:reset is scheduled daily at 03:00.

Configuration

  • Name
    DEMO_MODE
    Type
    boolean
    Description

    Enable demo mode. Default: false

  • Name
    DEMO_ALLOW_RESET
    Type
    boolean
    Description

    Override the demo- host check. Default: false

  • Name
    DEMO_PRODUCT_URL
    Type
    string
    Description

    Link target in the banner.

The behaviour is covered by Pest tests in tests/Feature/Demo: banner, credential guards, mail, reset, schedule, seed, and the support class.

Project Structure

Application Core

  • app/Models/ — User, Role, Permission, Activity, Email, Sms.
  • app/Policies/ — AbstractPolicy and per-model policies.
  • app/Providers/ — AppServiceProvider, AuthServiceProvider, EmailMessageServiceProvider, and Filament/AppPanelProvider.
  • app/Support/ — Demo and DemoSchedule.
  • app/helpers.php — Global helpers, autoloaded through Composer.

Filament Admin Panel

  • app/Filament/Resources/ — Users, Roles, Activities, Emails, Sms.
  • app/Filament/Pages/ — HealthCheckResults, ViewLog.
  • app/Filament/Auth/ — EditProfile.
  • app/Filament/Helpers/ — Shared pagination and search-limit helpers.

Background & Console

  • app/Jobs/ — SendSmsJob.
  • app/Listeners/ — FilamentEmailLogger.
  • app/Console/Commands/ — Permission, demo seed, and demo reset commands.
  • routes/console.php — Backup and heartbeat schedule.

Database & Config

  • database/migrations/, database/seeders/, database/factories/.
  • config/ — Includes permission.php, activitylog.php, backup.php, health.php, cashier.php, sentry.php, filament-email.php, and demo.php.
  • routes/web.php — Single redirect from / to the panel.

Frontend, Tests & CI

  • resources/css, resources/js, resources/views — Tailwind 4 and Vite assets.
  • tests/ — Pest feature and unit tests.
  • .github/workflows/ — lint.yml and tests.yml.
  • Envoy.blade.php — Deployment tasks.

Deployment

Using Laravel Envoy

Set DEPLOY_USER, DEPLOY_HOST, DEPLOY_REPOSITORY, and DEPLOY_APP_DIR (and optionally DEPLOY_BRANCH, default main) in the environment or .env, then run:

envoy run deploy

The deploy story runs three tasks over SSH on the target server: pull-repository (git fetch and git pull), run-composer (composer install, composer dump-autoload, php artisan migrate --force, php artisan optimize:clear), and run-node (npm install and npm run build).

Post-Deployment Steps

  1. Queue worker — Because QUEUE_CONNECTION=database, run a worker such as php artisan queue:work under a process manager. SendSmsJob is a queued job.
  2. Scheduler — Add the Laravel scheduler to cron so backups and the health heartbeat run:
* * * * * cd /path-to-project && php artisan schedule:run >> /dev/null 2>&1
  1. Web server — Point the document root to public/, and make storage/ and bootstrap/cache/ writable.
  2. Verify — Run php artisan health:check and open Health Check Results in the panel.

Was this page helpful?