# Research: Base Architecture - Foundation Layers

**Feature**: 004-base-architecture
**Date**: 2026-06-04

---

## 1. Laravel Eloquent Model Relationship Ordering

**Decision**: Use explicit ordering in HasMany relationship definitions.

**Rationale**: Laravel 11+ supports defining default ordering directly in relationship methods. For `installments()`, use `orderBy('installment_number', 'asc')`. For `auditLogs()`, use `orderBy('created_at', 'desc')`. This ensures collections are always sorted consistently without manual intervention.

```php
// Contract model
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');
}
```

**Alternatives Considered**:
- Scoped relationships with custom constraint methods
- Global scopes on models for ordering
- Collection macro for ordering on-load

---

## 2. Laravel Repository Pattern - BaseRepositoryInterface & BaseEloquentRepository

**Decision**: Create a generic BaseRepositoryInterface with standard CRUD methods that all domain repositories extend, with binding in AppServiceProvider.

**Rationale**: The codebase already demonstrates this pattern in `AdminRepositoryInterface`. A BaseRepositoryInterface provides consistency across the application, reduces code duplication, and makes testing easier by allowing mock implementations.

```php
interface BaseRepositoryInterface
{
    public function all(array $columns = ['*']): Collection;
    public function find(int $id): ?Model;
    public function findOrFail(int $id): Model;
    public function create(array $data): Model;
    public function update(int $id, array $data): Model;
    public function delete(int $id): bool;
    public function paginate(int $perPage = 20): LengthAwarePaginator;
}
```

**Alternatives Considered**:
- Skip BaseRepositoryInterface - each repository defines its own contract
- Use generic type: `class EloquentRepository<T extends Model>`
- Use Trait for common methods instead of inheritance

---

## 3. Laravel BaseResource Customization

**Decision**: Create BaseResource extending JsonResource that wraps responses with `success`, `message`, `data` fields, complementing the existing ApiResponseHelper functions.

**Rationale**: The codebase uses a functional helper approach in `ApiResponseHelper.php`. A BaseApiResource provides a reusable Resource class for consistent structure when transforming models/collections.

```php
class BaseResource extends JsonResource
{
    public function toArray($request): array
    {
        return [
            'success' => true,
            'message' => $this->getMessage(),
            'data' => parent::toArray($request),
        ];
    }
}
```

**Alternatives Considered**:
- Use API Resource classes only (no helpers)
- Use Response macro
- Use dedicated ApiResponse class

---

## 4. Laravel Exception Handler Mapping

**Decision**: Use Laravel 11's `withExceptions()` in `bootstrap/app.php` combined with `config/exception-classes.php` mapping to ApiResponseHelper/CostumErrorResponse methods.

**Rationale**: The codebase uses a hybrid approach that delegates to handler functions. The `CostumErrorResponse.php` demonstrates individual handler functions for each exception type. This pattern is cleaner than overriding the Handler class.

```php
// bootstrap/app.php
->withExceptions(function (Exceptions $exceptions) {
    $exceptions->renderable(function (ModelNotFoundException $e) {
        return modelNotFoundResponse(Model::class);
    });
    // etc.
});
```

**Alternatives Considered**:
- Extend Handler class with `render()` method overrides (Laravel 10 style)
- Register handlers via Service Provider
- Use third-party package

---

## 5. Laravel Queue Database Driver Configuration

**Decision**: Use database queue driver with jobs table, job batching enabled, and failed jobs table. Configure retry_after based on job longest runtime.

**Rationale**: The codebase already implements this correctly in `config/queue.php`. Laravel defaults include the jobs table migration.

**Configuration**:
```env
QUEUE_CONNECTION=database
```

**Alternatives Considered**:
- Redis queue driver (better performance, requires additional package)
- Sync driver for development
- AWS SQS for serverless deployments

---

## Key Findings Summary

| Topic | Decision |
|-------|----------|
| Model Relationships | Explicit ordering in relationship definitions |
| Repository Pattern | BaseRepositoryInterface + BaseEloquentRepository with AppServiceProvider binding |
| BaseResource | Extend JsonResource with success/message/data wrapper |
| Exception Handler | Use withExceptions() in bootstrap/app.php mapping to helper functions |
| Queue | Database driver with existing Laravel jobs table |