# Phase 2 — Domain & Database Report

**Status:** Complete — awaiting approval to start Phase 3  
**Date:** 2026-10-07  
**Scope:** Migrations, enums, models, relationships only. No invoice services, APIs, UI, or payment flow.

---

## What was implemented

### Migrations (Project module)

| Migration | Purpose |
|-----------|---------|
| `2026_10_07_120000_create_contract_milestones_table` | Contract milestones (amount, status, approval hooks) |
| `2026_10_07_120100_create_project_invoices_table` | Invoices with `invoice_type` contract \| milestone |
| `2026_10_07_120200_create_project_invoice_milestone_allocations_table` | Per-milestone amounts on milestone-wise invoices |
| `2026_10_07_120300_add_auto_invoice_flag_to_contracts_table` | `auto_invoice_on_milestone_approval` default `false` |

### Enums

| Enum | Values |
|------|--------|
| `ContractMilestoneStatus` | draft, pending_approval, approved, rejected |
| `ProjectInvoiceType` | contract, milestone |
| `ProjectInvoiceStatus` | draft, issued, cancelled |
| `ProjectInvoiceSource` | manual, automatic |

### Models + relationships

```text
Contract
  ├── milestones() → ContractMilestone
  └── invoices() → ProjectInvoice

ContractMilestone
  └── allocations() → ProjectInvoiceMilestoneAllocation

ProjectInvoice
  ├── contract(), client()
  └── milestoneAllocations() → ProjectInvoiceMilestoneAllocation
        └── milestone()
```

**Contract-wise invoices** have zero allocation rows.  
**Milestone-wise invoices** store one allocation row per milestone (partial / multi-milestone / multi-invoice supported at schema level).

### Defaults chosen (open decisions from Phase 1)

| Decision | Choice in Phase 2 |
|----------|-------------------|
| Module placement | Stay inside **Project** (`project_invoices`, not a new module) |
| Auto-invoice default | **Off** (`auto_invoice_on_milestone_approval = false`) |
| Tax/discount columns | Present (default 0); logic deferred |
| Payment tables | Deferred to Phase 7 (`paid_amount` / `outstanding_amount` on invoice ready) |
| Hard-cap vs `contract_value` | Not enforced in DB (application layer later) |

---

## Tests

`Modules/Project/tests/Unit/ContractMilestoneInvoiceDomainTest.php` — **5 passed**

- Enum values / eligibility helpers  
- Contract-wise invoice without allocations  
- Milestone-wise invoice with two allocations  
- One milestone across multiple invoices (partial path)  
- Auto-invoice flag defaults false  

---

## Explicitly NOT done (later phases)

- Invoiceability / remaining amount service (Phase 3)  
- Manual create invoice API (Phase 4)  
- Auto-invoice on approval (Phase 5)  
- UI (Phase 6)  
- Customer payments (Phase 7)  
- Permissions / routes / resources  

---

## Files touched

- `backend/Modules/Project/database/migrations/2026_10_07_120000_*.php` (4 files)  
- `backend/Modules/Project/app/Enums/ContractMilestoneStatus.php`  
- `backend/Modules/Project/app/Enums/ProjectInvoiceType.php`  
- `backend/Modules/Project/app/Enums/ProjectInvoiceStatus.php`  
- `backend/Modules/Project/app/Enums/ProjectInvoiceSource.php`  
- `backend/Modules/Project/app/Models/ContractMilestone.php`  
- `backend/Modules/Project/app/Models/ProjectInvoice.php`  
- `backend/Modules/Project/app/Models/ProjectInvoiceMilestoneAllocation.php`  
- `backend/Modules/Project/app/Models/Contract.php` (relations + auto-invoice flag)  
- `backend/Modules/Project/tests/Unit/ContractMilestoneInvoiceDomainTest.php`  
- This report  

---

## STOP

Phase 2 complete. **Awaiting explicit approval for Phase 3 — Milestone Invoiceability.**
