Development Guide
This guide covers local setup, testing, and coding standards.
Contributing
Contributions welcome — features, fixes, tests, and docs.
- Setup: Follow Quick Start below
- Branch: Create a feature branch from
dev - Code: Make small, focused commits
- Test: Run backend and frontend tests (see Testing)
- 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:
Run the app
bash./utils/deploy.shNote: The backend automatically creates
.envfrom.env.examplewhen you run anyphp artisancommand if it doesn't exist. You'll see a helpful message to runphp artisan key:generate.Tip: Use
./utils/deploy.sh --skip-buildfor faster deployments when you've already built the Docker images and just need to restart containers or run database migrations.Access the app
- Main App: http://localhost:8000
- Admin Panel: http://localhost:8000/admin (admin@catarchy.space / password)
- API Docs: http://localhost:8000/api/documentation
- Project Docs: http://localhost:8000/docs (VitePress)
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/docsWhy 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.ymlonly (no dev override). HTTPS is handled by reverse proxy (nginx/caddy/traefik) with proper certificates.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:generateAlternatively, run separately:
bashcd backend && php artisan l5-swagger:generate cd ../frontend && bun run api:generateCI/Commit Guardrail To ensure your generated code matches the current backend attributes, run:
bashbun run api:check(Exits with code 1 if there are uncommitted changes to generated files).
Deployment: The
./utils/deploy.shscript 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/:idto view storage used and storage limit for that user - Storage Limits Config: Open
/admin/system-settingsto 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.
# 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=UnitRunning tests locally (outside Docker):
If you need to run tests on your local machine:
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 --parallelFrontend (Vitest)
cd frontend
# Run all tests
bun test
# Interactive UI
bun run test:ui
# Coverage report
bun run test:coverageEnd-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:
# From frontend/
cd frontend
bun run e2e # headless run
bun run e2e:ui # interactive UI
bun run e2e:report # open last HTML reportIf Playwright browsers are missing on your machine, install them once:
cd frontend
bun x playwright install chromiumStatic Analysis & Quality Gates
Code Quality (Formatting)
Run Laravel Pint to automatically format code according to PSR-12 and Laravel conventions.
# From the backend directory
cd backend
./vendor/bin/pintPHPStan (Backend Type Analysis)
PHPStan enforces type safety and catches bugs at write-time using static analysis. Currently configured at Level 5.
Run analysis:
cd backend
composer phpstanDeptrac (Architecture Layer Enforcement)
Deptrac prevents architectural violations by enforcing allowed dependencies between layers.
Run analysis:
cd backend
composer deptracAsset Management
Updating Icons
Use utils/update_icon.sh to regenerate the favicon, PWA icons, and manifest whenever the branding icon changes.
./utils/update_icon.sh /absolute/path/to/new/icon.pngThe 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.