# CLAUDE.md - Backend System Context

**Project**: ShowPrima Event Ticketing Platform
**Architecture**: Domain-Driven Design (DDD)
**Last Updated**: 2026-02-03
**Phase**: Post-Decomposition (Domains Implemented)

---

## 🏗️ Architecture Overview

### Domain-Driven Design (DDD)

ShowPrima uses **strict DDD** with bounded contexts and anti-corruption layers. The architecture enforces complete domain isolation with cross-domain communication through explicit contracts.

**5 Implemented Domains**:

1. **Customer** (5/5★) - Account management, profiles, order history, preferences
2. **Ordering** (5/5★) - Order processing, payments, refunds, pricing
3. **Gala** (5/5★) - Event management, publishing, scheduling, visibility
4. **Venue** (5/5★) - Venue/seat management, pricing tiers, templates
5. **Notifications** (4/5★) - Email templates, delivery, tracking

**Key Principles**:
- Domains communicate **ONLY** via Contracts (interfaces)
- No direct model relationships across domains
- Type-safe enums (no magic strings)
- Max 500 LOC per file (enforced via code review)
- Read/Management service separation

**Domain Structure**:
```
app/Domains/{DomainName}/
├── Contracts/              # Anti-corruption layer interfaces
├── Models/                 # Domain models
├── Services/               # Read/Management/Specialized
│   ├── {Domain}ReadService.php
│   ├── {Domain}ManagementService.php
│   └── {Specialized}Service.php
├── ValueObjects/           # DDD value objects
├── Events/                 # Domain events
├── Gateways/              # External integrations (Ordering only)
└── {Domain}ServiceProvider.php
```

**Example Domain Organization** (Ordering):
```
app/Domains/Ordering/
├── Contracts/
│   ├── OrderReadRepositoryInterface.php
│   └── PaymentProcessorInterface.php
├── Models/
│   ├── Order.php
│   ├── OrderLineItem.php
│   └── SeatReservation.php
├── Services/
│   ├── OrderReadService.php
│   ├── OrderManagementService.php
│   ├── PricingService.php
│   └── RefundService.php
├── ValueObjects/
│   ├── Money.php
│   └── OrderNumber.php
├── Events/
│   ├── OrderPaid.php
│   └── OrderRefunded.php
├── Gateways/
│   ├── StripeGateway.php
│   └── RevolutGateway.php
└── OrderingServiceProvider.php
```

### Anti-Corruption Layers (ACL)

Each domain exposes contracts for cross-domain communication to prevent tight coupling and enable independent evolution:

**Active Contracts**:
- `GalaToOrderingContract` - Event availability, capacity, pricing tiers
- `OrderingToNotificationsContract` - Order confirmations, receipts, refund notices
- `OrderingToCustomerContract` - Order history, customer purchase data
- `CustomerToIAMContract` - Profile data, authentication context
- `VenueToOrderingContract` - Seat availability, pricing, venue templates

**Location**: `app/Contracts/`

**Contract Implementation Pattern**:
```php
// 1. Define interface in app/Contracts/
namespace App\Contracts;

interface GalaToOrderingContract {
    public function getPublishedEvents(): Collection;
    public function getEventById(string $eventId): ?Event;
    public function checkCapacity(string $eventId): int;
}

// 2. Implement in provider domain (Gala)
namespace App\Domains\Gala\Services;

use App\Contracts\GalaToOrderingContract;

class GalaContractService implements GalaToOrderingContract {
    public function getPublishedEvents(): Collection {
        return Event::where('is_published', true)->get();
    }
    // ...
}

// 3. Register in provider's service provider
namespace App\Domains\Gala;

class GalaServiceProvider extends ServiceProvider {
    public function register() {
        $this->app->singleton(
            GalaToOrderingContract::class,
            GalaContractService::class
        );
    }
}

// 4. Inject in consumer domain (Ordering)
namespace App\Domains\Ordering\Services;

use App\Contracts\GalaToOrderingContract;

class OrderManagementService {
    public function __construct(
        private GalaToOrderingContract $galaContract
    ) {}

    public function createOrder(string $eventId) {
        $event = $this->galaContract->getEventById($eventId);
        // ...
    }
}
```

