# User Management REST API

This package contains the REST API layer for the User Management system.

## Architecture

Built following **Clean Architecture** principles:
- **Controllers**: Handle HTTP requests/responses, convert DTOs
- **DTOs**: Request/Response objects for API communication
- **Exception Handler**: Centralized error handling
- **OpenAPI Config**: Swagger/OpenAPI documentation

## Package Structure

```
infrastructure/web/usermanagement/
├── controller/
│   ├── AuthController.java          # Authentication endpoints
│   ├── UserController.java          # User management endpoints
│   └── RoleController.java          # Role management endpoints
├── dto/
│   ├── LoginRequest.java            # Login request
│   ├── LoginResponse.java           # Login response with JWT
│   ├── RefreshTokenRequest.java    # Refresh token request
│   ├── CreateUserRequest.java       # Create user request
│   ├── UpdateUserRequest.java       # Update user request
│   ├── ChangePasswordRequest.java   # Change password request
│   ├── AssignRoleRequest.java       # Assign role request
│   └── ErrorResponse.java           # Standard error response
├── exception/
│   └── GlobalExceptionHandler.java  # Centralized exception handling
└── config/
    └── OpenApiConfig.java           # Swagger/OpenAPI configuration
```

## API Endpoints

### Authentication (Public)

| Method | Endpoint | Description | Security |
|--------|----------|-------------|----------|
| POST | `/api/auth/login` | Login with username/password | Public |
| POST | `/api/auth/logout` | Logout (invalidate JWT) | Authenticated |
| POST | `/api/auth/refresh` | Refresh access token | Public |

### User Management (Authenticated)

| Method | Endpoint | Description | Security |
|--------|----------|-------------|----------|
| POST | `/api/users` | Create user | ADMIN only |
| GET | `/api/users` | List all users | Authenticated |
| GET | `/api/users/{id}` | Get user by ID | Authenticated |
| PUT | `/api/users/{id}` | Update user | Authenticated |
| POST | `/api/users/{id}/lock` | Lock user account | ADMIN only |
| POST | `/api/users/{id}/unlock` | Unlock user account | ADMIN only |
| POST | `/api/users/{id}/roles` | Assign role to user | ADMIN only |
| DELETE | `/api/users/{id}/roles/{roleName}` | Remove role from user | ADMIN only |
| PUT | `/api/users/{id}/password` | Change password | Authenticated |

### Role Management (ADMIN only)

| Method | Endpoint | Description | Security |
|--------|----------|-------------|----------|
| GET | `/api/roles` | List all roles | ADMIN only |

## Security

### Authentication
- JWT-based authentication (stateless)
- Access token + refresh token
- Token expiration: 1 hour (configurable)
- Refresh token for obtaining new access tokens

### Authorization
- Role-based access control (RBAC)
- Permission-based authorization via `AuthorizationPort`
- ADMIN endpoints require `USER_MANAGEMENT` permission
- Users can change their own password

### Security Configuration
- Public endpoints: `/api/auth/login`, `/api/auth/refresh`
- Protected endpoints: All other `/api/**` endpoints
- JWT validation via `JwtAuthenticationFilter`
- Authorization checks via `@PreAuthorize` annotations

## Error Handling

### Standard Error Response Format

```json
{
  "code": "USER_NOT_FOUND",
  "message": "User with ID 'user-123' not found",
  "status": 404,
  "timestamp": "2026-02-17T12:00:00",
  "path": "/api/users/user-123",
  "validationErrors": null
}
```

### HTTP Status Codes

| Status | Description | Examples |
|--------|-------------|----------|
| 200 OK | Success | GET, PUT requests |
| 201 Created | Resource created | POST /api/users |
| 204 No Content | Success, no response body | Password change, logout |
| 400 Bad Request | Validation error | Missing required fields |
| 401 Unauthorized | Authentication failed | Invalid credentials, expired token |
| 403 Forbidden | Authorization failed | Missing permission |
| 404 Not Found | Resource not found | User not found |
| 409 Conflict | Resource conflict | Username already exists |
| 500 Internal Server Error | Unexpected error | System errors |

### Error Types Handled

1. **Domain Errors** (`UserError`)
   - `UserNotFound` → 404 Not Found
   - `UsernameAlreadyExists` → 409 Conflict
   - `EmailAlreadyExists` → 409 Conflict
   - `InvalidCredentials` → 401 Unauthorized
   - `UserLocked` → 403 Forbidden
   - `UserInactive` → 403 Forbidden
   - `RoleNotFound` → 404 Not Found
   - `InvalidPassword` → 400 Bad Request
   - `Unauthorized` → 403 Forbidden

2. **Validation Errors**
   - Bean Validation (`@Valid`) → 400 Bad Request
   - Returns list of field-level errors

3. **Authentication Errors**
   - Invalid JWT token → 401 Unauthorized
   - Expired JWT token → 401 Unauthorized

4. **Authorization Errors**
   - Missing permission → 403 Forbidden

5. **Unexpected Errors**
   - Runtime exceptions → 500 Internal Server Error

## API Documentation (Swagger)

### Access Swagger UI
- URL: `http://localhost:8080/swagger-ui/index.html`
- OpenAPI Spec: `http://localhost:8080/v3/api-docs`

### Features
- Interactive API testing
- Request/Response examples
- Authentication support (Bearer token)
- Comprehensive endpoint documentation

### How to Test with Swagger

1. **Login**
   - Go to `POST /api/auth/login`
   - Click "Try it out"
   - Enter credentials: `{"username": "admin", "password": "admin123"}`
   - Execute
   - Copy the `accessToken` from response

