# Phase 1 — Read-Only Analysis
## Contract → Milestone → Invoice → Payment

**Status:** Complete — awaiting approval to start Phase 2  
**Date:** 2026-10-07  
**Scope:** Inspection only. No code, migration, API, or UI changes in this phase.  
**Master prompt:** [`CONTRACT_MILESTONE_INVOICE_PAYMENT_MASTER_PROMPT.md`](./CONTRACT_MILESTONE_INVOICE_PAYMENT_MASTER_PROMPT.md)

---

## 1. Current Architecture

ERPFlow today is **contract-centric PMS + commissioning**, not a sales/billing stack.

```text
Company
  └── Client                         (Project module)
        └── Project                  (no money columns)
              └── ProjectServiceLink
                    └── Contract     ★ commercial spine
                          ├── contract_value, currency
                          ├── billing_type (label: retainer|fixed|hourly|milestone)
                          ├── payment_terms, renewal_type, status
                          ├── ContractCommissionShare / ContractMember
                          └── [UI] Payments → Commissioning Payment Cleared

Platform Approval Engine             (morph subject; used by Payroll/Attendance/etc.)
Commissioning                        (payment-cleared inbox → commission runs)
Payroll                              (employee payslips — unrelated AR)
Asset                                (asset_finance_events outbox skeleton)
```

**Active backend modules:** Configuration, Employee, Attendance, Payroll, Project, Commissioning, Asset.

**Absent modules:** Invoice, Billing, Finance/Accounting, Receivable, Milestone.

Contract is the primary commercial context. That aligns with the master prompt rule: *Contract is primary; Milestone is optional billing source.*

---

## 2. Existing Components

### 2.1 Contract (Implemented)

| Layer | Location |
|-------|----------|
| Model | `backend/Modules/Project/app/Models/Contract.php` |
| Table | `contracts` |
| Service | `ContractService` (+ status transitions) |
| API | `/api/v1/project/contracts` |
| FE | `frontend/src/modules/project/.../contract/*` |
| Permissions | `project.contracts-view/create/update/delete/manage` |

Money fields: `contract_value` decimal(15,2), `currency`, `billing_type`, `payment_terms`.

`billing_type = milestone` is a **UI/label option only** — no milestone entity or invoicing engine behind it.

### 2.2 Client (Implemented)

| Layer | Location |
|-------|----------|
| Model/Table | `Client` / `clients` |
| FE | Clients pages/tabs under Project |

Suitable as invoice party (`client_id` already on `contracts`).

### 2.3 Milestone (Not Implemented)

No model, migration, table, API, or UI named Milestone as a deliverable/billing entity.

“Milestone” appearances today:

- Contract `billing_type` option
- Commission type `milestone_based`
- Commissioning frequency enum label “When Milestone Completes”
- Docs / test copy only

### 2.4 Invoice / Invoice Lines (Not Implemented)

No `invoices`, `invoice_items`, sales invoice, or customer invoice anywhere in modules, migrations, FE, or `actions.php`.

### 2.5 Payment — Customer AR (Not Implemented as product)

| What exists | Role |
|-------------|------|
| `commissioning_payment_cleared_inbox` | Manual “client paid” → commission draft |
| FE `ContractPaymentsPanel` | Records payment clears for commission |
| Config `payment_methods` | Inward/outward masters |
| Payroll payment allocations | Employee disbursement (not AR) |

Docs explicitly: Commissioning **will not** generate invoices or own client collection UI.

### 2.6 Approval (Platform — Implemented, unused for milestones)

Platform tables/services:

- `approval_requests`, steps, approvers, audits
- `ApprovalEngine`, workflows, settings
- Morph `subject_type` / `subject_id` pattern

Used today by domains such as Payroll / Attendance. **No milestone subject** wired yet.

Contract status “pending_approval → active” is a **simple status field**, not Platform ApprovalEngine.

### 2.7 Finance / GL (Not Implemented)

No chart of accounts, journals, AR ledgers. Closest stubs:

- `commissioning_ledgers` (commission employee ledger)
- `asset_finance_events` (asset cost outbox; no full consumer)

### 2.8 Docs intent

- PMS Business SRS: payment, invoice, expense, profitability → **later phase**
- Commissioning SRS / plan: invoice generation **out of scope**

---

## 3. Reusable Components

| Component | Reuse how |
|-----------|-----------|
| `contracts` + `Contract` model/service | Parent of milestones & invoices; value/currency/terms |
| `clients` | Invoice bill-to party |
| Project module layout (Controller → Request → Service Interface → Service → Repo Interface → Repo → Model) | Same stack for Milestone / Invoice |
| Platform `ApprovalEngine` | Milestone approval (Draft → Pending → Approved/Rejected) |
| `config/actions.php` + permission sync | New `milestones-*`, `invoices-*`, payment manage under Project (or new Billing section) |
| Commissioning `PaymentCleared` / inbox | **Downstream bridge** after invoice payment (Phase 7+) — not the invoice engine |
| Config `payment_methods` | Payment recording UI options |
| Payroll PDF patterns | Reference only for future invoice PDF (later phase) |
| Money casting `decimal:2` / contract_value precision | Same for milestone/invoice amounts |
| FE Project module shell + Contract detail drawer | Tabs for Milestones / Invoices |
| Event/listener/job pattern (e.g. Payroll MonthFrozen) | Auto-invoice after milestone approved |