---

## 🔄 Development Workflow

### Worktree-Based Development

Use dedicated worktrees for domain-specific work to enable parallel development:

**Active Worktrees**:
- `/Users/charlie/code/showprima` - **Production** (main branch)
- `/Users/charlie/code/showprima-order-decomp` - Order domain work (feature/decomp-sprint)
- `/Users/charlie/code/showprima-gala-decomp` - Gala domain work (feature/gala-decomp)
- `/Users/charlie/code/showprima-notif-decomp` - Notification domain work (feature/notif-decomp)

**Worktree Commands**:
```bash
# Create new domain worktree
git worktree add ../showprima-iam-decomp feature/iam-decomp

# List all worktrees
git worktree list

# Remove worktree when done
git worktree remove ../showprima-iam-decomp
```

### Merge Strategy

```
feature/domain-decomp → dev → staging → main → production
      ↓                  ↓       ↓        ↓
  Development      Integration  QA    Production
```

**Critical Rules**:
- ✅ Always work in decomp worktree for domain refactors
- ✅ Merge via PR with full test suite passing
- ✅ Run domain boundary enforcement tests before merge
- ❌ Never refactor domains in main worktree
- ❌ Never merge without API contract verification

### Domain Decomposition Workflow

**Step-by-Step Process**:
1. **Create feature worktree** for domain work
2. **Implement domain** following DDD patterns (see `/showprima-order-decomp` as reference)
3. **Add domain boundary enforcement tests** to verify isolation
4. **Verify API contracts unchanged** (100% backward compatibility)
5. **Run full test suite** (PHPUnit + E2E)
6. **Merge via PR** with comprehensive test evidence

**Reference Implementation**:
- See `/Users/charlie/code/showprima-order-decomp` as the **Golden Standard**
- Read `/Users/charlie/code/docs/ORDER-DECOMP-COMPLETION-REPORT-2026-01-29.md`

---

## 🧪 Testing Strategy

### Test Pyramid

**Backend Test Coverage** (151 tests):
- **Unit Tests** (63): Domain services, value objects, enums, business logic
- **Feature Tests** (88): API endpoints, integration flows, database operations
- **E2E Tests** (48): Customer journeys, domain enforcement, data retention

**Test Execution**:
```bash
# Run all backend tests
vendor/bin/phpunit

# Run unit tests only
vendor/bin/phpunit tests/Unit/

# Run feature tests only
vendor/bin/phpunit tests/Feature/

# Run E2E API tests
npm run test:api
```

### Domain Boundary Enforcement Tests

**Critical for DDD Architecture**: Run domain boundary tests to verify strict isolation:

```bash
# Run domain enforcement suite (14 tests)
npm run test:api:domain
```

**What These Tests Verify** (14 tests):
- ✅ Gala domain isolation (no direct model dependencies)
- ✅ Notifications decoupling (uses contracts only)
- ✅ Customer self-containment (bounded context)
- ✅ Cross-domain contracts functioning correctly
- ✅ Database access patterns respect boundaries
- ✅ No magic strings (enum usage verification)
- ✅ Service layer separation (Read vs Management)

**Test Location**: `tests/api/domain-enforcement/*.spec.ts`

### E2E Test Suite

**Comprehensive API Testing** (48 tests, 27/31 passing):

```bash
# Run full E2E suite
npm run test:api

# Run with UI for debugging
npm run test:api:ui

# Run specific test file
npx playwright test tests/api/customer-journey.spec.ts
```

**Test Coverage**:
1. **Customer Journeys** (18 tests):
   - Complete booking flow (hold → confirm → payment)
   - Order history retrieval
   - Customer profile management
   - Multi-seat booking scenarios

