# Matendes HRM System - Developer Guidelines

**Version:** 2.0.0  
**System:** Laravel 11.x HRM System with SOLID Architecture  
**Target Audience:** Development Team Members, DevOps Engineers, QA Engineers  
**Architecture:** SOLID Principles, Repository Pattern, Service Layer  
**Last Updated:** January 2025

---

## 📋 Table of Contents

1. [Development Environment Setup](#development-environment-setup)
2. [SOLID Architecture Implementation](#solid-architecture-implementation)
3. [Project Structure & Architecture](#project-structure--architecture)
4. [Repository Pattern & Service Layer](#repository-pattern--service-layer)
5. [Coding Standards & Conventions](#coding-standards--conventions)
6. [Error Handling & Exception Management](#error-handling--exception-management)
7. [Database Management & Migrations](#database-management--migrations)
8. [API Development Guidelines](#api-development-guidelines)
9. [Testing Standards & Coverage](#testing-standards--coverage)
10. [Performance Optimization](#performance-optimization)
11. [Security Best Practices](#security-best-practices)
12. [Git Workflow & Best Practices](#git-workflow--best-practices)
13. [Documentation Standards](#documentation-standards)
14. [Troubleshooting & Debugging](#troubleshooting--debugging)

---

## 🚀 Development Environment Setup

### Prerequisites

**Required Software:**
- **PHP:** 8.2 or higher
- **Composer:** Latest version
- **Node.js:** 18.x or higher
- **NPM/Yarn:** Latest version
- **MySQL:** 8.0 or higher (or SQLite for development)
- **Git:** Latest version

**Recommended Tools:**
- **IDE:** VS Code, PhpStorm, or Sublime Text
- **Database Client:** phpMyAdmin, Sequel Pro, or DBeaver
- **API Testing:** Postman, Insomnia
- **Version Control:** Git with GUI client

### Initial Setup

1. **Clone Repository**
   ```bash
   git clone https://github.com/matendes/hrm-system.git
   cd matendes-hrm
   ```

2. **Install Dependencies**
   ```bash
   # PHP dependencies
   composer install
   
   # Node.js dependencies (if frontend assets exist)
   npm install
   ```

3. **Environment Configuration**
   ```bash
   # Copy environment file
   cp .env.example .env
   
   # Generate application key
   php artisan key:generate
   
   # Configure database settings in .env
   DB_CONNECTION=mysql
   DB_HOST=127.0.0.1
   DB_PORT=3306
   DB_DATABASE=matendes_hrm
   DB_USERNAME=root
   DB_PASSWORD=
   ```

4. **Database Setup**
   ```bash
   # Create database
   mysql -u root -p
   CREATE DATABASE matendes_hrm;
   
   # Run migrations with seeders
   php artisan migrate:fresh --seed
   ```

5. **Development Server**
   ```bash
   php artisan serve
   # Access: http://localhost:8000
   ```

---

## 🏗️ SOLID Architecture Implementation

### Overview

The Matendes HRM system follows **SOLID principles** for maintainable, scalable, and testable code architecture:

- **S** - Single Responsibility Principle
- **O** - Open/Closed Principle  
- **L** - Liskov Substitution Principle
- **I** - Interface Segregation Principle
- **D** - Dependency Inversion Principle

### Single Responsibility Principle (SRP)

Each class should have only one reason to change.

**✅ Good Example:**
```php
// Employee service focused only on employee operations
class EmployeeService implements EmployeeServiceInterface
{
    public function createEmployee(array $data): Employee { }
    public function updateEmployee(Employee $employee, array $data): Employee { }
}

// Separate service for career operations
class EmployeeCareerService implements EmployeeCareerServiceInterface  
{
    public function promoteEmployee(Employee $employee, string $newPosition): EmploymentHistory { }
    public function transferEmployee(Employee $employee, string $newDepartment): EmploymentHistory { }
}
```

**❌ Bad Example:**
```php
// Violation: Employee service doing too many things
class EmployeeService 
{
    public function createEmployee() { }
    public function generateReports() { }    // Should be in ReportService
    public function sendEmails() { }         // Should be in NotificationService
    public function calculateSalary() { }    // Should be in PayrollService
}
```

### Dependency Inversion Principle (DIP)

High-level modules should not depend on low-level modules. Both should depend on abstractions.

**✅ Good Example:**
```php
// Controller depends on abstraction, not concrete implementation
class EmployeeController extends BaseController
{
    public function __construct(
        private EmployeeServiceInterface $employeeService,
        private EmployeeRepositoryInterface $employeeRepository
    ) {}
    
    public function store(CreateEmployeeRequest $request): JsonResponse
    {
        $employee = $this->employeeService->createEmployee($request->validated());
        return $this->successResponse(['employee' => $employee]);
    }
}

// Service provider binds interfaces to implementations
class EmployeeServiceProvider extends ServiceProvider
{
    public array $bindings = [
        EmployeeServiceInterface::class => EmployeeService::class,
        EmployeeRepositoryInterface::class => EmployeeRepository::class,
    ];
}
```

---

## 🏗️ Project Structure & Architecture

### Directory Structure

```
matendes-hrm/
├── app/
│   ├── Http/
│   │   ├── Controllers/
│   │   │   └── Api/
│   │   │       └── V1/           # API version 1 controllers
│   │   ├── Middleware/           # Custom middleware
│   │   ├── Requests/            # Form requests with validation
│   │   └── Resources/           # API resources for data transformation
│   ├── Models/                  # Eloquent models
│   ├── Services/               # Business logic services
│   ├── Traits/                 # Reusable traits
│   └── Jobs/                   # Queued jobs
├── database/
│   ├── migrations/             # Database migrations
│   ├── seeders/               # Database seeders
│   └── factories/             # Model factories
├── lang/                      # Localization files
│   ├── en/                   # English translations
│   ├── es/                   # Spanish translations
│   └── fr/                   # French translations
├── routes/
│   ├── api.php               # API routes
│   └── web.php               # Web routes
├── storage/
│   └── app/
│       └── public/           # File uploads
├── tests/                    # Test files
└── docs/                     # Project documentation
```

### Architecture Patterns

**Service Layer Architecture:**
- Controllers handle HTTP requests and delegate business logic to Services
- Services contain business logic and interact with models
- Models represent data and database interactions

**Repository Pattern (Optional):**
- Use repositories for complex data access patterns
- Keep simple CRUD operations in controllers/services

**API Versioning:**
- Version APIs using URL prefixes (`/api/v1/`)
- Maintain backward compatibility when possible

---

## 📝 Coding Standards & Conventions

### PHP Standards

Follow **PSR-12** coding standards:

```php
<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use App\Http\Resources\Api\V1\UserResource;
use App\Services\AuthenticationService;
use Illuminate\Http\JsonResponse;

/**
 * Authentication Controller
 * 
 * Handles user authentication operations including login, logout,
 * token management, and profile updates.
 */
class AuthController extends Controller
{
    public function __construct(
        private AuthenticationService $authService
    ) {
        // Constructor injection preferred over property injection
    }

    /**
     * User login endpoint
     */
    public function login(LoginRequest $request): JsonResponse
    {
        try {
            $result = $this->authService->authenticate($request->validated());
            
            return $this->successResponse('auth.login_successful', [
                'user' => new UserResource($result['user']),
                'token' => $result['token'],
                'expires_at' => $result['expires_at'],
            ]);
        } catch (\Exception $e) {
            return $this->errorResponse('auth.login_failed', null, 401);
        }
    }
}
```

### Naming Conventions

**Classes:**
- Controllers: `UserController`, `AttendanceController`
- Models: `User`, `Employee`, `AttendanceRecord`
- Services: `AuthenticationService`, `NotificationService`
- Requests: `LoginRequest`, `CreateEmployeeRequest`
- Resources: `UserResource`, `EmployeeResource`

**Methods:**
- CRUD operations: `index()`, `show()`, `store()`, `update()`, `destroy()`
- API endpoints: `login()`, `logout()`, `clockIn()`, `clockOut()`

**Variables:**
- camelCase for variables: `$userId`, `$attendanceRecord`
- snake_case for database columns: `created_at`, `employee_id`

**Database:**
- Table names: plural, snake_case (`users`, `attendance_records`)
- Primary keys: `id` (UUID)
- Foreign keys: `{table}_id` (`user_id`, `company_id`)
- Timestamps: `created_at`, `updated_at`

### File Naming

```
Controllers/Api/V1/AuthController.php
Models/User.php
Services/AttendanceService.php
Requests/Auth/LoginRequest.php
Resources/Api/V1/UserResource.php
Middleware/SetLocaleMiddleware.php
```

---

## 💾 Database Management

### Migration Guidelines

**Creating Migrations:**
```bash
# Create migration
php artisan make:migration create_employees_table

# Create migration with model
php artisan make:model Employee -m
```

**Migration Structure:**
```php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('employees', function (Blueprint $table) {
            $table->uuid('id')->primary();
            $table->foreignUuid('user_id')->constrained()->onDelete('cascade');
            $table->foreignUuid('company_id')->constrained()->onDelete('cascade');
            $table->string('employee_id')->unique();
            $table->string('department');
            $table->string('position');
            $table->decimal('salary', 10, 2)->nullable();
            $table->string('currency', 3)->default('USD');
            $table->date('hire_date');
            $table->enum('status', ['active', 'inactive', 'terminated'])->default('active');
            $table->json('settings')->nullable();
            $table->timestamps();
            
            $table->index(['company_id', 'status']);
            $table->index('employee_id');
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('employees');
    }
};
```

### Model Guidelines

**Model Structure:**
```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;

class Employee extends BaseModel
{
    use HasFactory, HasUuids, SoftDeletes;

    protected $fillable = [
        'user_id',
        'company_id',
        'employee_id',
        'department',
        'position',
        'salary',
        'currency',
        'hire_date',
        'status',
        'settings',
    ];

    protected $casts = [
        'hire_date' => 'date',
        'salary' => 'decimal:2',
        'settings' => 'array',
    ];

    // Relationships
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    public function company(): BelongsTo
    {
        return $this->belongsTo(Company::class);
    }

    public function attendanceRecords(): HasMany
    {
        return $this->hasMany(AttendanceRecord::class);
    }

    // Scopes
    public function scopeActive($query)
    {
        return $query->where('status', 'active');
    }

    public function scopeByDepartment($query, string $department)
    {
        return $query->where('department', $department);
    }

    // Accessors & Mutators
    public function getFullNameAttribute(): string
    {
        return $this->user->name;
    }
}
```

### Seeder Guidelines

```php
<?php

namespace Database\Seeders;

use App\Models\User;
use App\Models\Company;
use App\Models\Employee;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;

class EmployeeSeeder extends Seeder
{
    public function run(): void
    {
        $company = Company::first();
        
        $users = [
            [
                'name' => 'John Doe',
                'email' => 'john@matendes.com',
                'password' => Hash::make('password123'),
                'status' => 'active',
            ],
            // ... more users
        ];

        foreach ($users as $userData) {
            $user = User::create($userData);
            
            Employee::create([
                'user_id' => $user->id,
                'company_id' => $company->id,
                'employee_id' => 'EMP' . str_pad(Employee::count() + 1, 3, '0', STR_PAD_LEFT),
                'department' => 'Engineering',
                'position' => 'Software Developer',
                'salary' => 75000.00,
                'hire_date' => now()->subMonths(rand(1, 24)),
            ]);
        }
    }
}
```

---

## 🚀 API Development Guidelines

### Controller Structure

```php
<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Http\Requests\Employee\CreateEmployeeRequest;
use App\Http\Requests\Employee\UpdateEmployeeRequest;
use App\Http\Resources\Api\V1\EmployeeResource;
use App\Models\Employee;
use App\Services\EmployeeService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class EmployeeController extends Controller
{
    public function __construct(
        private EmployeeService $employeeService
    ) {}

    /**
     * List employees with pagination and filtering
     */
    public function index(Request $request): JsonResponse
    {
        $employees = $this->employeeService->getEmployees($request->all());
        
        return $this->successResponse('employee.retrieved', [
            'employees' => EmployeeResource::collection($employees->items()),
            'pagination' => [
                'current_page' => $employees->currentPage(),
                'last_page' => $employees->lastPage(),
                'per_page' => $employees->perPage(),
                'total' => $employees->total(),
            ]
        ]);
    }

    /**
     * Get specific employee
     */
    public function show(Employee $employee): JsonResponse
    {
        $employee->load(['user', 'company', 'attendanceRecords']);
        
        return $this->successResponse('employee.retrieved', [
            'employee' => new EmployeeResource($employee)
        ]);
    }

    /**
     * Create new employee
     */
    public function store(CreateEmployeeRequest $request): JsonResponse
    {
        $employee = $this->employeeService->createEmployee($request->validated());
        
        return $this->successResponse('employee.created', [
            'employee' => new EmployeeResource($employee)
        ], 201);
    }

    /**
     * Update employee
     */
    public function update(UpdateEmployeeRequest $request, Employee $employee): JsonResponse
    {
        $employee = $this->employeeService->updateEmployee($employee, $request->validated());
        
        return $this->successResponse('employee.updated', [
            'employee' => new EmployeeResource($employee)
        ]);
    }

    /**
     * Delete employee
     */
    public function destroy(Employee $employee): JsonResponse
    {
        $this->employeeService->deleteEmployee($employee);
        
        return $this->successResponse('employee.deleted');
    }
}
```

### Request Validation

```php
<?php

namespace App\Http\Requests\Employee;

use Illuminate\Foundation\Http\FormRequest;

class CreateEmployeeRequest extends FormRequest
{
    public function authorize(): bool
    {
        return $this->user()->can('employees.create');
    }

    public function rules(): array
    {
        return [
            'user_id' => ['required', 'uuid', 'exists:users,id'],
            'employee_id' => ['required', 'string', 'unique:employees'],
            'department' => ['required', 'string', 'max:100'],
            'position' => ['required', 'string', 'max:100'],
            'salary' => ['nullable', 'numeric', 'min:0'],
            'currency' => ['nullable', 'string', 'size:3'],
            'hire_date' => ['required', 'date', 'before_or_equal:today'],
            'manager_id' => ['nullable', 'uuid', 'exists:employees,id'],
        ];
    }

    public function messages(): array
    {
        return [
            'user_id.required' => trans('validation.required', ['attribute' => 'User']),
            'employee_id.unique' => trans('validation.unique', ['attribute' => 'Employee ID']),
            'hire_date.before_or_equal' => 'Hire date cannot be in the future',
        ];
    }
}
```

### API Resources

```php
<?php

namespace App\Http\Resources\Api\V1;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class EmployeeResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'employee_id' => $this->employee_id,
            'department' => $this->department,
            'position' => $this->position,
            'salary' => $this->when($request->user()->can('employees.view_salary'), $this->salary),
            'currency' => $this->currency,
            'hire_date' => $this->hire_date->format('Y-m-d'),
            'status' => $this->status,
            'created_at' => $this->created_at->toISOString(),
            'updated_at' => $this->updated_at->toISOString(),
            
            // Relationships
            'user' => new UserResource($this->whenLoaded('user')),
            'company' => new CompanyResource($this->whenLoaded('company')),
            'manager' => new EmployeeResource($this->whenLoaded('manager')),
            
            // Computed attributes
            'full_name' => $this->full_name,
            'tenure_months' => $this->hire_date->diffInMonths(now()),
        ];
    }
}
```

---

## 🌐 Localization & Translation

### Translation System Architecture

The system implements Laravel's localization with a custom translation layer:

**Translation Files Structure:**
```
lang/
├── en/
│   └── messages.php       # English translations
├── es/
│   └── messages.php       # Spanish translations
└── fr/
    └── messages.php       # French translations
```

### Using Translations in Controllers

```php
<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Controller;
use App\Traits\HasTranslations;

class ExampleController extends Controller
{
    // HasTranslations trait is already included in base Controller
    
    public function exampleMethod()
    {
        // Success response with translation
        return $this->successResponse('employee.created', $employeeData);
        
        // Error response with translation
        return $this->errorResponse('employee.not_found', null, 404);
        
        // Response with parameters
        return $this->errorResponse('general.validation_failed', null, 422, [
            'field' => 'email'
        ]);
    }
}
```

### Translation Keys Structure

**messages.php structure:**
```php
return [
    // Authentication
    'auth' => [
        'login_successful' => 'Login successful',
        'login_failed' => 'Invalid credentials provided',
        'logout_successful' => 'Logout successful',
        // ... more auth messages
    ],
    
    // Employee Management
    'employee' => [
        'created' => 'Employee created successfully',
        'updated' => 'Employee updated successfully',
        'not_found' => 'Employee not found',
        // ... more employee messages
    ],
    
    // General messages
    'general' => [
        'success' => 'Operation completed successfully',
        'error' => 'An error occurred',
        'validation_failed' => 'Validation failed',
        // ... more general messages
    ],
];
```

### Locale Detection

The `SetLocale` middleware automatically detects user locale from:
1. `Accept-Language` header
2. URL parameter (`?locale=es`)
3. Authenticated user's locale preference
4. Session locale
5. Default application locale

### Adding New Languages

1. Create translation file: `lang/{locale}/messages.php`
2. Add locale to middleware: `app/Http/Middleware/SetLocale.php`
3. Update available locales array:
   ```php
   $availableLocales = ['en', 'es', 'fr', 'de']; // Add 'de' for German
   ```

---

## 🧪 Testing Standards

### Test Structure

```php
<?php

namespace Tests\Feature\Api\V1;

use App\Models\User;
use App\Models\Employee;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Laravel\Sanctum\Sanctum;
use Tests\TestCase;

class EmployeeControllerTest extends TestCase
{
    use RefreshDatabase;

    private User $user;
    private Employee $employee;

    protected function setUp(): void
    {
        parent::setUp();
        
        $this->user = User::factory()->create();
        $this->employee = Employee::factory()->create();
        
        Sanctum::actingAs($this->user, ['*']);
    }

    /** @test */
    public function it_can_list_employees(): void
    {
        Employee::factory()->count(5)->create();

        $response = $this->getJson('/api/v1/employees');

        $response->assertOk()
            ->assertJsonStructure([
                'success',
                'message',
                'data' => [
                    'employees' => [
                        '*' => [
                            'id',
                            'employee_id',
                            'department',
                            'position',
                        ]
                    ],
                    'pagination'
                ]
            ]);
    }

    /** @test */
    public function it_can_create_employee(): void
    {
        $employeeData = [
            'user_id' => User::factory()->create()->id,
            'employee_id' => 'EMP123',
            'department' => 'Engineering',
            'position' => 'Developer',
            'hire_date' => '2025-01-01',
        ];

        $response = $this->postJson('/api/v1/employees', $employeeData);

        $response->assertCreated()
            ->assertJsonFragment([
                'success' => true,
                'employee_id' => 'EMP123'
            ]);

        $this->assertDatabaseHas('employees', [
            'employee_id' => 'EMP123'
        ]);
    }

    /** @test */
    public function it_validates_required_fields(): void
    {
        $response = $this->postJson('/api/v1/employees', []);

        $response->assertUnprocessable()
            ->assertJsonValidationErrors([
                'user_id',
                'employee_id',
                'department',
                'position',
                'hire_date'
            ]);
    }
}
```

### Running Tests

```bash
# Run all tests
php artisan test

# Run specific test file
php artisan test tests/Feature/Api/V1/EmployeeControllerTest.php

# Run with coverage
php artisan test --coverage

# Run parallel tests (faster)
php artisan test --parallel
```

---

## 🔄 Git Workflow & Best Practices

### Branch Naming Convention

```
feature/attendance-geolocation
bugfix/user-login-validation
hotfix/critical-security-patch
release/v1.2.0
```

### Commit Message Format

```
feat(attendance): add geolocation verification for clock-in

- Implement GPS coordinate validation
- Add geofencing logic for work locations
- Include location verification in attendance service

Closes #123
```

**Commit Types:**
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `style`: Code formatting
- `refactor`: Code restructuring
- `test`: Test additions/modifications
- `chore`: Build process or auxiliary tool changes

### Git Workflow

1. **Create Feature Branch**
   ```bash
   git checkout master
   git pull origin master
   git checkout -b feature/new-feature
   ```

2. **Development Process**
   ```bash
   # Make changes
   git add .
   git commit -m "feat(module): description"
   
   # Push regularly
   git push origin feature/new-feature
   ```

3. **Pull Request Process**
   - Create PR against `master` branch
   - Ensure all tests pass
   - Request code review
   - Address review comments
   - Merge after approval

---

## 🔒 Security Best Practices

### Authentication & Authorization

```php
// Use policy-based authorization
public function update(UpdateEmployeeRequest $request, Employee $employee)
{
    $this->authorize('update', $employee);
    // ... rest of method
}

// Define policies
class EmployeePolicy
{
    public function update(User $user, Employee $employee): bool
    {
        return $user->can('employees.update') && 
               $user->company_id === $employee->company_id;
    }
}
```

### Data Validation & Sanitization

```php
// Always validate input
public function rules(): array
{
    return [
        'email' => ['required', 'email', 'unique:users'],
        'salary' => ['nullable', 'numeric', 'min:0', 'max:9999999.99'],
        'phone' => ['nullable', 'regex:/^[\+]?[1-9][\d]{0,15}$/'],
    ];
}

// Sanitize output
public function toArray(Request $request): array
{
    return [
        'name' => e($this->name), // HTML escape
        'salary' => $this->when($request->user()->can('view_salary'), $this->salary),
    ];
}
```

### Environment Security

```bash
# .env security
APP_DEBUG=false
APP_ENV=production

# Strong keys
php artisan key:generate

# Database credentials
DB_PASSWORD=strong_random_password

# API rate limiting
THROTTLE_REQUESTS=60
```

---

## ⚡ Performance Optimization

### Database Optimization

```php
// Use eager loading
$employees = Employee::with(['user', 'company', 'manager'])->get();

// Use database indexing
Schema::table('employees', function (Blueprint $table) {
    $table->index(['company_id', 'status']);
    $table->index('employee_id');
});

// Query optimization
Employee::select('id', 'name', 'department')
    ->where('status', 'active')
    ->limit(100)
    ->get();
```

### Caching Strategy

```php
// Cache expensive queries
$employees = Cache::remember('active_employees', 3600, function () {
    return Employee::with('user')->active()->get();
});

// Cache API responses
return Cache::tags(['employees'])->remember("employee_{$id}", 1800, function () use ($id) {
    return Employee::with('user')->findOrFail($id);
});
```

### Queue Jobs

```php
// Background processing
dispatch(new ProcessAttendanceReportJob($employee, $dateRange));

// Job structure
class ProcessAttendanceReportJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public function handle(): void
    {
        // Heavy processing logic
    }
}
```

---

## 📚 Documentation Standards

### Code Documentation

```php
/**
 * Process employee attendance for geolocation verification
 * 
 * This method validates the employee's location against configured
 * geofences and processes the attendance record accordingly.
 * 
 * @param Employee $employee The employee clocking in/out
 * @param array $locationData GPS coordinates and accuracy
 * @param string $action Either 'clock_in' or 'clock_out'
 * 
 * @return array Attendance record data with verification status
 * 
 * @throws AttendanceException If location verification fails
 * @throws GeofenceException If no valid geofences found
 * 
 * @example
 * $result = $this->processAttendanceWithLocation($employee, [
 *     'latitude' => 40.7128,
 *     'longitude' => -74.0060,
 *     'accuracy' => 10
 * ], 'clock_in');
 */
public function processAttendanceWithLocation(Employee $employee, array $locationData, string $action): array
{
    // Implementation
}
```

### API Documentation

- Maintain comprehensive API documentation
- Include request/response examples
- Document all error codes
- Keep Postman collection updated

---

## 🛠️ Troubleshooting & Debugging

### Common Issues

**Database Connection Issues:**
```bash
# Check database connectivity
php artisan tinker
DB::connection()->getPdo();

# Clear config cache
php artisan config:clear
```

**Authentication Issues:**
```bash
# Clear auth cache
php artisan auth:clear-resets

# Regenerate API keys
php artisan passport:install --force
```

**Performance Issues:**
```bash
# Enable query logging
DB::enableQueryLog();
// ... your code
dd(DB::getQueryLog());

# Profile with Telescope (if installed)
php artisan telescope:install
```

### Logging Best Practices

```php
// Structured logging
Log::info('Employee attendance processed', [
    'employee_id' => $employee->id,
    'action' => $action,
    'location' => $locationData,
    'timestamp' => now(),
]);

// Error logging with context
try {
    // risky operation
} catch (\Exception $e) {
    Log::error('Attendance processing failed', [
        'employee_id' => $employee->id,
        'error' => $e->getMessage(),
        'trace' => $e->getTraceAsString(),
    ]);
    
    throw $e;
}
```

### Development Tools

```bash
# Laravel Debugbar (development only)
composer require barryvdh/laravel-debugbar --dev

# API debugging
php artisan route:list
php artisan route:cache

# Database debugging
php artisan migrate:status
php artisan db:show
```

---

## 🚀 Quick Commands Reference

### Development Commands
```bash
# Start development
php artisan serve
php artisan queue:work

# Database
php artisan migrate:fresh --seed
php artisan db:seed --class=EmployeeSeeder

# Testing
php artisan test
php artisan test --filter=EmployeeTest

# Code generation
php artisan make:controller Api/V1/EmployeeController --api
php artisan make:model Employee -mfr
php artisan make:request CreateEmployeeRequest
php artisan make:resource Api/V1/EmployeeResource

# Optimization
php artisan optimize
php artisan config:cache
php artisan route:cache
php artisan view:cache
```

### Debugging Commands
```bash
# Clear caches
php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

# Logs
tail -f storage/logs/laravel.log
php artisan log:clear

# Queue monitoring
php artisan queue:monitor
php artisan queue:failed
php artisan queue:retry all
```

---

**Remember:** Always follow these guidelines for consistent, maintainable, and secure code. When in doubt, refer to the Laravel documentation and ask for code review from senior team members.

**Last Updated:** August 2025  
**Next Review:** December 2025