# Phase 4 Architectural Decision Record (ADR)

**Document Status:** Approved Architecture Decisions  
**Date:** September 4, 2026  
**Role:** Senior Enterprise Architect, Financial Systems Architect  

---

## ADR-001: Direct POS & Immediate Cash Sale Architectural Pattern

### Context
Commercial transactions in retail or point-of-sale (POS) environments require immediate settlement upon order creation, whereas B2B commercial sales follow asynchronous billing and payment workflows.

### Decision
The system adopts a single, unified, business-agnostic flow for immediate cash sales:
```
Order (Completed) 
  → Invoice (Issued) 
  → Payment (Received) 
  → Payment Allocation (Applied) 
  → General Ledger Journal Posting
```
For immediate cash/POS transactions, all 5 operations execute inside a **single atomic database transaction**.

### Rationale
- Keeps `app/Domains/Core/` 100% business-agnostic (no restaurant, bar, retail, or POS UI concepts).
- Guarantees full auditability and sub-ledger integrity without bypassing Accounts Receivable.
- Eliminates dual accounting pathways for cash vs credit sales.

---

## ADR-002: Strict Three-Way Matching & Discrepancy Override Governance

### Context
Procurement bills must be verified against Purchase Orders and Purchase Receipts before financial approval and Accounts Payable posting.

### Rules
1. **Quantity Rule:** Billed Quantity MUST NOT exceed Received Quantity (`billed_qty <= received_qty`).
2. **Price Rule:** Billed Unit Price exceeding PO Unit Price triggers status `DISCREPANCY`.
3. **Manager Override Governance:**
   - Overrides require permission `bills.override_discrepancy`.
   - Override events record `overridden_by` (User ID), `override_reason` (text), and `overridden_at` (timestamp).
   - Financial journal posting (`DR Inventory/Expense`, `DR Tax Recoverable`, `CR Accounts Payable`) is blocked until discrepancy is cleared or overridden.

---

## ADR-003: Tax Rate Snapshotting & Deterministic Historical Integrity

### Context
Tax rates and tax categories change over time due to statutory legislation. Historical invoices must remain fixed regardless of future rate modifications.

### Decision
- At document issuance/approval, the active tax rate is snapshotted into `InvoiceLine.tax_rate_snapshot` and `SupplierInvoiceLine.tax_rate_snapshot`.
- Historical calculations reference the snapshot, never the live `TaxCategory`.
- Cross-organization tax account references are strictly forbidden via `AccountResolver`.

---

## ADR-004: Commercial Document Immutability & Corrective Workflow

### Context
Financial accounting standards forbid mutating posted financial records or issued commercial invoices.

### Decision
- Invoices in status `ISSUED`, `PAID`, or `PARTIALLY_PAID` are immutable.
- Supplier Invoices in status `APPROVED`, `PAID`, or `PARTIALLY_PAID` are immutable.
- Corrections must be issued via explicit compensating records:
  - Customer adjustments: `CreditNote`
  - Financial adjustments: `FinancialService::reverseJournal()`

---

## ADR-005: Legacy Payment Coexistence & Migration Strategy

### Context
Phase 3 Core Payment model anchored payments directly to `order_id`. Phase 4 introduces `Invoice` and `SupplierInvoice` sub-ledgers.

### Decision
1. `Payment.order_id` migration changes column to `nullable()`.
2. `Payment.invoice_id` is added as an optional direct link.
3. `PaymentAllocation` pivot table becomes the primary, canonical source of truth for payment-to-invoice matching (supporting 1:1, 1:N, N:1, partial, and overpayments).
4. Legacy Phase 3 tests referencing `Payment::create(['order_id' => ...])` remain 100% valid and operational without breaking changes.
