# User Module Documentation

## Overview

The User module provides a complete CRUD (Create, Read, Update, Delete) system for managing application users. Each user has a name, email, and password. The module includes a service layer for business logic, a controller for handling HTTP requests, and proper route definitions. It also supports soft deletes with restore functionality.

## Architecture

### Components

1. **Model**: `app/Models/User.php`
   - Handles database interactions
   - Uses soft deletes
   - Implements Laravel Sanctum for API authentication
   - Password hashing built-in

2. **Service**: `app/Services/UserService.php`
   - Contains all business logic
   - Manages password hashing
   - Handles create, read, update, delete operations
   - Includes soft delete management (restore, force delete)

3. **Controller**: `app/Http/Controllers/UserController.php`
   - Handles HTTP requests/responses
   - Validates input data
   - Delegates business logic to the service

4. **Routes**: `routes/users.php`
   - Defines all API endpoints
   - Separates public (read-only) from protected routes

## Database Schema

```sql
CREATE TABLE users (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    email_verified_at TIMESTAMP NULL,
    password VARCHAR(255) NOT NULL,
    remember_token VARCHAR(100) NULL,
    deleted_at TIMESTAMP NULL,
    created_at TIMESTAMP NULL,
    updated_at TIMESTAMP NULL
);
```

### Fields

- `id`: Primary key
- `name`: User's full name (required, max 255 characters)
- `email`: User's email address (required, unique, max 255 characters)
- `email_verified_at`: Email verification timestamp (optional)
- `password`: Hashed password (required, automatically hashed)
- `remember_token`: Token for "remember me" functionality
- `deleted_at`: Soft delete timestamp
- `created_at`: Record creation timestamp
- `updated_at`: Record last update timestamp

## API Endpoints

### Public Endpoints (No Authentication Required)

#### 1. Get All Users
```http
GET /api/users
```

**Response:**
```json
[
  {
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com",
    "email_verified_at": null,
    "created_at": "2024-01-01T00:00:00.000000Z",
    "updated_at": "2024-01-01T00:00:00.000000Z"
  }
]
```

**Note:** Password is never returned in responses (hidden by model).

#### 2. Get User by ID
```http
GET /api/users/{id}
```

**Example:**
```http
GET /api/users/1
```

**Response:**
```json
{
  "id": 1,
  "name": "John Doe",
  "email": "john@example.com",
  "email_verified_at": null,
  "created_at": "2024-01-01T00:00:00.000000Z",
  "updated_at": "2024-01-01T00:00:00.000000Z"
}
```

**Error Response (404):**
```json
{
  "message": "User not found"
}
```

#### 3. Get User by Email
```http
GET /api/users/email/{email}
```

**Example:**
```http
GET /api/users/email/john@example.com
```

### Protected Endpoints (Require Authentication)

All protected endpoints require a Sanctum authentication token:
```http
Authorization: Bearer YOUR_TOKEN_HERE
```

#### 4. Create User
```http
POST /api/users
Authorization: Bearer {token}
Content-Type: application/json
```

**Request Body:**
```json
{
  "name": "Jane Smith",
  "email": "jane@example.com",
  "password": "SecurePass123"
}
```

**Validation Rules:**
- `name`: required, string, max 255 characters
- `email`: required, valid email format, max 255 characters, must be unique
- `password`: required, string, minimum 8 characters

**Success Response (201):**
```json
{
  "message": "User created successfully",
  "user": {
    "id": 2,
    "name": "Jane Smith",
    "email": "jane@example.com",
    "created_at": "2024-01-01T00:00:00.000000Z",
    "updated_at": "2024-01-01T00:00:00.000000Z"
  }
}
```

#### 5. Update User
```http
PUT /api/users/{id}
Authorization: Bearer {token}
Content-Type: application/json
```

**Request Body (All fields optional):**
```json
{
  "name": "Jane Doe",
  "email": "jane.doe@example.com",
  "password": "NewSecurePass456"
}
```

**Validation Rules:**
- `name`: sometimes required, string, max 255 characters
- `email`: sometimes required, valid email format, unique except for current user
- `password`: sometimes required, string, minimum 8 characters

**Success Response (200):**
```json
{
  "message": "User updated successfully",
  "user": {
    "id": 2,
    "name": "Jane Doe",
    "email": "jane.doe@example.com",
    "updated_at": "2024-01-01T01:00:00.000000Z"
  }
}
```

**Note:** Password is automatically hashed before storing. If provided, it will update the user's password.

#### 6. Delete User (Soft Delete)
```http
DELETE /api/users/{id}
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "message": "User deleted successfully"
}
```

**Note:** This is a soft delete. The user record is not permanently removed and can be restored. All user's API tokens are revoked upon deletion.

