## Patrol Setup Wizard - Quick Start & Testing

### Quick Start Guide

#### 1. Prerequisites
- Laravel app running on `http://localhost:8000`
- Dotnet API running on `http://localhost:5000/api`
- User authenticated with Sanctum token

#### 2. Get API Token
```bash
curl -X POST "http://localhost:8000/api/v1/employee/auth/login" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "admin@example.com",
    "password": "password"
  }'
```

Response will include `token` field.

#### Patrol-gated mobile login (new endpoint)

Use this endpoint for the mobile app when login must require completed Patrol Setup. The existing `/auth/login` endpoint remains available for current clients.

```bash
curl -X POST "http://localhost:8000/api/v1/employee/auth/patrol-login" \
  -H "Content-Type: application/json" \
  -d '{
    "login": "guard@example.com",
    "password": "password"
  }'
```

The `login` value can be an email address or phone number. If the credentials are valid but the employee has no current active Patrol Setup, the endpoint responds with HTTP `403`:

```json
{
  "success": false,
  "message": "Please complete the Patrol Setup before logging in."
}
```

See [Employee Patrol Login API](./Employee_Patrol_Login_API.md) for request fields, all response shapes, and error codes.

#### 3. Full Workflow Example

**Step 1: Fetch Employees from Dotnet**
```bash
TOKEN="your_api_token"

curl -X GET "http://localhost:8000/api/v1/admin/wizard/employees" \
  -H "Authorization: Bearer $TOKEN"
```

Expected Response:
```json
{
  "success": true,
  "message": "Employees retrieved successfully",
  "count": 5,
  "data": [
    {
      "id": 1,
      "code": "EMP001",
      "name": "John Doe",
      "branch": "FWG0001-HYD",
      "department": "Security"
    }
  ]
}
```

**Step 2: Get Clients from Dotnet**

The Patrol Setup client dropdown is filtered per selected branch. Only client records whose .NET `IsPatrol` field is `true` (including the string `"True"`) are listed; `false`, `0`, or missing values are hidden.
```bash
curl -X GET "http://localhost:8000/api/v1/admin/wizard/clients?branch_code=FWG0001-HYD" \
  -H "Authorization: Bearer $TOKEN"
```

Expected Response:
```json
{
  "success": true,
  "message": "Clients retrieved and synced successfully",
  "count": 3,
  "synced": [
    {
      "dotnet_code": "CLI001",
      "laravel_id": 1,
      "name": "Acme Corp"
    }
  ],
  "data": [...]
}
```

**Step 3: Get Available Services**
```bash
curl -X GET "http://localhost:8000/api/v1/admin/wizard/services" \
  -H "Authorization: Bearer $TOKEN"
```

**Step 4: Assign Employee to Site**
```bash
curl -X POST "http://localhost:8000/api/v1/admin/wizard/assign-site" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "employee_id": 5,
    "service_id": 1,
    "start_date": "2026-06-04",
    "end_date": "2027-06-04"
  }'
```

Response:
```json
{
  "success": true,
  "message": "Employee assigned to site successfully",
  "data": {
    "assignment_id": 10,
    "employee": {
      "id": 5,
      "name": "Jane Smith"
    },
    "service": {
      "id": 1,
      "name": "Head Office Security"
    }
  }
}
```

**Step 5: Create Patrol Schedule**
```bash
curl -X POST "http://localhost:8000/api/v1/admin/wizard/create-schedule" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "service_id": 1,
    "schedule_name": "Morning Patrol",
    "start_time": "08:00",
    "end_time": "16:00",
    "interval_hours": 2,
    "checkpoints": [
      {
        "name": "Main Gate",
        "lat": 17.3850,
        "lng": 78.4867
      },
      {
        "name": "Building A",
        "lat": 17.3855,
        "lng": 78.4870
      },
      {
        "name": "Building B",
        "lat": 17.3860,
        "lng": 78.4875
      }
    ]
  }'
```

Response:
```json
{
  "success": true,
  "message": "Patrol schedule created successfully",
  "data": {
    "schedule_id": 5,
    "schedule_name": "Morning Patrol",
    "checkpoints_created": 3,
    "start_time": "08:00",
    "end_time": "16:00"
  }
}
```

**Step 6: Create Geofence**
```bash
curl -X POST "http://localhost:8000/api/v1/admin/wizard/create-geofence" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "service_id": 1,
    "name": "Acme Corp Perimeter",
    "type": "radius",
    "latitude": 17.3850,
    "longitude": 78.4867,
    "radius": 500
  }'
```

