# US-010: Execute a Periodic Preventive Visit

---

## User Story

**As** a maintenance technician  
**I want** to execute a preventive visit and fill in the checklist  
**So that** I can document all completed work and submit a report to the supervisor

---

## Operational Scenario

### Main Flow

1. The technician logs into their account
2. Opens the "My Visits" page
3. Selects the visit scheduled for today
4. Clicks "Start Visit" → the system automatically records the start time
5. The system displays the checklist associated with this visit
6. The technician fills in the checklist item by item
7. Uploads photos of the assets after maintenance
8. If a fault is discovered → records it in the "Discovered Faults" section
9. Specifies spare parts needed for the next visit (if any)
10. Obtains the client's signature
11. Clicks "End Visit" → the system automatically records the end time
12. Clicks "Submit Report"
13. The supervisor receives the report for approval

### Alternative Flows

- **Save as Draft:** The technician saves and continues later
- **No internet connection:** Offline mode → uploaded when connection is restored

---

## Fields & Data

### Screen: Visit Details (Technician)

#### Section 1 — Visit Data (Read Only)

| Field | Notes |
|-------|-------|
| Visit Number | |
| Visit Type | Periodic Preventive Maintenance |
| Client Name | |
| Location + "Open in Maps" button | |
| Phone Number + "Call" button | |
| Visit Date | |
| Status | Scheduled |

**Buttons:**
- Start Visit (large green button)
- Call Client
- Open Location in Maps

---

### Screen: Execute Visit

**Fixed Header:**

| Field | Notes |
|-------|-------|
| Start Time | Read Only (auto at "Start Visit" click) |
| Elapsed Time | Auto timer |

#### Section 1 — Asset List

Displays all assets linked to this visit:

| Column | Notes |
|--------|-------|
| Asset Name | |
| Location | |
| Serial Number | |
| Status | Intact / Needs Maintenance |
| Action | "Start Inspection" button |

#### Section 2 — Checklist (Dynamic per asset type)

*(Shown when "Start Inspection" is clicked for an asset)*

Displays all checklist items linked to the visit:

**Example items:**

| Item | Type | Notes |
|------|------|-------|
| Are the filters clean? | Checkbox (Yes / No) + Notes field | |
| Measure operating temperature | Number + unit (°C) | |
| Has the motor been lubricated? | Checkbox | |
| Condition of electrical wiring | Dropdown (Intact / Needs Maintenance / Damaged) | |
| Asset photos after maintenance | Upload (multiple) | |

Mandatory items are marked with (*) and cannot be skipped.

#### Section 3 — Discovered Faults (Optional)

**Button:** `+ Add Discovered Fault within Asset`

For each fault:

| Field | Type |
|-------|------|
| Fault Description | Textarea |
| Severity | Radio (Minor / Moderate / Critical) |
| Fault Photos | Upload |
| Requires spare parts? | Toggle |
| If Yes → proceed to Spare Parts section | |

#### Section 4 — Spare Parts Required for Next Visit

Table:

| Column | Type |
|--------|------|
| Item Name | Search + Dropdown (from system inventory) |
| Required Quantity | Number |
| Part Photo | Upload |
| Part Number | Text |
| Brand | Text |
| Country of Origin | Text |

**Button:** `+ Add Item`

#### Section 5 — Additional Photos & Videos

| Field | Type |
|-------|------|
| Upload Photos | Upload (multiple) |
| Upload Videos | Upload (multiple) |
| General Notes | Textarea |

---

## Buttons

| Button | Action |
|--------|--------|
| Save as Draft | Saves progress without submitting |
| End Visit & Submit Report | |

---

## Acceptance Criteria

- **AC1:** When "Start Visit" is clicked, the system records a precise timestamp for the start time
- **AC2:** The timer displays the elapsed time since the visit started in real time
- **AC3:** The checklist is automatically pulled based on the asset type linked to the visit and contracted in the system
- **AC4:** Mandatory items (*) must be filled before "End Visit" is allowed
- **AC5:** If the technician attempts to end the visit without filling a mandatory item, a clear warning is shown
- **AC7:** The "Spare Parts" field supports searching from the system inventory
- **AC8:** Photo and video uploads support direct capture from the camera
- **AC9:** When "Save as Draft" is clicked, progress is saved and the technician can return to complete the report later
- **AC12:** When "End Visit & Submit Report" is clicked, the system records a precise timestamp for the end time
- **AC13:** The report cannot be edited after submission to the supervisor except by the supervisor themselves
- **AC14:** When the report is submitted, an immediate notification is sent to the supervisor

