# TANRAIL ONE — Phase 3.3 Financial Data Model

## 1. Enums
- `AccountType`: ASSET, LIABILITY, EQUITY, REVENUE, EXPENSE.
- `JournalStatus`: POSTED, REVERSED.

## 2. Models

### `Account` (Organization Scoped)
Represents a node in the Chart of Accounts.
- `id`
- `organization_id` (FK)
- `code` (String, e.g., "1000")
- `name` (String, e.g., "Cash")
- `type` (Enum: AccountType)
- `is_active` (Boolean)

### `FiscalPeriod` (Organization Scoped)
- `id`
- `organization_id` (FK)
- `name` (String, e.g., "September 2026")
- `start_date` (Date)
- `end_date` (Date)
- `is_closed` (Boolean)

### `Journal` (Business Unit Scoped)
The header for an accounting entry.
- `id`
- `business_unit_id` (FK)
- `reference_type` (Polymorphic string, e.g., "App\Domains\Core\Models\Payment")
- `reference_id` (Polymorphic ID)
- `description` (String)
- `posting_date` (Date)
- `status` (Enum: JournalStatus)
- `reverses_journal_id` (Nullable FK to Journal - self-referencing)
- `created_by` (FK to User)

### `JournalEntry` (Immutable Lines)
- `id`
- `journal_id` (FK)
- `account_id` (FK)
- `debit` (Decimal 15,4)
- `credit` (Decimal 15,4)
- `description` (String nullable)

## 3. Immutability Rules
- `$fillable` arrays on `Journal` and `JournalEntry` omit `status`, `debit`, `credit` to prevent mass-assignment.
- `booted()` observer on `Journal` prevents `delete()` entirely, and prevents `update()` unless it is specifically modifying `status` to `REVERSED` via the Service.
- `booted()` observer on `JournalEntry` throws `RuntimeException` on `update()` or `delete()`.