Response:
```json
{
  "success": true,
  "message": "Geofence created successfully",
  "data": {
    "geofence_id": 3,
    "name": "Acme Corp Perimeter",
    "type": "radius",
    "radius": 500
  }
}
```

### Testing Scenarios

#### Scenario 1: New Employee from Dotnet
```bash
# 1. Get employees list
# 2. Select employee from dotnet (e.g., id=1)
# 3. Assign to service (assigns automatically on first request)
# 4. Create schedule
# 5. Create geofence
```

#### Scenario 2: Create New Employee in Laravel
```bash
# 1. Create new employee
curl -X POST "http://localhost:8000/api/v1/admin/wizard/employees" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sarah Johnson",
    "email": "sarah.j@example.com",
    "phone": "9988776655",
    "password": "secure_pass_123"
  }'

# 2. Use returned employee_id for assignment
# 3. Assign to service
# 4. Create schedule
# 5. Create geofence
```

#### Scenario 3: Complete Setup (All Steps at Once)
```bash
curl -X POST "http://localhost:8000/api/v1/admin/wizard/complete" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "employee_id": 5,
    "service_id": 1,
    "schedule": {
      "start_time": "08:00",
      "end_time": "16:00"
    },
    "geofence": {
      "type": "radius",
      "latitude": 17.3850,
      "longitude": 78.4867,
      "radius": 500
    }
  }'
```

### Error Scenarios

#### Invalid Employee ID
```json
{
  "success": false,
  "message": "Failed to assign site: No query results found for model [App\\Models\\User]"
}
```

#### Duplicate Assignment
```json
{
  "success": false,
  "message": "Employee is already assigned to this service"
}
```

#### Invalid Coordinates
```json
{
  "success": false,
  "message": "The latitude must be between -90 and 90."
}
```

#### Invalid Time Range
```json
{
  "success": false,
  "message": "End time must be after start time"
}
```

### Database Validation

After successful setup, verify in database:

```sql
-- Check employee assignment
SELECT * FROM employee_assignments WHERE service_id = 1;

-- Check patrol schedule
SELECT * FROM patrol_schedules WHERE service_id = 1;

-- Check checkpoints
SELECT * FROM patrol_checkpoints WHERE service_id = 1;

-- Check QR codes
SELECT * FROM checkpoint_qr_codes WHERE checkpoint_id IN (
  SELECT id FROM patrol_checkpoints WHERE service_id = 1
);

-- Check geofence
SELECT * FROM geofences WHERE service_id = 1;
```

### Troubleshooting

#### "Cannot fetch dotnet employees"
- Verify `DOTNET_API_URL` in .env
- Check dotnet service is running
- Verify network connectivity

#### "Employee not found in dotnet system"
- Verify employee ID exists in dotnet
- Check dotnet database for active employees

#### "Client not found"
- Verify branch code is correct
- Check dotnet client exists for branch

#### "Service must be active"
- Verify service_id is correct
- Check `is_active` field in `client_services` table

#### "Employee already assigned"
- Clear old assignment or change service_id
- Check `employee_assignments` table

### Performance Tips

1. **Batch Operations** - Use `complete` endpoint for all steps
2. **Caching** - Services endpoint results can be cached
3. **Indexing** - Add indexes on frequent queries:
   ```sql
   ALTER TABLE employee_assignments ADD INDEX (service_id);
   ALTER TABLE patrol_schedules ADD INDEX (service_id);
   ```

4. **Rate Limiting** - Consider adding rate limits for API endpoints

### Security Considerations

1. **Authentication** - All endpoints require Sanctum token
2. **Authorization** - Add role-based checks (admin only)
3. **Validation** - All inputs validated server-side
4. **Transaction Safety** - All operations are atomic
5. **Error Messages** - Don't expose sensitive data in errors

### Monitoring

Add logging for monitoring:
```php
// In service methods
Log::info('Patrol assignment created', [
    'employee_id' => $employee->id,
    'service_id' => $service->id,
    'assignment_id' => $assignment->id
]);

Log::error('Patrol setup failed', [
    'error' => $e->getMessage(),
    'trace' => $e->getTraceAsString()
]);
```

### Next Steps

1. Implement frontend UI for wizard
2. Add real-time patrol tracking
3. Implement QR code scanning for mobile
4. Add analytics and reporting
5. Create admin dashboard