---

## 4. Missing Components (must be built)

| Domain | Missing |
|--------|---------|
| Milestone | Table, model, CRUD, amounts, status, approval wiring, remaining invoiceable calc |
| Invoice | Module-or-within-Project: header + statuses + invoice_type (`contract` \| `milestone`) |
| Invoice ↔ Milestone allocation | Pivot/line table retaining per-milestone amounts (M:N + partial) |
| Contract-wise invoiceability | Track sum of contract-wise invoices vs contract_value (open decision: hard cap?) |
| Customer Payment | Payments against invoice; paid/outstanding; **not** mutating milestone remaining |
| Auto-invoice | Config flag + listener on approval → shared invoice service |
| FE | Milestone UI, invoice create (two modes), list/detail, payment UI |
| Permissions | Milestone view/manage/approve; Invoice view/create; Payment manage |
| Tests | Master prompt scenarios 1–12 |

---

## 5. Database Impact (proposed — Phase 2 only after approval)

> Proposed design only. **Not created in Phase 1.**

### New tables (likely)

```text
contract_milestones
  id, company_id, contract_id
  code/name, amount, currency
  status (draft|pending_approval|approved|rejected|…)
  due_date?, notes?
  approval_request refs / timestamps
  created_by, updated_by, timestamps
  indexes: (company_id, contract_id), status

project_invoices   -- name TBD; avoid clash with future Finance module
  id, company_id, contract_id, client_id (denormalized from contract)
  invoice_number, invoice_type (contract|milestone)
  issue_date, due_date?
  subtotal, tax?, discount?, total
  status (draft|issued|cancelled|…)
  paid_amount, outstanding_amount   -- or derived
  currency, notes
  source (manual|automatic)
  timestamps + audit users
  unique: (company_id, invoice_number)

project_invoice_milestone_allocations  -- only for invoice_type=milestone
  id, invoice_id, milestone_id
  amount
  unique (invoice_id, milestone_id)
  indexes for sum-by-milestone over-invoicing checks

project_invoice_payments   -- Phase 7; or evolve commissioning inbox
  id, invoice_id, amount, payment_date, reference
  payment_method_id?, status
```

### Existing tables touched lightly

| Table | Change |
|-------|--------|
| `contracts` | Possibly optional flags: `auto_invoice_on_milestone_approval` — **open decision** |
| Commissioning inbox | Later: link `invoice_id` / payment source — Phase 7 |

### Constraints to enforce in DB + service

- Allocation amount > 0  
- Milestone.contract_id must match invoice.contract_id  
- SUM(allocations for milestone where invoice not cancelled) ≤ milestone.amount  
- Contract-wise invoices: no rows in allocation table  

**Ambiguity (see Risks):** Should SUM(all invoices on contract) ≤ `contract_value`?

---

## 6. API Impact (proposed)

Prefix consistent with Project: `/api/v1/project/...`

| Area | Endpoints (illustrative) |
|------|---------------------------|
| Milestones | Nested under contracts + show/update/status/approve |
| Invoiceability | Milestone resource fields: `amount`, `invoiced_amount`, `remaining_amount` |
| Invoices | Index/filter by contract; show; store (type=contract\|milestone + allocations) |
| Summary | `GET contracts/{id}/invoice-summary` |
| Payments | Nested under invoices (Phase 7) |

Reuse existing Contract show/list; extend resources with summary fields when ready.

Do **not** invent parallel `/billing` module routes unless Product wants a separate module — default recommendation: **keep inside Project module** until Finance exists.

---

## 7. Frontend Impact (proposed)

| Surface | Change |
|---------|--------|
| Contract detail drawer | Tabs: Milestones, Invoices (and keep Payments for commission until AR payment replaces/bridges) |
| Milestone list/form | Amount, status, approve action |
| Create Invoice wizard | Step 1: type Contract-wise vs Milestone-wise |
| Milestone-wise UI | Multi-select approved milestones + amount per row + remaining hints |
| Invoice list/detail | Type badge; hide milestone section for contract-wise |
| Permissions | PermissionGuard on create/approve/pay |

---

## 8. Permission Impact

Existing (reuse):

- `project.contracts-view`, `project.contracts-manage` (and create/update/delete)

Likely **new** (under `project` module in `actions.php`):

| Slug (proposed) | Purpose |
|-----------------|---------|
| `milestones-view` | View milestones |
| `milestones-manage` | CRUD milestones |
| `milestones-approve` | Approve/reject (or wire via Platform approval + this gate) |
| `invoices-view` | View invoices |
| `invoices-create` / `invoices-manage` | Create/void/issue |
| `invoice-payments-manage` | Record payments (Phase 7) |

