Skip to content

Development Guide

This guide covers local setup, testing, and coding standards.

Contributing

Contributions welcome — features, fixes, tests, and docs.

  1. Setup: Follow Quick Start below
  2. Branch: Create a feature branch from dev
  3. Code: Make small, focused commits
  4. Test: Run backend and frontend tests (see Testing)
  5. PR: Open a pull request to dev

For detailed git workflow, branching strategy, and conflict resolution, see Git Workflow.

Quick Start

New to the repo? Follow these steps to get running:

  1. Run the app

    bash
    ./utils/deploy.sh

    Note: The backend automatically creates .env from .env.example when you run any php artisan command if it doesn't exist. You'll see a helpful message to run php artisan key:generate.

    Tip: Use ./utils/deploy.sh --skip-build for faster deployments when you've already built the Docker images and just need to restart containers or run database migrations.

  2. Access the app

  3. Optional: Enable HTTPS for local dev (single compose)

    bash
    # Set in backend/.env
    APP_ENV=development
    ENABLE_HTTPS=true
    
    # Generate self-signed certificates (one-time setup)
    # Note: script will NOT overwrite existing certs; use --force to regenerate
    ./utils/generate-dev-certs.sh
    
    # Deploy using the single entry point
    ./utils/deploy.sh
    
    # Access via HTTPS
    # https://localhost (browser will show security warning - click "Advanced" → "Proceed")
    # https://localhost/admin
    # https://localhost/docs

    Why HTTPS in dev?

    • Test features requiring secure context (Service Workers, Web Crypto API, etc.)
    • Match production behavior more closely
    • Test HTTPS-specific security headers

    Production note: Production deployments use docker-compose.yml only (no dev override). HTTPS is handled by reverse proxy (nginx/caddy/traefik) with proper certificates.

  4. Generate API Client

    If you change the backend API (@OA annotations), you must regenerate the frontend types and hooks:

    bash
    # Run from root to sync both backend and frontend
    bun run api:generate

    Alternatively, run separately:

    bash
    cd backend && php artisan l5-swagger:generate
    cd ../frontend && bun run api:generate

    CI/Commit Guardrail To ensure your generated code matches the current backend attributes, run:

    bash
    bun run api:check

    (Exits with code 1 if there are uncommitted changes to generated files).

    Deployment: The ./utils/deploy.sh script automatically regenerates both the OpenAPI spec and the frontend client during the pre-build stage to ensure the production image is always consistent.

    Usage: Refer to frontend/src/api/generated/ for the output. Prefer using the generated hooks (useGetPets, usePostPets, etc.) over manual Axios calls for full type safety.

    See API Conventions for more details on full-stack typesafety.

Test Users (Seeded Data)

  • Super Admin: admin@catarchy.space / password
  • Admin: user1@catarchy.space / password
  • Regular Users: 3 users with factory-generated names/emails / password

Admin Features

  • User Impersonation: Click 👤 icon in Users table to impersonate any user
  • Stop Impersonating: Use navbar indicator or admin panel to return
  • User Ban/Unban: Ban users to put them in read-only mode (view-only, no writes); unban to restore full access
  • User Storage Visibility: Open /admin/users/:id to view storage used and storage limit for that user
  • Storage Limits Config: Open /admin/system-settings to configure default vs premium storage ceilings

Testing

Backend (Pest/PHPUnit)

Always run backend tests inside the Docker container to ensure proper extensions and PHP version.

Tests run in parallel by default for faster execution.

bash
# Run all tests (parallel by default)
cd backend && php artisan test --parallel

# Run tests without parallel execution
cd backend && php artisan test --no-parallel

# Run specific test suites
cd backend && php artisan test --parallel --testsuite=Feature
cd backend && php artisan test --parallel --testsuite=Unit

Running tests locally (outside Docker):

If you need to run tests on your local machine:

bash
cd backend

# First time only - .env will be auto-created from .env.example
composer install
php artisan key:generate

# Configure your local database settings in .env, then run tests
php artisan test --parallel

Frontend (Vitest)

bash
cd frontend

# Run all tests
bun test

# Interactive UI
bun run test:ui

# Coverage report
bun run test:coverage

End-to-End (Playwright)

Playwright E2E tests live under frontend/e2e/.

For this project, the default E2E runner (frontend/scripts/e2e-test.sh) manages Docker services (db, backend, mailhog) and database seeding automatically before running Playwright.

Quick start:

bash
# From frontend/
cd frontend
bun run e2e            # headless run
bun run e2e:ui         # interactive UI
bun run e2e:report     # open last HTML report

If Playwright browsers are missing on your machine, install them once:

bash
cd frontend
bun x playwright install chromium

Static Analysis & Quality Gates

Code Quality (Formatting)

Run Laravel Pint to automatically format code according to PSR-12 and Laravel conventions.

bash
# From the backend directory
cd backend
./vendor/bin/pint

PHPStan (Backend Type Analysis)

PHPStan enforces type safety and catches bugs at write-time using static analysis. Currently configured at Level 5.

Run analysis:

bash
cd backend
composer phpstan

Deptrac (Architecture Layer Enforcement)

Deptrac prevents architectural violations by enforcing allowed dependencies between layers.

Run analysis:

bash
cd backend
composer deptrac

Asset Management

Updating Icons

Use utils/update_icon.sh to regenerate the favicon, PWA icons, and manifest whenever the branding icon changes.

bash
./utils/update_icon.sh /absolute/path/to/new/icon.png

The script requires ImageMagick (convert) and updates both frontend/public and backend/public assets so backend and SPA entry points stay in sync.

The frontend ships separate light and dark web manifests. Theme switching between them is handled by the app-owned runtime in frontend/src/lib/theme-runtime.ts, while the backend SPA shell applies the initial resolved theme before hydration so the manifest, theme-color, and color-scheme metadata stay in sync from first paint onward.