2. **Authorize**
   - Click "Authorize" button (top right)
   - Enter: `Bearer <access-token>`
   - Click "Authorize"

3. **Test Protected Endpoints**
   - All subsequent requests will include the JWT token
   - Test any protected endpoint (e.g., GET /api/users)

## Request/Response Examples

### Login
**Request:**
```json
POST /api/auth/login
{
  "username": "admin",
  "password": "admin123"
}
```

**Response (200 OK):**
```json
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "tokenType": "Bearer",
  "expiresIn": 3600,
  "expiresAt": "2026-02-17T14:30:00",
  "refreshToken": "refresh-token-here"
}
```

### Create User
**Request:**
```json
POST /api/users
Authorization: Bearer <access-token>
{
  "username": "john.doe",
  "email": "john.doe@example.com",
  "password": "SecurePass123",
  "roleNames": ["USER", "MANAGER"],
  "branchId": "BRANCH-001"
}
```

**Response (201 Created):**
```json
{
  "id": "user-uuid",
  "username": "john.doe",
  "email": "john.doe@example.com",
  "roles": [
    {
      "id": "role-uuid",
      "name": "USER",
      "permissions": ["INVENTORY_READ"],
      "description": "Standard user"
    }
  ],
  "branchId": "BRANCH-001",
  "status": "ACTIVE",
  "createdAt": "2026-02-17T12:00:00",
  "lastLogin": null
}
```

### Error Response
**Request:**
```json
POST /api/users
Authorization: Bearer <access-token>
{
  "username": "admin",
  "email": "admin@example.com",
  "password": "password123",
  "roleNames": ["USER"]
}
```

**Response (409 Conflict):**
```json
{
  "code": "USER_USERNAME_EXISTS",
  "message": "Username 'admin' already exists",
  "status": 409,
  "timestamp": "2026-02-17T12:00:00",
  "path": "/api/users",
  "validationErrors": null
}
```

## Dependencies

- **Spring Web**: REST controllers, HTTP request handling
- **Spring Security**: JWT authentication, authorization
- **Spring Validation**: Bean validation (`@Valid`, `@NotBlank`, etc.)
- **SpringDoc OpenAPI**: Swagger/OpenAPI documentation
- **SLF4J**: Logging

## Best Practices

1. **Controller Responsibilities**
   - Handle HTTP concerns (requests, responses, status codes)
   - Convert between DTOs and commands
   - Delegate business logic to use cases
   - Extract ActorId from SecurityContext
   - Check authorization for sensitive operations

2. **DTO Design**
   - Immutable records
   - Bean validation annotations
   - OpenAPI/Swagger annotations
   - Separate request/response DTOs

3. **Error Handling**
   - Centralized via `GlobalExceptionHandler`
   - Consistent error response format
   - Appropriate HTTP status codes
   - Don't expose internal details in production

4. **Security**
   - Always extract ActorId for audit logging
   - Check authorization for ADMIN operations
   - Validate all user input
   - Use HTTPS in production

5. **API Design**
   - RESTful URLs
   - Proper HTTP methods (GET, POST, PUT, DELETE)
   - Idempotent operations where appropriate
   - Versioned API (future: `/api/v1/users`)

## Testing

### Manual Testing with curl

**Login:**
```bash
curl -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123"}'
```

**List Users (with JWT):**
```bash
curl -X GET http://localhost:8080/api/users \
  -H "Authorization: Bearer <access-token>"
```

**Create User (ADMIN):**
```bash
curl -X POST http://localhost:8080/api/users \
  -H "Authorization: Bearer <access-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "john.doe",
    "email": "john.doe@example.com",
    "password": "SecurePass123",
    "roleNames": ["USER"],
    "branchId": "BRANCH-001"
  }'
```

### Integration Testing
- See `src/test/java/de/effigenix/infrastructure/web/usermanagement/` for integration tests
- Uses `@SpringBootTest` and `MockMvc`
- Tests authentication, authorization, error handling

## Future Enhancements

1. **API Versioning**: `/api/v1/users`
2. **Rate Limiting**: Prevent API abuse
3. **CORS Configuration**: Configure allowed origins
4. **Request Logging**: Log all API requests
5. **Response Caching**: Cache GET requests
6. **Pagination**: For list endpoints
7. **Filtering/Sorting**: Query parameters for list endpoints
8. **HATEOAS**: Add hypermedia links to responses
9. **GraphQL**: Alternative to REST for complex queries
10. **WebSocket**: For real-time updates

## Production Considerations

1. **Security**
   - Enable HTTPS (TLS/SSL)
   - Restrict Swagger UI access
   - Configure CORS properly
   - Enable CSRF protection (if using cookies)
   - Use secure JWT signing key (store in environment variables)

2. **Performance**
   - Enable response compression (GZIP)
   - Add caching headers
   - Use connection pooling
   - Monitor response times

3. **Monitoring**
   - Add Spring Actuator endpoints
   - Configure metrics (Prometheus/Grafana)
   - Add distributed tracing (Zipkin/Jaeger)
   - Log all errors with correlation IDs

4. **Error Handling**
   - Don't expose stack traces in responses
   - Generic error messages for security
   - Log detailed errors server-side
   - Add error tracking (Sentry/Rollbar)

## References

- [Spring Web Documentation](https://spring.io/guides/gs/rest-service/)
- [Spring Security JWT](https://spring.io/guides/tutorials/spring-boot-oauth2/)
- [SpringDoc OpenAPI](https://springdoc.org/)
- [RESTful API Design Best Practices](https://restfulapi.net/)
- [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