2. **Domain Enforcement** (14 tests):
   - Cross-domain contract validation
   - Bounded context verification
   - Anti-corruption layer testing

3. **Data Retention** (17 tests - awaiting backend perf fix):
   - Order persistence
   - Payment record retention
   - Line items generation

**Known Issues**:
- `/api/seats/confirm` timeout (PDF generation >30s) - performance bottleneck, not logic bug
- 4 tests failing due to timeout (tracked in backlog)

**Test Database**:
- MySQL (`showprima_test`) for 100% production parity
- Schema managed via `database/schema/mysql-schema.sql`
- `RefreshDatabase` trait for test isolation

---

## 📐 Domain-Specific Patterns

### Type-Safe Enums

**Replace magic strings with type-safe enums** for reliability and IDE support:

```php
// ❌ Old (magic string - error-prone)
if ($order->status === 'paid') {
    // "PAID", "Paid", "paid" all different!
}

// ✅ New (type-safe enum)
use App\Enums\OrderStatus;

if ($order->statusEnum() === OrderStatus::PAID) {
    // Autocomplete + compile-time validation
}
```

**Available Enums** (7 total):

**Ordering Domain**:
- `OrderStatus` - Order lifecycle states (`PENDING`, `PAID`, `CANCELLED`, `REFUNDED`)
- `PaymentGateway` - Payment providers (`STRIPE`, `REVOLUT`, `PAYPAL`, `NBE`)
- `PaymentStatus` - Payment outcomes (`PENDING`, `COMPLETED`, `FAILED`, `REFUNDED`)
- `PaymentInstrument` - Payment methods (`CARD`, `BANK_TRANSFER`, `CASH`, `MOBILE`)
- `Currency` - Currency codes (`EUR`, `USD`, `EGP`)

**Venue Domain**:
- `SeatType` - Seat categories (`TABLE`, `INDIVIDUAL`, `STANDING`, `VIP`)

**Gala Domain**:
- `GalaStatus` - Event states (`DRAFT`, `PUBLISHED`, `ARCHIVED`, `CANCELLED`)

**Enum Implementation Pattern**:
```php
namespace App\Enums;

enum OrderStatus: string {
    case PENDING = 'pending';
    case PAID = 'paid';
    case CANCELLED = 'cancelled';
    case REFUNDED = 'refunded';

    // Backward compatibility helper
    public static function normalize(string $value): self {
        return match(strtolower($value)) {
            'pending' => self::PENDING,
            'paid', 'completed' => self::PAID,
            'cancelled', 'canceled' => self::CANCELLED,
            'refunded' => self::REFUNDED,
            default => throw new \ValueError("Invalid status: {$value}"),
        };
    }

    // UI display helper
    public function label(): string {
        return match($this) {
            self::PENDING => 'Awaiting Payment',
            self::PAID => 'Paid',
            self::CANCELLED => 'Cancelled',
            self::REFUNDED => 'Refunded',
        };
    }
}
```

**Using Enums in Models**:
```php
use App\Enums\OrderStatus;

class Order extends Model {
    protected $casts = [
        'status' => OrderStatus::class,
    ];

    // Backward compatibility accessor
    public function statusEnum(): OrderStatus {
        return is_string($this->status)
            ? OrderStatus::normalize($this->status)
            : $this->status;
    }
}
```

**Location**: `app/Enums/`

### Value Objects

**Immutable, validated data structures** that encapsulate business rules:

