Skip to content

Development Process

A guide to the day-to-day development workflow for the CPR backend.

First-Time Setup

bash
# 1. Clone the repository
git clone <repo-url>
cd cpr-backend

# 2. Run the full setup
composer setup

# 3. Or set up manually:
composer install
cp .env.example .env
php artisan key:generate
php artisan migrate --seed
npm install

Using Docker (Sail)

bash
./vendor/bin/sail up -d
./vendor/bin/sail artisan migrate --seed

Daily Workflow

Starting Development

bash
# Start all services (Laravel server, queue worker, log watcher, Vite)
composer dev

This starts:

  • Laravel server at http://localhost:8000
  • Queue worker for background jobs
  • Pail for real-time log monitoring
  • Vite dev server at http://localhost:5173

Adding a New Feature

Follow this order when building a new feature:

1. Database Layer

bash
php artisan make:migration create_feature_table
php artisan make:model FeatureName
php artisan make:factory FeatureNameFactory
php artisan make:seeder FeatureNameSeeder
php artisan migrate

2. Data Access Layer

  • Create a repository in app/Repositories/
  • Create a contract/interface in app/Contracts/Repositories/
  • Register bindings in RepositoryServiceProvider

3. Business Logic Layer

  • Create action classes in app/Actions/ for CRUD operations
  • Create a service class in app/Services/
  • Create DTOs if needed for complex data flows

4. API Layer

  • Create a controller in app/Http/Controllers/Api/V1/
  • Create Form Requests in app/Http/Requests/ (Store and Update variants)
  • Create an API Resource in app/Http/Resources/
  • Add routes in routes/api/v1/

5. Tests

bash
php artisan make:test Feature/Api/V1/FeatureNameTest

Write tests for:

  • Successful CRUD operations
  • Validation errors (422)
  • Unauthorized access (401)
  • Missing branch context (400)
  • Forbidden access (403)

6. Run Quality Checks

bash
# Format code
composer pint

# Static analysis
composer stan

# Run tests
composer test

Adding a New Clinical Exam Module

Since many modules follow the same pattern, here's the specific flow for exam types:

  1. Migration: patient_visit_id FK, exam-specific columns
  2. Model with LogsActivity trait, belongs to PatientVisit
  3. Repository extending AbstractFilterableRepository
  4. Service with CRUD methods
  5. Controller with standard CRUD endpoints
  6. Store/Update Form Requests
  7. API Resource
  8. Route file in routes/api/v1/ (added to branch-scoped group)
  9. Tests for all CRUD operations

Environment Configuration

Development (.env.example)

env
APP_ENV=local
APP_DEBUG=true
DB_CONNECTION=sqlite
CACHE_STORE=database
QUEUE_CONNECTION=sync

API Development (.env.example.api)

env
APP_ENV=local
APP_DEBUG=true
DB_CONNECTION=mysql
CACHE_STORE=redis
QUEUE_CONNECTION=redis
ENABLE_BRANCH_ISOLATION=true
REQUIRE_BRANCH_CONTEXT=true

Debugging

  • API responses: Check storage/logs/laravel.log or use php artisan pail
  • Database queries: Enable query logging or use DB::enableQueryLog()
  • Authentication: Verify token in personal_access_tokens table
  • Branch context: Check X-Branch-Id header and branch_users pivot
  • Errors in production: Check Sentry dashboard

CPR - Clinical Patient Records