Skip to content

Latest commit

 

History

History
377 lines (300 loc) · 9.62 KB

File metadata and controls

377 lines (300 loc) · 9.62 KB

Quick Start Guide - WorkOrder API

What Was Done

Your Spring Boot application has been verified, enhanced, and documented. All components now follow best practices for managing customers, work orders, and ski items.


Files Created

  1. WorkOrderResponse.java - DTO for work order responses
  2. SkiItemResponse.java - DTO for ski item responses
  3. CustomerResponse.java - DTO for customer responses
  4. WORKORDER_WORKFLOW_VERIFICATION.md - Comprehensive guide
  5. CHANGES_SUMMARY.md - What changed and why
  6. DTO_REFERENCE_GUIDE.md - How to use DTOs
  7. ARCHITECTURE_GUIDE.md - System architecture
  8. QUICK_START_GUIDE.md - This file!

Files Modified

  1. Customer.java - Added initialization, null checks, duplicate prevention
  2. WorkOrder.java - Added getSkiItems/setSkiItems getters
  3. WorkOrderController.java - Verified, enhanced with DTOs
  4. CustomerController.java - Verified, enhanced with DTOs

How to Use the API

1. Create a Work Order

curl -X POST http://localhost:8080/workorders \
  -H "Content-Type: application/json" \
  -d '{
    "customerFirstName": "John",
    "customerLastName": "Doe",
    "email": "john@example.com",
    "phone": "5551234567",
    "skis": [
      {
        "skiMake": "Rossignol",
        "skiModel": "Experience 80",
        "serviceType": "WAXING"
      }
    ]
  }'

Response (HTTP 201 Created):

{
  "id": 1,
  "status": "RECEIVED",
  "createdAt": "2026-01-31T10:30:00",
  "customerId": 1,
  "customerName": "John Doe",
  "customerEmail": "john@example.com",
  "customerPhone": "5551234567",
  "skiItems": [
    {
      "id": 1,
      "skiMake": "Rossignol",
      "skiModel": "Experience 80",
      "serviceType": "WAXING"
    }
  ]
}

2. Get All Work Orders

curl http://localhost:8080/workorders

Response:

[
  {
    "id": 1,
    "status": "RECEIVED",
    "createdAt": "2026-01-31T10:30:00",
    "customerId": 1,
    "customerName": "John Doe",
    "customerEmail": "john@example.com",
    "customerPhone": "5551234567",
    "skiItems": [...]
  }
]

3. Get Specific Work Order

curl http://localhost:8080/workorders/1

4. Get All Customers

curl http://localhost:8080/customers

Response:

[
  {
    "id": 1,
    "firstName": "John",
    "lastName": "Doe",
    "email": "john@example.com",
    "phone": "5551234567",
    "workOrders": [
      {
        "id": 1,
        "status": "RECEIVED",
        "createdAt": "2026-01-31T10:30:00",
        "skiItemCount": 1
      }
    ]
  }
]

5. Get Customer Work Orders

curl http://localhost:8080/customers/1/workorders

Response: List of WorkOrderResponse with full ski item details

6. Search Customer by Email

curl "http://localhost:8080/customers/search?email=john@example.com"

Key Features

✅ Finding Customers

When you POST a work order, the system automatically:

  1. Searches for customer by email OR phone (not just email)
  2. If found, updates the name and creates new work order for existing customer
  3. If not found, creates new customer and assigns work order
  4. Result: Same email/phone = same customer history
First POST:  email=john@example.com, phone=5551234567
  → Creates Customer (id=1)
  → Creates WorkOrder (id=1) for Customer 1

Second POST: email=john@example.com, phone=5551234567  (same)
  → Finds Customer (id=1)
  → Creates WorkOrder (id=2) for Customer 1

GET /customers/1/workorders
  → Returns both WorkOrder 1 and WorkOrder 2 ✅

✅ Cascade Operations

When you delete a customer, all work orders and ski items are deleted:

DELETE /customers/1
  → Deletes Customer 1
  → Cascades: Deletes all WorkOrders for Customer 1
  → Cascades: Deletes all SkiItems for those WorkOrders

✅ JSON Safety

No infinite loops or circular references:

✓ WorkOrder doesn't include full Customer object
✓ SkiItem doesn't include full WorkOrder object
✓ Customer includes work order summaries (not full details)
✓ All responses are clean and manageable

✅ Validation

Input is validated automatically:

POST /workorders with invalid email
  → HTTP 400 Bad Request

POST /workorders with phone that's not 10 digits
  → Phone is normalized (only digits kept)
  → If still not 10 digits → HTTP 400 Bad Request

POST /workorders with no ski items
  → HTTP 400 Bad Request (at least 1 required)

API Summary Table

