# Quickstart: Base Architecture - Foundation Layers

**Feature**: 004-base-architecture

## Overview

This feature creates the foundational architecture layer: 8 Eloquent models, Repository pattern infrastructure, BaseResource for unified API responses, Exception Handler integration, and Queue configuration.

## File Structure

```
app/
├── Models/
│   └── User.php                           ← User model with hard immutability
├── Domains/
│   ├── Auth/Models/Admin.php             ← Admin with HasRoles + admin guard
│   ├── Contract/Models/
│   │   ├── Contract.php                   ← Contract with relationships
│   │   └── Installment.php                ← Installment with contract relationship
│   ├── Payment/Models/
│   │   ├── Payment.php                    ← Payment with contract + auditLogs
│   │   └── PaymentAuditLog.php            ← PaymentAuditLog with relationships
│   ├── Agent/Models/AgentSharesLog.php   ← AgentSharesLog with agent relationship
│   └── Notification/Models/NotificationTemplate.php
├── Shared/
│   ├── Repositories/
│   │   ├── Contracts/BaseRepositoryInterface.php
│   │   └── Eloquent/BaseEloquentRepository.php
│   └── Http/Resources/BaseResource.php
├── Exceptions/
│   └── Handler.php                        ← Exception mapping (modify existing)
└── Providers/
    └── AppServiceProvider.php             ← Repository bindings
```

## Key Implementation Details

### 1. User Model - Hard Immutability

```php
// app/Models/User.php
public function delete(): void
{
    throw new RuntimeException('Users cannot be deleted');
}

public function destroy($ids): void
{
    throw new RuntimeException('Users cannot be deleted');
}
```

### 2. Contract Model - Ordered Relationships

```php
// app/Domains/Contract/Models/Contract.php
public function installments(): HasMany
{
    return $this->hasMany(Installment::class)->orderBy('installment_number', 'asc');
}

public function auditLogs(): HasMany
{
    return $this->hasMany(PaymentAuditLog::class)->orderBy('created_at', 'desc');
}
```

### 3. Repository Binding

```php
// app/Providers/AppServiceProvider.php
public function register(): void
{
    $this->app->bind(BaseRepositoryInterface::class, BaseEloquentRepository::class);
}
```

### 4. Exception Handler Mapping

```php
// bootstrap/app.php
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->renderable(function (ModelNotFoundException $e) {
        return modelNotFoundResponse(Model::class);
    });
    $exceptions->renderable(function (ValidationException $e) {
        return unprocessableResponse($e->errors());
    });
    $exceptions->renderable(function (AuthorizationException $e) {
        return forbiddenResponse('Access denied');
    });
});
```

### 5. Queue Configuration

```env
# .env
QUEUE_CONNECTION=database
```

## Verification Commands

```bash
# Verify all models exist and can be instantiated
php artisan tinker --execute="
    \$models = [\App\Models\User::class, \App\Domains\Auth\Models\Admin::class,
               \App\Domains\Contract\Models\Contract::class, \App\Domains\Contract\Models\Installment::class,
               \App\Domains\Payment\Models\Payment::class, \App\Domains\Payment\Models\PaymentAuditLog::class,
               \App\Domains\Agent\Models\AgentSharesLog::class, \App\Domains\Notification\Models\NotificationTemplate::class];
    foreach (\$models as \$model) {
        echo class_exists(\$model) ? \$model . \" OK\n\" : \$model . \" MISSING\n\";
    }
"

# Verify User deletion throws exception
php artisan tinker --execute="
    try {
        \$user = \App\Models\User::first();
        \$user->delete();
    } catch (\RuntimeException \$e) {
        echo 'Exception thrown: ' . \$e->getMessage();
    }
"

# Verify repository interface contract
php artisan tinker --execute="
    \$repo = app(\App\Shared\Repositories\Contracts\BaseRepositoryInterface::class);
    echo 'BaseRepositoryInterface bound: ' . (\$repo instanceof \App\Shared\Repositories\Eloquent\BaseEloquentRepository ? 'YES' : 'NO');
"

# Verify jobs table exists
php artisan queue:monitor --filter=table_exists 2>/dev/null || php artisan migrate:status --database=jobs 2>/dev/null || echo "Check jobs table manually"

# Verify queue connection
php artisan env | grep QUEUE_CONNECTION
```

## Testing

```bash
# Run model tests
php artisan test --filter=BaseArchitecture

# Or run all tests
php artisan test
```

## Common Issues

1. **Relationship ordering not applied**: Ensure `orderBy` is called in the relationship method, not in the controller
2. **Repository not binding**: Check `AppServiceProvider::register()` method has the binding
3. **Exception mapping not working**: Verify `bootstrap/app.php` has `withExceptions()` configured
4. **Queue not working**: Ensure `QUEUE_CONNECTION=database` in `.env` and `php artisan queue:work` is running