Align with existing slug style (`contracts-view`, not `view-contracts`). Register in `requires_approval` if Milestone approve uses Platform ApprovalEngine.

---

## 9. Risks & Ambiguities

| # | Risk / Ambiguity | Recommendation |
|---|------------------|----------------|
| R1 | **No Finance/Payment module** — master prompt says “follow existing Finance/Payment”; none exists for AR | Phase 7: introduce invoice payments in Project (or thin Billing), bridge to Commissioning `PaymentCleared` |
| R2 | Contract `billing_type=milestone` vs invoice `invoice_type` | Keep both; `billing_type` = commercial intent; `invoice_type` = per-invoice basis. Do not overload `billing_type` |
| R3 | Cap contract-wise invoices vs `contract_value`? | **Open Decision** — recommend soft warn first or hard cap like milestones |
| R4 | Cap SUM(milestone amounts) vs `contract_value`? | **Open Decision** — recommend ≤ contract_value |
| R5 | Contract status “pending_approval” vs Platform Approval for milestones | Use **Platform ApprovalEngine** for milestones; do not invent second engine; do not conflate with contract status |
| R6 | Auto-invoice when? Only if contract billing mode / flag says so | Config on contract (or company setting); default **manual only** until configured |
| R7 | Commission Payment Cleared UI vs true invoice payment | Avoid two UIs long-term; Phase 7 should clarify bridge vs replace |
| R8 | Task permissions already mention “tasks” but no Task models in Project module | Do not confuse Task RBAC with Milestone; new milestone permissions |
| R9 | Module placement: Project vs new Invoice module | Prefer **Project-owned** MVP tables/services to ship faster; extract Finance later if needed |
| R10 | Cancelled invoices and remaining amount | Cancelled must **release** allocated amounts (invoiceability calc excludes cancelled) |

### Open Business Decisions (block or guide Phase 2+)

1. Hard-cap contract-wise invoicing to `contract_value`?  
2. Must milestone amounts sum ≤ `contract_value`?  
3. Default auto-invoice on milestone approval: off/on?  
4. Invoice statuses MVP set: `draft | issued | cancelled` (+ paid derived)? Or include `sent`?  
5. Tax/discount in MVP or amount-only?  
6. New Laravel module `Billing`/`Invoice` vs keep under `Project`?  
7. After invoice payment: auto-fire Commissioning `PaymentCleared`?  

---

## 10. Implementation Plan (phase map)

| Phase | Deliverable | Depends on |
|-------|-------------|------------|
| **1** | This analysis | — |
| **2** | Migrations + models + enums + relationships for milestones, invoices, allocations | Decisions R3/R4/R6/R9 preferred |
| **3** | Invoiceability service: eligibility, remaining, over-invoice guard; approval status gate | Phase 2 + Approval for approval |
| **4** | Manual create invoice APIs (contract-wise + milestone-wise) + permissions + tests | Phase 3 |
| **5** | Auto-invoice on approved (config-gated) via event → same service | Phase 4 |
| **6** | Invoice/milestone management UI + richer read APIs | Phase 4 (5 optional parallel) |
| **7** | Invoice payments, paid/outstanding; commission bridge optional | Phase 4+ |
| **8** | E2E scenarios 1–12 + regression | All |

### Suggested Phase 2 schema sketch (for approval)

```text
Contract 1 ─── * Milestone
Contract 1 ─── * Invoice
Invoice (type=contract) ─── (no milestone rows)
Invoice (type=milestone) ─── * Allocation ─── Milestone
Invoice 1 ─── * Payment                 (Phase 7)
```

Money: `decimal(15,2)` matching `contracts.contract_value`.  
FKs: `restrict` on delete of contract with invoices; allocations `cascade` with invoice.

### Test strategy per phase

- Phase 2: model/factory smoke + migration  
- Phase 3: unit tests remaining/over-invoice/unapproved  
- Phase 4+: feature tests for scenarios 1–8, 11–12  
- Phase 7: scenarios 9–10  
- Phase 8: full matrix  

---

## Phase 1 Verdict

| Question | Answer |
|----------|--------|
| Can we implement without new tables? | **No** — Milestone + Invoice + allocations (+ payments later) are missing |
| Reuse Contract/Client? | **Yes** |
| Reuse Invoice module? | **N/A — does not exist** |
| Reuse Finance payment? | **No AR system** — build invoice payment + optional Commissioning bridge |
| Reuse ApprovalEngine? | **Yes** for milestone approval |
| Safe to start Phase 2? | **Yes**, after confirming Open Decisions (especially module placement + contract_value caps + auto-invoice default) |

---

## STOP

Phase 1 complete. **No code was changed** (only documentation added):

- `docs/project-management/CONTRACT_MILESTONE_INVOICE_PAYMENT_MASTER_PROMPT.md`
- `docs/project-management/CONTRACT_MILESTONE_INVOICE_PAYMENT_PHASE1_ANALYSIS.md`

**Awaiting explicit approval to start Phase 2 — Domain & Database.**