```php
namespace App\Domains\Ordering\ValueObjects;

use App\Enums\Currency;

final readonly class Money {
    private function __construct(
        public int $cents,
        public Currency $currency
    ) {
        if ($cents < 0) {
            throw new \InvalidArgumentException('Amount cannot be negative');
        }
    }

    public static function fromCents(int $cents, Currency $currency): self {
        return new self($cents, $currency);
    }

    public static function fromAmount(float $amount, Currency $currency): self {
        return new self((int) round($amount * 100), $currency);
    }

    public function multiply(int $factor): self {
        return new self($this->cents * $factor, $this->currency);
    }

    public function add(self $other): self {
        if ($this->currency !== $other->currency) {
            throw new \InvalidArgumentException('Currency mismatch');
        }
        return new self($this->cents + $other->cents, $this->currency);
    }

    public function toFloat(): float {
        return $this->cents / 100;
    }
}
```

**Usage Example**:
```php
use App\Domains\Ordering\ValueObjects\Money;
use App\Enums\Currency;

$ticketPrice = Money::fromCents(1500, Currency::EUR); // €15.00
$total = $ticketPrice->multiply(2); // €30.00
$withFee = $total->add(Money::fromCents(75, Currency::EUR)); // €30.75
```

**Location**: `app/Domains/{Domain}/ValueObjects/`

### Domain Events

**Async communication between domains** using Laravel's event system:

```php
// 1. Define event in provider domain
namespace App\Domains\Ordering\Events;

class OrderPaid {
    public function __construct(
        public readonly Order $order,
        public readonly Payment $payment
    ) {}
}

// 2. Dispatch event in domain service
namespace App\Domains\Ordering\Services;

use App\Domains\Ordering\Events\OrderPaid;

class OrderManagementService {
    public function confirmPayment(string $orderId) {
        $order = Order::findOrFail($orderId);
        $order->update(['status' => OrderStatus::PAID]);

        event(new OrderPaid($order, $order->payment));
    }
}

// 3. Listen in consumer domain
namespace App\Domains\Notifications\Listeners;

use App\Domains\Ordering\Events\OrderPaid;
use App\Mail\PaymentConfirmationMail;
use Illuminate\Support\Facades\Mail;

class SendOrderConfirmation {
    public function handle(OrderPaid $event) {
        Mail::to($event->order->customer_email)
            ->queue(new PaymentConfirmationMail($event->order));
    }
}

// 4. Register listener in EventServiceProvider
protected $listen = [
    OrderPaid::class => [
        SendOrderConfirmation::class,
    ],
];
```

**Location**: `app/Domains/{Domain}/Events/`

### Service Provider Pattern

**Each domain registers its services** via dedicated service provider:

```php
namespace App\Domains\Ordering;

use Illuminate\Support\ServiceProvider;
use App\Domains\Ordering\Contracts\OrderReadRepositoryInterface;
use App\Domains\Ordering\Repositories\OrderReadRepository;

class OrderingServiceProvider extends ServiceProvider {
    public function register() {
        // Register repositories
        $this->app->singleton(
            OrderReadRepositoryInterface::class,
            OrderReadRepository::class
        );

        // Register services
        $this->app->singleton(OrderManagementService::class);
        $this->app->singleton(PricingService::class);

        // Register gateways
        $this->app->singleton(StripeGateway::class);
    }

    public function boot() {
        // Load migrations
        $this->loadMigrationsFrom(__DIR__ . '/database/migrations');

        // Load routes
        $this->loadRoutesFrom(__DIR__ . '/routes.php');
    }
}
```

**Register in `config/app.php`**:
```php
'providers' => [
    // ...
    App\Domains\Ordering\OrderingServiceProvider::class,
    App\Domains\Gala\GalaServiceProvider::class,
    App\Domains\Customer\CustomerServiceProvider::class,
    App\Domains\Venue\VenueServiceProvider::class,
    App\Domains\Notifications\NotificationsServiceProvider::class,
],
```

---

## 📋 Contract Interface Catalog

### Cross-Domain Contracts