Method Endpoint Request Response Status
GET /workorders - List 200
GET /workorders/{id} - WorkOrderResponse 200/404
POST /workorders CreateWorkOrderRequest WorkOrderResponse 201
DELETE /workorders/{id} - - 200/404
GET /customers - List 200
GET /customers/{id} - CustomerResponse 200/404
GET /customers/{id}/workorders - List 200/404
GET /customers/search ?email=... CustomerResponse 200/404

What's Different from Before

Aspect Before After
API Response Raw entities with circular refs Clean DTOs ✅
Customer search Email only Email OR phone ✅
POST /workorders return Raw WorkOrder entity WorkOrderResponse DTO ✅
GET /customers Raw entity with all data CustomerResponse with summaries ✅
Customer.workOrders Uninitialized (NPE risk) Initialized with ArrayList ✅
WorkOrderController methods Minimal docs Comprehensive Javadoc ✅
HTTP Status 200 for POST 201 Created for POST ✅
Error Handling Basic Improved with null checks ✅

Testing Scenarios

Scenario 1: New Customer First Order

1. POST /workorders (new email, new phone)
   ✓ Creates Customer
   ✓ Creates WorkOrder
   ✓ Creates SkiItem
   ✓ Returns WorkOrderResponse with id=1

Scenario 2: Same Customer Second Order

1. POST /workorders (same email as before)
   ✓ Finds existing Customer
   ✓ Creates new WorkOrder for same Customer
   ✓ Returns WorkOrderResponse with new id

2. GET /customers/{customerId}/workorders
   ✓ Returns both WorkOrders

Scenario 3: Multiple Ski Items

1. POST /workorders with 3 ski items
   ✓ Creates WorkOrder with all 3 SkiItems
   ✓ Response includes all 3 in skiItems array

2. GET /workorders/{workOrderId}
   ✓ Returns all 3 SkiItems

Scenario 4: JSON Serialization

1. GET /workorders
   ✓ Response is valid JSON (not infinite)
   ✓ Each work order includes ski items
   ✓ Customer data is summarized (no recursion)

2. Check response size
   ✓ Reasonable size (DTOs are efficient)

Next Steps (Optional)

If you want to add more features:

  1. Update Work Order Status

    @PutMapping("/{id}")
    public ResponseEntity<WorkOrderResponse> updateWorkOrderStatus(
        @PathVariable Long id,
        @RequestBody WorkOrderStatusUpdateRequest request
    ) {
        // Update status, return WorkOrderResponse
    }
  2. Add Work Order to Existing Customer

    @PostMapping("/{customerId}/workorders")
    public ResponseEntity<WorkOrderResponse> addWorkOrderToCustomer(
        @PathVariable Long customerId,
        @RequestBody CreateWorkOrderRequest request
    ) {
        // Create work order for specific customer
    }
  3. Delete Ski Item from Work Order

    @DeleteMapping("/{workOrderId}/skis/{skiId}")
    public ResponseEntity<Void> removeSkiItem(
        @PathVariable Long workOrderId,
        @PathVariable Long skiId
    ) {
        // Remove ski item (cascades to deletion)
    }
  4. Add Pagination

    @GetMapping
    public Page<WorkOrderResponse> getAllWorkOrders(
        @PageableDefault(size = 20, sort = "createdAt", direction = Direction.DESC)
        Pageable pageable
    ) {
        // Return paginated results
    }
  5. Add Custom Queries

    // In repository
    List<WorkOrder> findByCustomerIdAndStatusOrderByCreatedAtDesc(Long customerId, String status);
    List<WorkOrder> findByCreatedAtBetween(LocalDateTime start, LocalDateTime end);

Troubleshooting

"org.hibernate.lazy.LazyInitializationException"

  • Cause: Trying to access lazy-loaded collection outside session
  • Fix: Already applied - skiItems use EAGER loading, workOrders are loaded with customer

"JSON infinite recursion error"

  • Cause: Returning raw entities with bidirectional relationships
  • Fix: Already applied - DTOs are returned instead of entities

"Customer with email already exists error"

  • Cause: Duplicate email in database
  • Fix: Check unique constraint, use findByEmailOrPhone to find existing customer

"NullPointerException in customer.addWorkOrder()"

  • Cause: workOrders list not initialized
  • Fix: Already applied - initialized with new ArrayList<>()

Documentation Files

Read these files for more details:

  1. WORKORDER_WORKFLOW_VERIFICATION.md - Complete workflow guide
  2. CHANGES_SUMMARY.md - What changed and why
  3. DTO_REFERENCE_GUIDE.md - How DTOs work
  4. ARCHITECTURE_GUIDE.md - System architecture and diagrams
  5. QUICK_START_GUIDE.md - This file!

Summary

Your WorkOrder management system is now:

  • Verified - All relationships and workflows checked
  • Enhanced - DTOs, null checks, validation
  • Safe - Cascade operations, orphan removal
  • Clean - No JSON circular references
  • Documented - Comprehensive guides and Javadoc
  • Production Ready - Best practices applied

Start the application and test with the curl commands above! 🚀