# ABC Core Coding Standard (Phase 1.1)

## General Principles

- **Readability over cleverness.** Code is read more often than it is written.
- **Single Responsibility.** One class, one purpose.
- **DRY (Don't Repeat Yourself).** Extract shared logic to helpers, traits, or base classes.
- **Explicit over implicit.** No magic methods without documentation.
- **Configurable over hardcoded.** No literals in business logic; use `config()` or Constants.
- **Constants over strings.** Never use raw strings for banking types, statuses, or currencies.

## PHP Standards

- PHP 7.4+ compatible. Use typed properties and return types where possible.
- Always declare `strict_types=1` at the top of every PHP file.
- PSR-4 autoloading via namespace `App\`.
- Class names: `PascalCase`.
- Method names: `camelCase`.
- Constants: `UPPER_SNAKE_CASE`.
- Variables: `camelCase`.
- File names must match class names exactly.

## Architecture Rules

### Controllers

- Must extend `BaseController`.
- May only call `Services` or `Validators`. Never call `Repositories` directly.
- Must return `Response` or raw data (auto-wrapped to JSON).
- Must not contain business logic.
- Must not contain SQL.
- Must validate input before passing to services.

### Services

- Must extend `BaseService`.
- Contain ALL business logic.
- Must use `executeInTransaction()` for multi-step operations.
- Must call `Repositories` for data access; never access DB directly.
- Must log actions via `logAction()`.
- Must dispatch events via `EventDispatcher` instead of calling other services directly.
- Must be reusable by multiple controllers.
- Must use Constants for all type/status values.

### Repositories

- Must extend `BaseRepository`.
- Must implement `RepositoryInterface`.
- The ONLY place where SQL is allowed.
- Must use prepared statements for all dynamic values.
- Must return arrays or `BaseModel` instances, never raw PDO statements.
- Must not contain business logic.
- Must not call other repositories or services.

### Models

- Must extend `BaseModel`.
- Define `$fillable`, `$hidden`, and `$casts` explicitly.
- Use `HasUuid` trait if the model exposes data via API.
- Must be lightweight data containers.
- Must not contain business logic or SQL.

### Middleware

- Must implement `MiddlewareInterface`.
- Must return the result of `$next($request)` unless rejecting.
- Must not modify the request in a way that breaks downstream expectations.

### Events

- Must extend `Event`.
- Must be immutable (no setters after creation).
- Must contain all data needed by listeners.
- Must not trigger side effects in the constructor.

### Queue Jobs

- Must implement `QueueableInterface` or be callable via class name + payload.
- Must be idempotent (safe to run multiple times).
- Must handle failures gracefully and report via Logger.
- Must not block the main request.

## Error Handling

- Use custom exceptions: `AppException`, `ValidationException`, `NotFoundException`, etc.
- Never use `die()` or `exit()` in application code (except `Response::send()`).
- Always catch exceptions at the application boundary (`ExceptionHandler`).
- Log all exceptions with context (file, line, trace).
- Events never fail the main transaction. Catch listener exceptions and log them.

## Database

- Use `Database::query()` with parameter binding for all dynamic values.
- Never concatenate user input into SQL.
- Use transactions for multi-step operations.
- Keep migrations reversible and atomic.
- Index foreign keys and query columns.
- Use `utf8mb4` with `utf8mb4_unicode_ci`.

## Configuration

- All environment-sensitive values in `.env`.
- All application config in `app/Config/*.php`.
- Use `env()` or `config()` helpers. Never hardcode credentials or URLs.
- All banking constants in `app/Constants/*.php`. Never use raw strings.

## Logging

- Log level must respect `LOG_LEVEL` env variable.
- Use structured context (arrays) rather than string concatenation.
- Never log passwords, tokens, or sensitive PII.
- Log all financial actions with UUIDs and amounts.

## Security

- Sanitize all input with `Request::sanitize()` when needed.
- Validate all input with `Validator` before processing.
- Hash passwords with `Auth::hashPassword()`.
- Compare tokens with `hash_equals()`.
- Encrypt sensitive data at rest with `encrypt()`.
- Regenerate session IDs periodically.
- Apply rate limiting to all state-changing endpoints.
- Expose UUIDs in API responses, never sequential IDs.

## UUID Usage

- Models that expose public API data must use `HasUuid` trait.
- API responses must include `uuid` fields.
- Internal repository queries may use integer `id` for efficiency.
- Never expose `id` in JSON responses to clients.