| Contract | Provider | Consumer | Purpose | Methods |
|----------|----------|----------|---------|---------|
| `GalaToOrderingContract` | Gala | Ordering | Event availability, capacity | `getPublishedEvents()`, `getEventById()`, `checkCapacity()` |
| `OrderingToNotificationsContract` | Ordering | Notifications | Order confirmations | `getOrderDetails()`, `getCustomerEmail()`, `getLineItems()` |
| `OrderingToCustomerContract` | Ordering | Customer | Order history | `getCustomerOrders()`, `getOrderCount()`, `getTotalSpent()` |
| `CustomerToIAMContract` | Customer | IAM | Profile data | `getProfile()`, `updateProfile()`, `getPreferences()` |
| `VenueToOrderingContract` | Venue | Ordering | Seat availability | `getSeatsByEvent()`, `getSeatPricing()`, `getVenueLayout()` |

**Implementation Pattern**:

1. **Define interface** in `app/Contracts/`:
```php
namespace App\Contracts;

interface GalaToOrderingContract {
    public function getPublishedEvents(): Collection;
    public function getEventById(string $eventId): ?Event;
    public function checkCapacity(string $eventId): int;
}
```

2. **Implement in provider domain**:
```php
namespace App\Domains\Gala\Services;

use App\Contracts\GalaToOrderingContract;

class GalaContractService implements GalaToOrderingContract {
    public function getPublishedEvents(): Collection {
        return Event::where('is_published', true)->get();
    }

    public function getEventById(string $eventId): ?Event {
        return Event::find($eventId);
    }

    public function checkCapacity(string $eventId): int {
        return Seat::where('event_id', $eventId)
            ->where('is_active', true)
            ->count();
    }
}
```

3. **Inject via dependency injection** in consumer:
```php
namespace App\Domains\Ordering\Services;

use App\Contracts\GalaToOrderingContract;

class OrderManagementService {
    public function __construct(
        private GalaToOrderingContract $galaContract
    ) {}

    public function getAvailableEvents() {
        return $this->galaContract->getPublishedEvents();
    }
}
```

**Location**: `app/Contracts/`

---

## 💾 Database Migration Safety

**ALWAYS** use safe migration practices to prevent data loss:

### 1. **Backup First**

```bash
# Automatic backup (recommended)
php artisan migrate:safe

# Manual backup
./scripts/backup-db.sh
```

### 2. **Run on Dev Environment**

```bash
# Test on local development first
php artisan migrate --env=local

# Then test on dev server
ssh globalgalashow@glo.globalgala.com
cd ~/public_html/dev
./scripts/deploy-dev.sh
```

### 3. **Test Rollback**

```bash
# Verify rollback works
php artisan migrate:rollback

# Re-run migration
php artisan migrate
```

### 4. **Enum Migration Pattern**

**Use Strangler Fig pattern** for backward compatibility:

```php
// Migration: Add new enum column
Schema::table('orders', function (Blueprint $table) {
    $table->string('status_new')->nullable()->after('status');
});

// Model: Add normalize() method
public function statusEnum(): OrderStatus {
    return is_string($this->status)
        ? OrderStatus::normalize($this->status)
        : $this->status;
}

// Later migration: Drop old column after full migration
Schema::table('orders', function (Blueprint $table) {
    $table->dropColumn('status'); // Only after verified safe
    $table->renameColumn('status_new', 'status');
});
```

**Never Drop Columns Immediately**:
- ✅ Add new column alongside old
- ✅ Dual-write to both columns
- ✅ Verify data migrated correctly
- ✅ Update all application code
- ✅ Only then drop old column (weeks later)

### 5. **Available Database Tools**

**Backup Database** (`scripts/backup-db.sh`):
```bash
cd /Users/charlie/code/showprima
./scripts/backup-db.sh
```
- Auto-detects MySQL/SQLite from `.env`
- Creates compressed SQL dumps in `database/backups/mysql/`
- Includes metadata and integrity verification
- Automatic cleanup (keeps last 10)

**Restore Database** (`scripts/restore-db.sh`):
```bash
./scripts/restore-db.sh backup_20260203_143022.sql.gz
```
- Pre-restore safety backup
- Verification after restore

