# Test Scenario Guide: Contract Lifecycle Automation 🔄

### 1. Scenario Introduction 🏢
Maintenance contracts are the backbone of the maintenance module. Their lifecycle includes creation, activation, possible termination, and renewal. Previously, the system lacked automated expiry transitions and formal termination/renewal workflows. 

This update implements a complete **state machine** that ensures contracts automatically transition to `EXPIRED` or `EXPIRING` based on dates, allows authorized managers to terminate contracts early (with associated cleanup of planned visits), and provides a streamlined renewal flow to create successor contracts.

---

### 2. Technical Schema Changes (Detailed) 🔍

Analyze the changes in **FormRequest validation rules** and **API Responses**:

* **Endpoint:** `POST /api/v1/maintenance/contracts/{id}/terminate`
    * **Permissions:** Restricted to **R-08 (Technical Manager)** role.
    * **Payload:** 
        * `reason` (string, optional): The justification for early termination.
    * **Response Changes:** 
        * Returns `MaintenanceContractResource` with updated `status` (`terminated`).
        * New metadata block: `termination` (`reason`, `terminated_at`, `terminated_by_user_id`).
* **Endpoint:** `POST /api/v1/maintenance/contracts/{id}/renew`
    * **Validation:** No payload required; uses existing contract as a template.
    * **Response Changes:** 
        * Returns a **newly created** `DRAFT` contract resource.
        * Linked via `renewed_from_contract_id`.
* **Model Changes (`MaintenanceContract`):**
    * **Casting:** `status` is now cast to `App\Domains\Maintenance\Enums\ContractStatus`.
    * **Relationships:** Added `renewedFrom`, `renewedTo`, and `terminatedByUser`.

---

### 3. Why the Update? (Change Log) 🔄

| Feature | Previous Behavior | New Behavior | Benefit |
| :--- | :--- | :--- | :--- |
| **Expiry** | Remained `active` indefinitely. | Auto-transitions to `EXPIRED` or `EXPIRING`. | Data Accuracy |
| **Termination** | No formal status; visits stayed open. | Early termination cancels all `PLANNED`/`SCHEDULED` visits. | Operational Cleanup |
| **Renewal** | Manual re-entry of all data. | One-click cloning into a new `DRAFT`. | Efficiency |
| **Notifications**| No alerts for ending contracts. | Alerts at 60, 30, 14, 7, 3, and 1 days. | Proactive Management |
| **Read-Only** | Any contract could be edited. | `TERMINATED`/`EXPIRED` contracts are locked. | Audit Integrity |

---

### 4. API Endpoints Table 📊

| Process | Endpoint | Method | Description |
| :--- | :--- | :--- | :--- |
| Terminate Contract | `/api/v1/maintenance/contracts/{id}/terminate` | `POST` | Early termination of a contract. Cancels pending visits. |
| Renew Contract | `/api/v1/maintenance/contracts/{id}/renew` | `POST` | Initiates renewal by cloning the current contract. |
| Process Expiry | `maintenance:process-contract-expiry` | `Artisan` | CLI command to process daily transitions and alerts. |

---

### 5. Test Cases 🧪

#### **[Case 1] The Happy Path (Standard Workflow)**
1.  **Creation**: Create a contract with an `end_date` in the future.
2.  **Expiry Detection**: Adjust `end_date` to tomorrow and run `php artisan maintenance:process-contract-expiry`. Verify status remains `EXPIRING` and notification is sent to **R-05** and **R-08**.
3.  **Final Expiry**: Wait for the date to pass (or force it) and run the command again. Verify status is `EXPIRED`.
4.  **Renewal**: Call `/renew`. Verify a new `DRAFT` contract exists with `start_date` = `old_end_date + 1 day`.

#### **[Case 2] Manual Termination & Teardown**
1.  Ensure a contract has several `PLANNED` and `SCHEDULED` visits in `mod_maintenance_visits`.
2.  Call `/terminate` as an **R-08** user.
3.  **Verification**: 
    *   Contract status is `terminated`.
    *   All associated visits now have status `cancelled`.
    *   **R-05** receives a `ContractTerminatedNotification`.

#### **[Case 3] Edge Cases & Security**
*   **Role Restriction**: Attempt to call `/terminate` as an **R-05** or **R-01** user. Expect `403 Forbidden`.
*   **Immutability**: Attempt to `PUT` an update to a `terminated` contract. Expect a validation error: *"TERMINATED and EXPIRED contracts are read-only."*
*   **Succession Chain**: Renew a contract that was already renewed. Verify the `renewed_from_contract_id` points to the correct immediate predecessor.
*   **Date Boundary**: Ensure a contract ending today at 23:59:59 is still `active` but transitions at 00:00:00 the next day.