#### 7. Get Trashed Users
```http
GET /api/users/trashed/all
Authorization: Bearer {token}
```

**Response:**
```json
[
  {
    "id": 3,
    "name": "Deleted User",
    "email": "deleted@example.com",
    "deleted_at": "2024-01-01T12:00:00.000000Z"
  }
]
```

#### 8. Restore Deleted User
```http
POST /api/users/{id}/restore
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "message": "User restored successfully",
  "user": {
    "id": 3,
    "name": "Deleted User",
    "email": "deleted@example.com",
    "deleted_at": null
  }
}
```

**Error Response (404):**
```json
{
  "message": "User not found or not deleted"
}
```

#### 9. Force Delete User (Permanent)
```http
DELETE /api/users/{id}/force
Authorization: Bearer {token}
```

**Success Response (200):**
```json
{
  "message": "User permanently deleted"
}
```

**Note:** This permanently removes the user record from the database. This action cannot be undone. All user's API tokens are revoked before deletion.

## Service Methods

### UserService Methods

```php
// Get all users
listAll(): Collection

// Find user by ID
findById(int $id): ?User

// Find user by email
findByEmail(string $email): ?User

// Create new user (automatically hashes password)
create(array $data): User

// Update existing user (automatically hashes password if provided)
update(int $id, array $data): ?User

// Soft delete user (revokes all tokens)
delete(int $id): bool

// Get all soft-deleted users
listTrashed(): Collection

// Restore a soft-deleted user
restore(int $id): ?User

// Permanently delete user (revokes all tokens)
forceDelete(int $id): bool
```

## Usage Examples

### Example 1: Create User using cURL

```bash
curl -X POST http://localhost:8000/api/users \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Doe",
    "email": "john@example.com",
    "password": "SecurePass123"
  }'
```

### Example 2: Update User Email

```bash
curl -X PUT http://localhost:8000/api/users/1 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "newemail@example.com"
  }'
```

### Example 3: Update User Password

```bash
curl -X PUT http://localhost:8000/api/users/1 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "password": "NewSecurePassword456"
  }'
```

### Example 4: Get All Users (Public)

```bash
curl -X GET http://localhost:8000/api/users
```

### Example 5: Soft Delete User

```bash
curl -X DELETE http://localhost:8000/api/users/1 \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Example 6: Restore Deleted User

```bash
curl -X POST http://localhost:8000/api/users/1/restore \
  -H "Authorization: Bearer YOUR_TOKEN"
```

### Example 7: Using the Service in Code

```php
use App\Services\UserService;

class YourController extends Controller
{
    protected $userService;
    
    public function __construct(UserService $userService)
    {
        $this->userService = $userService;
    }
    
    public function example(Request $request)
    {
        // Create a user
        $user = $this->userService->create([
            'name' => 'John Doe',
            'email' => 'john@example.com',
            'password' => 'SecurePass123'
        ]);
        
        // Get all users
        $users = $this->userService->listAll();
        
        // Find by email
        $user = $this->userService->findByEmail('john@example.com');
        
        // Update user
        $user = $this->userService->update(1, [
            'name' => 'John Smith',
            'password' => 'NewPassword456'
        ]);
        
        // Soft delete
        $this->userService->delete(1);
        
        // Get trashed users
        $trashedUsers = $this->userService->listTrashed();
        
        // Restore user
        $this->userService->restore(1);
        
        // Force delete (permanent)
        $this->userService->forceDelete(1);
    }
}
```

## Model Features

### Password Hashing

Passwords are automatically hashed using Laravel's built-in hashing:

```php
// This is done automatically by the service
$user->password = Hash::make($plainTextPassword);
```

### Hidden Attributes

The following attributes are automatically hidden from JSON responses:

```php
protected $hidden = [
    'password',
    'remember_token',
];
```

### API Token Management

Users can generate API tokens using Laravel Sanctum:

```php
// Generate token
$token = $user->createToken('token-name')->plainTextToken;

// Revoke all tokens
$user->tokens()->delete();

// Revoke current token
$request->user()->currentAccessToken()->delete();
```

### Soft Deletes

Users use soft deletes, meaning deleted records are not permanently removed:

```php
// Soft delete
$user->delete();

// Get trashed users
User::onlyTrashed()->get();

// Restore a soft-deleted user
$user->restore();