**Compare Databases** (`scripts/compare-db.sh`):
```bash
./scripts/compare-db.sh backup_20260203_143022.sql.gz
```
- Shows row count differences
- Schema change detection
- Migration differences

**Safe Migration** (`php artisan migrate:safe`):
```bash
php artisan migrate:safe

# Options:
php artisan migrate:safe --force        # Skip production confirmation
php artisan migrate:safe --seed         # Seed after migration
php artisan migrate:safe --skip-backup  # NOT RECOMMENDED
```

**See**: `/Users/charlie/code/docs/architecture/database-migration-patterns.md`

---

## 🚨 Emergency Protocols

### Critical Response Procedures

**1. API Changes**:
- ✅ Update frontend types immediately in `/showprima-frontend`
- ✅ Add deprecation warnings before removing endpoints
- ✅ Version breaking changes (e.g., `/api/v2/`)
- ✅ Run full E2E test suite before deploy

**2. Refactoring**:
- ✅ Always work in decomp worktree (not main)
- ✅ Use `/showprima-order-decomp` as reference
- ✅ Run domain boundary tests before commit
- ❌ Never refactor in production worktree

**3. Domain Violations**:
```bash
# Before commit, verify domain boundaries
npm run test:api:domain

# Should see:
# ✓ Gala domain isolation (14/14 tests passing)
```

**4. Rollback Capability**:
- Each domain has independent rollback
- Git worktrees enable fast rollback
- Database backups enable data rollback

### Emergency Reset Tools

**Health Check** (`scripts/health-check-comprehensive.sh`):
```bash
# Run after deployment
./scripts/health-check-comprehensive.sh

# With automated fixes
./scripts/health-check-comprehensive.sh --fix

# Verbose diagnostics
./scripts/health-check-comprehensive.sh --verbose
```

**Emergency Reset** (`scripts/emergency-reset.sh`):
```bash
# Clear all caches (30 seconds)
./scripts/emergency-reset.sh

# Full reset with vendor reinstall (2-5 minutes)
./scripts/emergency-reset.sh --full

# With database backup first
./scripts/emergency-reset.sh --full --backup-first
```

### Latest Architecture Documentation

**Critical Reading**:
- `/Users/charlie/code/docs/ORDER-DECOMP-COMPLETION-REPORT-2026-01-29.md` - Domain decomposition guide
- `/Users/charlie/code/docs/architecture/domain-modernization-initiative.md` - DDD architecture overview
- `/Users/charlie/code/docs/e2e-test-suite-complete-2026-01-29.md` - Testing guide
- `/Users/charlie/code/CLAUDE.md` - **Root context** (multi-repo coordination)

---

## 🚀 Deployment

**See**: `docs/deployment/MASTER_DEPLOYMENT_GUIDE.md` for complete deployment procedures.

**Quick Deploy** (Dev Server):
```bash
ssh globalgalashow@glo.globalgala.com
cd ~/public_html/dev
./scripts/deploy-dev.sh
```

**What Deploy Script Does**:
1. ✅ Pre-deployment validation (environment, database, PHP version, permissions)
2. ✅ Database backup (auto-detects MySQL, creates compressed backup)
3. ✅ Code deployment (git pull, composer install, cache clear)
4. ✅ Database deployment (migrations, role seeding if needed)
5. ✅ Queue worker deployment (restart with bulk queue support)
6. ✅ Post-deployment validation (Laravel boots, migrations complete)
7. ✅ Health check (queue system, email system, worker processes)
8. ✅ Status report (deployment metadata, quick actions)
9. ✅ Deployment log (timestamped record in `storage/logs/`)

**Queue Worker Configuration**:
```bash
# Queue priority: critical > default > tickets > bulk
--queue=critical,default,tickets,bulk

# critical: Password resets, 2FA, urgent emails
# default: Transactional emails (order confirmations, tickets)
# tickets: Ticket-specific operations
# bulk: Non-urgent bulk invitations, campaigns
```