------------------

# Audit Report: US-010 Execute a Periodic Preventive Visit

| Feature Name | US-010: Execute a Periodic Preventive Visit |
| :--- | :--- |
| **Audit Date** | 2026-04-15 |
| **Status** | Reviewed |

## 1. Executive Summary
The implementation follows the requested operational scenario for the most part. The backend services correctly manage the visit lifecycle (Start, In Progress, Submission) and enforce data integrity through checklist validation. However, some granular data fields for spare parts and specific offline/hardware requirements are either missing from the backend or implemented through generic abstractions.

---

## 2. Acceptance Criteria Verification

| ID | Requirement | Implementation Status | Code Reference |
| :--- | :--- | :--- | :--- |
| **AC1** | precise timestamp for start time | ✅ Implemented | `MaintenanceVisitService::startVisit` |
| **AC2** | Real-time elapsed timer | ⚠️ Partially Implemented | Backend provides `getVisitDurationInMinutes()`; real-time UI is handled on frontend. |
| **AC3** | Auto-pull checklist by asset type | ✅ Implemented | `MaintenanceVisitChecklistService::getChecklistForVisit` |
| **AC4** | Enforce mandatory items (*) | ✅ Implemented | `MaintenanceVisitReportService::validateRequiredResponses` |
| **AC5** | Warning for missing items | ✅ Implemented | Exception thrown in `MaintenanceVisitReportService` |
| **AC7** | Spare parts inventory search | ⚠️ Partially Implemented | `external_product_id` link exists; search logic usually resides in Catalog domain. |
| **AC8** | Direct capture from camera | ❌ Missing | Treated as generic binary upload in `MaintenanceReportAttachmentController`. |
| **AC9** | Save as Draft capability | ✅ Implemented | Supported via updating report without setting final status. |
| **AC12**| Precise timestamp for end time | ✅ Implemented | `MaintenanceVisitService::completeVisitAndSubmitReport` |
| **AC13**| Read-only after submission | ⚠️ Partially Implemented | Submission logic restricts re-entry, but `updateReport` lacks a status lock check. |
| **AC14**| Supervisor notification | ✅ Implemented | `MaintenanceVisitService::notifySupervisor` |

---

## 3. Data & Field Mapping

### Section 1 — Visit Data
Fields such as **Visit Number**, **Visit Date**, and **Location** are fully supported by the `MaintenanceVisit` model. Navigation ("Open in Maps") and communication ("Call") are implemented as data points for the frontend.

### Section 2 — Checklist (Dynamic)
The system uses a highly flexible dynamic question model:
- **Questions:** Pulled via `MaintenanceAssetType` inheritance.
- **Responses:** Stored in `mod_maintenance_visit_checklist_responses` with support for notes and compliance.

### Section 3 — Discovered Faults
- **Model:** `MaintenanceVisitReport`.
- **Fields:** `fault_description`, `actual_severity`, and `requires_procurement`.
- **Finding:** The "Fault Photos" are handled via the general attachment service linked to the report.

### Section 4 — Spare Parts (Next Visit)
- **Table:** `mod_maintenance_visit_spare_parts`.
- **Divergence:** The specification requests individual columns for **Part Number**, **Brand**, and **Country of Origin**. 
- **Actual Logic:** These fields are currently combined into the `notes` field during mapping in `MaintenanceVisitSparePartService::mapRequestToDatabaseFields`.
- **Missing:** Dedicated field for **Part Photo** on the spare part record itself.

---

## 4. Operational Flows

- **Main Flow:** Fully supported from `startVisit` to `completeVisitAndSubmitReport`.
- **Alternative Flow (Offline):** No evidence of offline sync logic (e.g., version tracking or queued uploads) in the backend repository layer.

---

## 5. Required Actions / Improvements
1. **Database Schema:** Suggest adding dedicated columns for `part_number`, `brand`, and `origin` to `mod_maintenance_visit_spare_parts` for better reporting.
2. **Security/Business Logic:** Add a status check in `MaintenanceVisitReportService::updateReport` to explicitly block edits when a report is in `AWAITING_APPROVAL` or `APPROVED` status.
3. **Media Links:** Create a direct relationship between `MaintenanceVisitSparePart` and `MaintenanceReportAttachment` to support "Part Photos".