// Permanently delete
$user->forceDelete();
```

## Security Features

1. **Authentication**: All write operations (create, update, delete) require authentication via Laravel Sanctum
2. **Password Hashing**: Passwords are automatically hashed using bcrypt
3. **Password Hidden**: Password field is never returned in API responses
4. **Validation**: Strong validation rules including:
   - Email format validation
   - Unique email constraint
   - Minimum password length (8 characters)
5. **Token Revocation**: All user tokens are automatically revoked when deleting users
6. **Soft Deletes**: Accidental deletions can be recovered
7. **Email Uniqueness**: System ensures no duplicate email addresses

## Error Handling

### Common Error Responses

**400 Bad Request - Validation Error:**
```json
{
  "message": "The given data was invalid.",
  "errors": {
    "email": ["The email field is required."],
    "password": ["The password must be at least 8 characters."]
  }
}
```

**401 Unauthorized:**
```json
{
  "message": "Unauthenticated."
}
```

**404 Not Found:**
```json
{
  "message": "User not found"
}
```

**422 Unprocessable Entity - Duplicate Email:**
```json
{
  "message": "The given data was invalid.",
  "errors": {
    "email": ["The email has already been taken."]
  }
}
```

## Testing

### Example Test Cases

```php
public function test_can_create_user()
{
    $admin = User::factory()->create();
    
    $response = $this->actingAs($admin)
        ->postJson('/api/users', [
            'name' => 'Test User',
            'email' => 'test@example.com',
            'password' => 'SecurePass123'
        ]);
    
    $response->assertStatus(201)
        ->assertJson([
            'message' => 'User created successfully'
        ]);
    
    $this->assertDatabaseHas('users', [
        'email' => 'test@example.com'
    ]);
}

public function test_can_update_user()
{
    $admin = User::factory()->create();
    $user = User::factory()->create(['email' => 'old@example.com']);
    
    $response = $this->actingAs($admin)
        ->putJson("/api/users/{$user->id}", [
            'email' => 'new@example.com'
        ]);
    
    $response->assertStatus(200);
    
    $this->assertDatabaseHas('users', [
        'id' => $user->id,
        'email' => 'new@example.com'
    ]);
}

public function test_can_soft_delete_user()
{
    $admin = User::factory()->create();
    $user = User::factory()->create();
    
    $response = $this->actingAs($admin)
        ->deleteJson("/api/users/{$user->id}");
    
    $response->assertStatus(200);
    
    $this->assertSoftDeleted('users', [
        'id' => $user->id
    ]);
}

public function test_can_restore_deleted_user()
{
    $admin = User::factory()->create();
    $user = User::factory()->create();
    $user->delete();
    
    $response = $this->actingAs($admin)
        ->postJson("/api/users/{$user->id}/restore");
    
    $response->assertStatus(200);
    
    $this->assertDatabaseHas('users', [
        'id' => $user->id,
        'deleted_at' => null
    ]);
}
```

## Best Practices

1. **Always use the Service Layer**: Don't bypass the service and interact directly with the model in controllers
2. **Password Security**: The service automatically hashes passwords - never store plain text passwords
3. **Validate Input**: Always validate user input in the controller before passing to the service
4. **Error Handling**: Check for null returns from service methods that might not find records
5. **Token Management**: Revoke tokens when users are deleted or when security is compromised
6. **Email Uniqueness**: Always validate email uniqueness when creating or updating users
7. **Soft Delete First**: Use soft delete by default, only force delete when absolutely necessary

## Integration with Auth Module

The User module works seamlessly with the existing Auth module (`app/Services/AuthService.php`):

```php
// Login generates tokens for users
$result = $authService->login(['email' => '...', 'password' => '...']);

// Get authenticated user
$result = $authService->getAuthenticatedUser();

// Logout revokes tokens
$result = $authService->logout($user);
```

## Future Enhancements

Potential improvements for the User module:

1. Add user roles and permissions (admin, user, etc.)
2. Implement email verification system
3. Add user profile fields (avatar, bio, phone, etc.)
4. Add password reset functionality
5. Implement two-factor authentication
6. Add user activity logging
7. Add pagination to list endpoints
8. Implement search and filtering
9. Add bulk user import/export
10. Add user preferences/settings

## Troubleshooting

### Cannot create users
- Ensure you're authenticated and sending a valid Bearer token
- Check that email is not already in use
- Verify password meets minimum length requirement (8 characters)

### Password not working after update
- Remember: passwords are hashed automatically
- If testing, ensure you're comparing hashed values correctly
- Use `Hash::check($plainText, $hashedPassword)` to verify passwords

### Soft deleted users appearing in queries
- Use `->withTrashed()` to include soft deleted records
- Use `->onlyTrashed()` to get only deleted records
- Default queries exclude soft deleted records automatically

### Token issues after user operations
- Tokens are automatically revoked when users are deleted
- User must log in again after restore
- Check token validity and expiration

## Related Modules

- **Auth Module**: `app/Services/AuthService.php` - Handles user authentication
- **Clients Module**: Uses `added_by` and `updated_by` fields referencing users
- **Sectors Module**: Uses `added_by` and `updated_by` fields referencing users
- **Projects Module**: Uses user relationships for tracking changes
- **Sections Module**: Uses user relationships for tracking changes