---

## 📧 Email System Architecture

**CRITICAL**: Queue worker MUST be running for emails to send!

### Email System Overview

Queue-based email system for reliability and scalability:

**Components**:
1. **Mailable Classes** (`app/Mail/*.php`) - Email templates
2. **Queue System** (database driver) - Pending email jobs
3. **Queue Worker** (background process) - Processes jobs, sends emails
4. **Mailpit** (local SMTP) - Captures emails in development (http://localhost:8025)

### Email Sending Pattern

**✅ CORRECT** (All emails use this):
```php
use App\Mail\WelcomeUserMail;
use Illuminate\Support\Facades\Mail;

// Queue email (automatic retry, non-blocking)
Mail::to($user->email)->queue(new WelcomeUserMail($user));
```

**❌ INCORRECT** (Never use):
```php
// Synchronous send (blocks request, no retry)
Mail::to($user->email)->send(new WelcomeUserMail($user));
```

### All Mailables Implement ShouldQueue

14+ Mailable classes with automatic queueing:
- ✅ `WelcomeUserMail` - New user welcome
- ✅ `WelcomeBackMail` - Account setup invitations
- ✅ `PaymentConfirmationMail` - Order confirmations
- ✅ `PasswordResetMail` - Password reset links
- ✅ `GenericTemplateMail` - EmailService emails

### Queue Worker - REQUIRED

**Start Queue Worker**:
```bash
# Development
./scripts/start-queue-worker.sh

# Or start all services at once
./scripts/start-dev-servers.sh
```

**Without Queue Worker**:
- ❌ Emails queued to database but **never sent**
- ❌ Jobs accumulate in `jobs` table
- ❌ Users don't receive confirmations

### Development Setup

**Quick Start**:
```bash
# Start everything at once
./scripts/start-dev-servers.sh

# Starts:
# - Laravel API (http://localhost:8000)
# - Queue Worker (processes emails)
# - Verifies Mailpit running
```

**View Emails**: http://localhost:8025 (Mailpit UI)

### Monitoring & Debugging

**Queue Statistics**:
```bash
# Live monitoring
./scripts/queue-monitor.sh

# One-time check
php artisan queue:monitor
```

**Failed Jobs**:
```bash
# View failed jobs
php artisan queue:failed

# Retry all
php artisan queue:retry all
```

---

## 🔀 Git Workflow & CI/CD

**CRITICAL**: Never push directly to `main` unless explicitly instructed.

### Branch Structure

- **`main`** - Production-ready code (protected)
- **`dev`** - Active development integration
- **`feature/*`** - Individual features
- **`fix/*`** - Bug fixes
- **`hotfix/*`** - Emergency production fixes

### Standard Development Workflow

```bash
# 1. Start from dev
git checkout dev
git pull origin dev
git checkout -b feature/your-feature-name

# 2. Make changes, commit regularly
git add .
git commit -m "feat: descriptive message"

# 3. Push feature branch
git push -u origin feature/your-feature-name

# 4. Create PR to dev (GitHub UI or gh CLI)

# 5. After approval: dev → staging → main
```

### Branch Progression

```
feature/* → dev → staging → main
   ↓         ↓       ↓        ↓
 Active   Integration  QA   Production
```

### Commit Message Conventions

Use conventional commits:
- `feat:` - New features
- `fix:` - Bug fixes
- `refactor:` - Code refactoring
- `test:` - Test additions
- `docs:` - Documentation
- `chore:` - Maintenance
- `db:` - Database migrations

### Rules & Guardrails

**DO**:
- ✅ Always work on feature branches
- ✅ Pull latest dev before creating feature branch
- ✅ Create PRs for all changes
- ✅ Test locally before pushing
- ✅ Backup before database changes
- ✅ Use `php artisan migrate:safe`

**DON'T**:
- ❌ Never push directly to main
- ❌ Never force push to shared branches
- ❌ Don't merge without review
- ❌ Don't commit broken code
- ❌ Don't skip database backups
- ❌ Don't commit `.env` files

---

## 📚 Documentation Index

**Latest Architecture Docs**:
- `/Users/charlie/code/docs/ORDER-DECOMP-COMPLETION-REPORT-2026-01-29.md` - **Domain decomposition guide**
- `/Users/charlie/code/docs/architecture/domain-modernization-initiative.md` - DDD overview
- `/Users/charlie/code/docs/e2e-test-suite-complete-2026-01-29.md` - Testing guide
- `/Users/charlie/code/CLAUDE.md` - **Root context** (multi-repo coordination)

**Deployment Docs**:
- `docs/deployment/MASTER_DEPLOYMENT_GUIDE.md` - Complete deployment procedures
- `docs/deployment/HEALTH_CHECK_RECOVERY_GUIDE.md` - Post-deployment verification
- `docs/deployment/CRON_STRATEGY_MASTER_PLAN.md` - Scheduled tasks

**Domain-Specific Docs**:
- `docs/TIER_SYSTEM_COMPLETE_FIX_SUMMARY.md` - Venue pricing tiers (authoritative)
- `docs/EMAIL_SYSTEM_QA_REVIEW.md` - Email system architecture
- `docs/payments/` - Payment gateway integration guides

**Working Papers** (`docs/`):
- Internal status reports
- Architecture audits
- Session notes

---

## 🛠️ Development Environment

**OS**: macOS (Darwin)
**Ports**:
- Backend API: `8000`
- Frontend Public: `3003`
- Frontend Admin: `3001`
- Frontend Ticketing: `3002`
- Frontend Scanner: `3004`

**Database**: MySQL (`showprima_dev`)
**Test Database**: MySQL (`showprima_test`)

**Dependencies**:
- **Backend**: `composer`, PHP 8.2+
- **Frontend**: `pnpm` (strictly enforced)

**PHP Version**:
- Required: PHP 8.0+
- Recommended: PHP 8.1-8.4
- NOT compatible: PHP 8.5+ (breaks DomPDF)

---

## 📖 Story Organization

**Backend-only stories**: `/Users/charlie/code/showprima/docs/stories/`

**Cross-repo stories** (backend + frontend): `/Users/charlie/code/docs/stories/`

See `/Users/charlie/code/CLAUDE.md` for complete story organization rules.

---

## 🔍 Common Development Commands

### Database Commands (USE SAFE VERSIONS)
```bash
# Run migrations (ALWAYS use safe version)
php artisan migrate:safe

# Backup database
./scripts/backup-db.sh

# Restore database
./scripts/restore-db.sh <backup_file>

# Compare databases
./scripts/compare-db.sh <backup_file>
```

### Testing Commands
```bash
# Run PHPUnit tests
vendor/bin/phpunit

# Run E2E tests
npm run test:api

# Run domain boundary tests
npm run test:api:domain

# Run with UI for debugging
npm run test:api:ui
```

### Laravel Commands
```bash
# Create migration
php artisan make:migration <name>

# Create model
php artisan make:model <name>

# Clear cache
php artisan cache:clear

# Queue monitoring
./scripts/queue-monitor.sh
```

### Email & Queue Commands
```bash
# Start queue worker (REQUIRED for emails!)
./scripts/start-queue-worker.sh

# Monitor queue
./scripts/queue-monitor.sh

# Test email system
./scripts/test-email-system.sh

# Check email health
php artisan email:check
```

---

**Agent Directives**:
- When asked to "Refactor domain", look at `/showprima-order-decomp` for the pattern
- When asked to "Fix bug" in production, work in `/showprima` (main worktree)
- Always check `docs/` for latest status reports before complex tasks
- Always run domain boundary tests before merging domain work
- Never refactor domains in main worktree (use decomp worktrees)
