# Event Categories Management API

**Author**: Josh S. Sakweli, Backend Lead Team  
**Last Updated**: 2025-12-11  
**Version**: v1.0

**Base URL**: `https://api.nexgate.com/api/v1`

**Short Description**: The Event Categories Management API provides administrative functionality for managing event categories in the Nexgate platform. This API enables authorized users (Staff Admin/Super Admin) to create, update, retrieve event categories, and seed default categories for event classification and organization.

**Hints**: 
- All POST/PUT endpoints require STAFF_ADMIN or SUPER_ADMIN role
- GET endpoints are accessible to all authenticated users
- Category names are unique (case-insensitive)
- Slugs are auto-generated from category names and must be unique
- Slug collisions are handled automatically by appending numbers (e.g., music-1, music-2)
- Categories support featured and active status flags
- Pagination is 1-indexed (page=1 for first page), default size is 10 items
- Event count tracks number of events in each category (updated automatically)
- Color codes must be valid hex format (#FF5733 or #F57)
- Icon URLs must be valid image URLs or paths

---

## Standard Response Format

All API responses follow a consistent structure using our Globe Response Builder pattern:

### Success Response Structure
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Operation completed successfully",
  "action_time": "2025-12-11T10:30:45",
  "data": {
    // Actual response data goes here
  }
}
```

### Error Response Structure
```json
{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Error description",
  "action_time": "2025-12-11T10:30:45",
  "data": "Error description"
}
```

### Standard Response Fields
| Field | Type | Description |
|-------|------|-------------|
| `success` | boolean | Always `true` for successful operations, `false` for errors |
| `httpStatus` | string | HTTP status name (OK, BAD_REQUEST, NOT_FOUND, etc.) |
| `message` | string | Human-readable message describing the operation result |
| `action_time` | string | ISO 8601 timestamp of when the response was generated |
| `data` | object/string | Response payload for success, error details for failures |

---

## HTTP Method Badge Standards

For better visual clarity, all endpoints use colored badges for HTTP methods with the following standard colors:

- **GET** - <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> - Green (Safe, read-only operations)
- **POST** - <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">POST</span> - Blue (Create new resources)
- **PUT** - <span style="background-color: #ffc107; color: black; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">PUT</span> - Yellow (Update/replace entire resource)

---

## EventCategoryResponse Structure

This is the standard response structure returned by all category endpoints:

```json
{
  "categoryId": "550e8400-e29b-41d4-a716-446655440000",
  "name": "Music & Concerts",
  "slug": "music-concerts",
  "description": "Live music performances, concerts, festivals, and DJ events",
  "iconUrl": "https://cdn.nexgate.com/icons/music.svg",
  "colorCode": "#E91E63",
  "isActive": true,
  "isFeatured": true,
  "eventCount": 125,
  "createdBy": "admin_user",
  "createdAt": "2025-12-11T10:30:45",
  "updatedBy": "admin_user",
  "updatedAt": "2025-12-11T14:20:30"
}
```

### Response Field Descriptions

| Field | Type | Description |
|-------|------|-------------|
| categoryId | string (UUID) | Unique identifier for the category |
| name | string | Category display name (unique, case-insensitive) |
| slug | string | URL-friendly identifier (auto-generated, unique) |
| description | string | Category description |
| iconUrl | string | URL or path to category icon image |
| colorCode | string | Hex color code for category theming (#RRGGBB or #RGB) |
| isActive | boolean | Whether category is active and visible |
| isFeatured | boolean | Whether category should be featured/highlighted |
| eventCount | integer | Number of events in this category |
| createdBy | string | Username of the admin who created the category |
| createdAt | string | ISO 8601 timestamp of creation |
| updatedBy | string | Username of the admin who last updated (null if never updated) |
| updatedAt | string | ISO 8601 timestamp of last update (null if never updated) |

---

## Endpoints

## 1. Create Category
**Purpose**: Create a new event category (requires admin privileges)

**Endpoint**: <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">POST</span> `{base_url}/e-events/categories`

**Access Level**: 🔒 Protected (Requires Bearer Token Authentication + Admin Role)

**Required Roles**: ROLE_STAFF_ADMIN or ROLE_SUPER_ADMIN

**Authentication**: Bearer Token

**Request Headers**:
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| Authorization | string | Yes | Bearer token for authentication (format: `Bearer <token>`) |
| Content-Type | string | Yes | Must be `application/json` |

**Request JSON Sample**:
```json
{
  "name": "Music & Concerts",
  "description": "Live music performances, concerts, festivals, and DJ events",
  "iconUrl": "https://cdn.nexgate.com/icons/music.svg",
  "colorCode": "#E91E63",
  "isActive": true,
  "isFeatured": true
}
```

**Request Body Parameters**:
| Parameter | Type | Required | Description | Validation |
|-----------|------|----------|-------------|------------|
| name | string | Yes | Category name | Min: 2, Max: 100 characters |
| description | string | No | Category description | Max: 500 characters |
| iconUrl | string | No | URL or path to icon image | Must be valid image URL (jpg, jpeg, png, gif, svg, webp) or path starting with /icons/ |
| colorCode | string | No | Hex color code | Must be valid hex format: #RRGGBB or #RGB (e.g., #FF5733 or #F57) |
| isActive | boolean | Yes | Whether category is active | Required boolean value |
| isFeatured | boolean | Yes | Whether category is featured | Required boolean value |

**Success Response**: Returns standard EventCategoryResponse structure (see "EventCategoryResponse Structure" section above)

**Success Response Message**: "Category created successfully"

**Success Response JSON Sample**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Category created successfully",
  "action_time": "2025-12-11T10:30:45",
  "data": {
    "categoryId": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Music & Concerts",
    "slug": "music-concerts",
    "description": "Live music performances, concerts, festivals, and DJ events",
    "iconUrl": "https://cdn.nexgate.com/icons/music.svg",
    "colorCode": "#E91E63",
    "isActive": true,
    "isFeatured": true,
    "eventCount": 0,
    "createdBy": "admin_user",
    "createdAt": "2025-12-11T10:30:45",
    "updatedBy": null,
    "updatedAt": null
  }
}
```

**Standard Error Types**:

### Application-Level Exceptions (400-499)
- `400 BAD_REQUEST`: Category already exists (duplicate name)
- `401 UNAUTHORIZED`: Authentication issues (empty, invalid, expired, or malformed tokens)
- `403 FORBIDDEN`: Access denied (insufficient permissions - not admin)
- `404 NOT_FOUND`: User not found or not authenticated
- `422 UNPROCESSABLE_ENTITY`: Validation errors with detailed field information
- `500 INTERNAL_SERVER_ERROR`: Unexpected server errors

**Error Response Examples**:

*Already Exists - Duplicate Name (400):*
```json
{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Category already exists",
  "action_time": "2025-12-11T10:30:45",
  "data": "Category with name 'Music & Concerts' already exists"
}
```

*Access Denied - Insufficient Permissions (403):*
```json
{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Access denied",
  "action_time": "2025-12-11T10:30:45",
  "data": "Access denied. Insufficient permissions."
}
```

*Validation Error - Invalid Name (422):*
```json
{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Validation failed",
  "action_time": "2025-12-11T10:30:45",
  "data": {
    "name": "Category name must be between 2 and 100 characters"
  }
}
```

*Validation Error - Invalid Color Code (422):*
```json
{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Validation failed",
  "action_time": "2025-12-11T10:30:45",
  "data": {
    "colorCode": "Color code must be a valid hex color (e.g., #FF5733 or #F57)"
  }
}
```

*Validation Error - Invalid Icon URL (422):*
```json
{
  "success": false,
  "httpStatus": "UNPROCESSABLE_ENTITY",
  "message": "Validation failed",
  "action_time": "2025-12-11T10:30:45",
  "data": {
    "iconUrl": "Icon URL must be a valid image URL or path"
  }
}
```

---

## 2. Update Category
**Purpose**: Update an existing event category (requires admin privileges)

**Endpoint**: <span style="background-color: #ffc107; color: black; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">PUT</span> `{base_url}/e-events/categories/{categoryId}`

**Access Level**: 🔒 Protected (Requires Bearer Token Authentication + Admin Role)

**Required Roles**: ROLE_STAFF_ADMIN or ROLE_SUPER_ADMIN

**Authentication**: Bearer Token

**Request Headers**:
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| Authorization | string | Yes | Bearer token for authentication (format: `Bearer <token>`) |
| Content-Type | string | Yes | Must be `application/json` |

**Path Parameters**:
| Parameter | Type | Required | Description | Validation |
|-----------|------|----------|-------------|------------|
| categoryId | string | Yes | UUID of the category to update | Must be valid UUID format |

**Request JSON Sample**:
```json
{
  "name": "Live Music & Concerts",
  "description": "Updated description for live music events",
  "iconUrl": "https://cdn.nexgate.com/icons/music-updated.svg",
  "colorCode": "#FF1744",
  "isActive": true,
  "isFeatured": false
}
```

**Request Body Parameters** (All Optional):
| Parameter | Type | Required | Description | Validation |
|-----------|------|----------|-------------|------------|
| name | string | No | Updated category name | Min: 2, Max: 100 characters |
| description | string | No | Updated description | Max: 500 characters |
| iconUrl | string | No | Updated icon URL/path | Must be valid image URL or path |
| colorCode | string | No | Updated hex color code | Must be valid hex format: #RRGGBB or #RGB |
| isActive | boolean | No | Updated active status | |
| isFeatured | boolean | No | Updated featured status | |

**Success Response**: Returns standard EventCategoryResponse structure with updated values

**Success Response Message**: "Category updated successfully"

**Standard Error Types**:

### Application-Level Exceptions (400-499)
- `400 BAD_REQUEST`: Category name already exists (when changing name to duplicate)
- `401 UNAUTHORIZED`: Authentication issues
- `403 FORBIDDEN`: Access denied (insufficient permissions - not admin)
- `404 NOT_FOUND`: Category not found with given ID
- `422 UNPROCESSABLE_ENTITY`: Validation errors
- `500 INTERNAL_SERVER_ERROR`: Unexpected server errors

**Error Response Examples**:

*Not Found - Invalid Category ID (404):*
```json
{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Category not found",
  "action_time": "2025-12-11T10:30:45",
  "data": "Category not found with ID: 550e8400-e29b-41d4-a716-446655440000"
}
```

*Already Exists - Duplicate Name (400):*
```json
{
  "success": false,
  "httpStatus": "BAD_REQUEST",
  "message": "Category already exists",
  "action_time": "2025-12-11T10:30:45",
  "data": "Category with name 'Sports & Fitness' already exists"
}
```

---

## 3. Get Category by ID
**Purpose**: Retrieve a single category by its UUID

**Endpoint**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{base_url}/e-events/categories/{categoryId}`

**Access Level**: 🔒 Protected (Requires Bearer Token Authentication)

**Authentication**: Bearer Token

**Request Headers**:
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| Authorization | string | Yes | Bearer token for authentication (format: `Bearer <token>`) |
| Content-Type | string | Yes | Must be `application/json` |

**Path Parameters**:
| Parameter | Type | Required | Description | Validation |
|-----------|------|----------|-------------|------------|
| categoryId | string | Yes | UUID of the category to retrieve | Must be valid UUID format |

**Success Response**: Returns standard EventCategoryResponse structure

**Success Response Message**: "Category retrieved successfully"

**Success Response JSON Sample**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Category retrieved successfully",
  "action_time": "2025-12-11T10:30:45",
  "data": {
    "categoryId": "550e8400-e29b-41d4-a716-446655440000",
    "name": "Music & Concerts",
    "slug": "music-concerts",
    "description": "Live music performances, concerts, festivals, and DJ events",
    "iconUrl": "https://cdn.nexgate.com/icons/music.svg",
    "colorCode": "#E91E63",
    "isActive": true,
    "isFeatured": true,
    "eventCount": 125,
    "createdBy": "admin_user",
    "createdAt": "2025-12-11T10:30:45",
    "updatedBy": "admin_user",
    "updatedAt": "2025-12-11T14:20:30"
  }
}
```

**Standard Error Types**:

### Application-Level Exceptions (400-499)
- `401 UNAUTHORIZED`: Authentication issues
- `404 NOT_FOUND`: Category not found with given ID
- `500 INTERNAL_SERVER_ERROR`: Unexpected server errors

---

## 4. Get Category by Slug
**Purpose**: Retrieve a single category by its URL-friendly slug

**Endpoint**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{base_url}/e-events/categories/slug/{slug}`

**Access Level**: 🔒 Protected (Requires Bearer Token Authentication)

**Authentication**: Bearer Token

**Request Headers**:
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| Authorization | string | Yes | Bearer token for authentication (format: `Bearer <token>`) |
| Content-Type | string | Yes | Must be `application/json` |

**Path Parameters**:
| Parameter | Type | Required | Description | Validation |
|-----------|------|----------|-------------|------------|
| slug | string | Yes | URL-friendly slug of the category | Lowercase, hyphen-separated (e.g., music-concerts) |

**Example Request URL**: `https://api.nexgate.com/api/v1/e-events/categories/slug/music-concerts`

**Success Response**: Returns standard EventCategoryResponse structure

**Success Response Message**: "Category retrieved successfully"

**Standard Error Types**:

### Application-Level Exceptions (400-499)
- `401 UNAUTHORIZED`: Authentication issues
- `404 NOT_FOUND`: Category not found with given slug
- `500 INTERNAL_SERVER_ERROR`: Unexpected server errors

**Error Response Example**:

*Not Found - Invalid Slug (404):*
```json
{
  "success": false,
  "httpStatus": "NOT_FOUND",
  "message": "Category not found",
  "action_time": "2025-12-11T10:30:45",
  "data": "Category not found with slug: non-existent-category"
}
```

---

## 5. Get All Categories
**Purpose**: Retrieve all event categories (unpaginated, complete list)

**Endpoint**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{base_url}/e-events/categories/all`

**Access Level**: 🔒 Protected (Requires Bearer Token Authentication)

**Authentication**: Bearer Token

**Request Headers**:
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| Authorization | string | Yes | Bearer token for authentication (format: `Bearer <token>`) |
| Content-Type | string | Yes | Must be `application/json` |

**Success Response JSON Sample**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Categories retrieved successfully",
  "action_time": "2025-12-11T10:30:45",
  "data": [
    {
      "categoryId": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Music & Concerts",
      "slug": "music-concerts",
      "description": "Live music performances, concerts, festivals, and DJ events",
      "iconUrl": "https://cdn.nexgate.com/icons/music.svg",
      "colorCode": "#E91E63",
      "isActive": true,
      "isFeatured": true,
      "eventCount": 125,
      "createdBy": "admin_user",
      "createdAt": "2025-12-11T10:30:45",
      "updatedBy": null,
      "updatedAt": null
    },
    {
      "categoryId": "660e8400-e29b-41d4-a716-446655440001",
      "name": "Sports & Fitness",
      "slug": "sports-fitness",
      "description": "Yoga, gym classes, marathons, tournaments, and outdoor activities",
      "iconUrl": "https://cdn.nexgate.com/icons/sports.svg",
      "colorCode": "#4CAF50",
      "isActive": true,
      "isFeatured": true,
      "eventCount": 89,
      "createdBy": "admin_user",
      "createdAt": "2025-12-11T10:30:45",
      "updatedBy": null,
      "updatedAt": null
    }
  ]
}
```

**Success Response Fields**:
| Field | Description |
|-------|-------------|
| data | Array of EventCategoryResponse objects (complete list, no pagination) |

**Standard Error Types**:

### Application-Level Exceptions (400-499)
- `401 UNAUTHORIZED`: Authentication issues
- `500 INTERNAL_SERVER_ERROR`: Unexpected server errors

---

## 6. Get Paginated Categories
**Purpose**: Retrieve event categories with pagination support

**Endpoint**: <span style="background-color: #28a745; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">GET</span> `{base_url}/e-events/categories/paged`

**Access Level**: 🔒 Protected (Requires Bearer Token Authentication)

**Authentication**: Bearer Token

**Request Headers**:
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| Authorization | string | Yes | Bearer token for authentication (format: `Bearer <token>`) |
| Content-Type | string | Yes | Must be `application/json` |

**Query Parameters**:
| Parameter | Type | Required | Description | Validation | Default |
|-----------|------|----------|-------------|------------|---------|
| page | integer | No | Page number (1-indexed) | Min: 1 | 1 |
| size | integer | No | Number of items per page | Min: 1, Max: 100 | 10 |

**Example Request URL**: `https://api.nexgate.com/api/v1/e-events/categories/paged?page=1&size=10`

**Success Response JSON Sample**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Categories retrieved successfully",
  "action_time": "2025-12-11T10:30:45",
  "data": {
    "content": [
      {
        "categoryId": "550e8400-e29b-41d4-a716-446655440000",
        "name": "Music & Concerts",
        "slug": "music-concerts",
        "description": "Live music performances, concerts, festivals, and DJ events",
        "iconUrl": "https://cdn.nexgate.com/icons/music.svg",
        "colorCode": "#E91E63",
        "isActive": true,
        "isFeatured": true,
        "eventCount": 125,
        "createdBy": "admin_user",
        "createdAt": "2025-12-11T10:30:45",
        "updatedBy": null,
        "updatedAt": null
      }
    ],
    "pageable": {
      "pageNumber": 0,
      "pageSize": 10,
      "sort": {
        "sorted": false,
        "empty": true,
        "unsorted": true
      },
      "offset": 0,
      "paged": true,
      "unpaged": false
    },
    "totalPages": 1,
    "totalElements": 10,
    "last": true,
    "size": 10,
    "number": 0,
    "sort": {
      "sorted": false,
      "empty": true,
      "unsorted": true
    },
    "numberOfElements": 10,
    "first": true,
    "empty": false
  }
}
```

**Success Response Fields**:
| Field | Description |
|-------|-------------|
| content | Array of EventCategoryResponse objects for current page |
| totalPages | Total number of pages available |
| totalElements | Total number of categories across all pages |
| size | Number of items per page (requested size) |
| number | Current page number (0-indexed in response) |
| first | Boolean indicating if this is the first page |
| last | Boolean indicating if this is the last page |
| empty | Boolean indicating if the result set is empty |

**Standard Error Types**:

### Application-Level Exceptions (400-499)
- `401 UNAUTHORIZED`: Authentication issues
- `500 INTERNAL_SERVER_ERROR`: Unexpected server errors

---

## 7. Seed Categories
**Purpose**: Populate the database with default event categories (requires admin privileges)

**Endpoint**: <span style="background-color: #007bff; color: white; padding: 4px 8px; border-radius: 4px; font-family: monospace; font-size: 12px; font-weight: bold;">POST</span> `{base_url}/e-events/categories/seed`

**Access Level**: 🔒 Protected (Requires Bearer Token Authentication + Admin Role)

**Required Roles**: ROLE_STAFF_ADMIN or ROLE_SUPER_ADMIN

**Authentication**: Bearer Token

**Request Headers**:
| Header | Type | Required | Description |
|--------|------|----------|-------------|
| Authorization | string | Yes | Bearer token for authentication (format: `Bearer <token>`) |
| Content-Type | string | Yes | Must be `application/json` |

**Request Body**: None (no body required)

**Default Categories Seeded**:

This endpoint creates the following 10 default categories (if they don't already exist):

1. **Music & Concerts** - Live music performances, concerts, festivals, and DJ events (Featured)
2. **Sports & Fitness** - Yoga, gym classes, marathons, tournaments, and outdoor activities (Featured)
3. **Business & Networking** - Professional meetups, conferences, workshops, and networking events (Featured)
4. **Food & Drink** - Food festivals, cooking classes, wine tastings, and dining experiences
5. **Arts & Culture** - Art exhibitions, theater, dance, museums, and cultural events
6. **Education & Learning** - Workshops, seminars, courses, bootcamps, and training sessions (Featured)
7. **Social & Community** - Parties, meetups, social clubs, game nights, and community events
8. **Technology & Innovation** - Tech talks, hackathons, product launches, and startup events
9. **Wellness & Spirituality** - Meditation, yoga retreats, healing workshops, and mindfulness events
10. **Entertainment** - Comedy shows, movie screenings, gaming, and entertainment events

**Success Response JSON Sample**:
```json
{
  "success": true,
  "httpStatus": "OK",
  "message": "Categories seeded successfully",
  "action_time": "2025-12-11T10:30:45",
  "data": [
    {
      "categoryId": "550e8400-e29b-41d4-a716-446655440000",
      "name": "Music & Concerts",
      "slug": "music-concerts",
      "description": "Live music performances, concerts, festivals, and DJ events",
      "iconUrl": "",
      "colorCode": "#E91E63",
      "isActive": true,
      "isFeatured": true,
      "eventCount": 0,
      "createdBy": "admin_user",
      "createdAt": "2025-12-11T10:30:45",
      "updatedBy": null,
      "updatedAt": null
    },
    {
      "categoryId": "660e8400-e29b-41d4-a716-446655440001",
      "name": "Sports & Fitness",
      "slug": "sports-fitness",
      "description": "Yoga, gym classes, marathons, tournaments, and outdoor activities",
      "iconUrl": "",
      "colorCode": "#4CAF50",
      "isActive": true,
      "isFeatured": true,
      "eventCount": 0,
      "createdBy": "admin_user",
      "createdAt": "2025-12-11T10:30:45",
      "updatedBy": null,
      "updatedAt": null
    }
    // ... (remaining 8 categories)
  ]
}
```

**Success Response Fields**:
| Field | Description |
|-------|-------------|
| data | Array of EventCategoryResponse objects (newly created categories only, or all existing if none were created) |

**Behavior Notes**:
- Only creates categories that don't already exist (checked by name, case-insensitive)
- If all 10 default categories already exist, returns the existing categories
- All seeded categories are marked as active (`isActive: true`)
- Categories marked as "Featured" have `isFeatured: true`
- Event count starts at 0 for newly seeded categories
- The authenticated admin user is set as `createdBy` for all new categories
- Slugs are auto-generated from category names

**Standard Error Types**:

### Application-Level Exceptions (400-499)
- `401 UNAUTHORIZED`: Authentication issues
- `403 FORBIDDEN`: Access denied (insufficient permissions - not admin)
- `404 NOT_FOUND`: User not found or not authenticated
- `500 INTERNAL_SERVER_ERROR`: Unexpected server errors

**Error Response Example**:

*Access Denied - Not Admin (403):*
```json
{
  "success": false,
  "httpStatus": "FORBIDDEN",
  "message": "Access denied",
  "action_time": "2025-12-11T10:30:45",
  "data": "Access denied. Insufficient permissions."
}
```

---

## Quick Reference Guide

### Common HTTP Status Codes
- `200 OK`: Successful GET/POST/PUT request
- `400 Bad Request`: Invalid request data or business rule violation (duplicate names)
- `401 Unauthorized`: Authentication required/failed
- `403 Forbidden`: Insufficient permissions (not admin)
- `404 Not Found`: Resource not found (category, user)
- `422 Unprocessable Entity`: Validation errors
- `500 Internal Server Error`: Server error

### Authentication & Authorization
- **Bearer Token**: Include `Authorization: Bearer your_token` in headers
- **Required Roles for POST/PUT**: ROLE_STAFF_ADMIN or ROLE_SUPER_ADMIN
- **GET Endpoints**: Accessible to all authenticated users

### Data Format Standards
- **Dates**: ISO 8601 format (2025-12-11T14:30:00)
- **IDs**: UUID format (e.g., 550e8400-e29b-41d4-a716-446655440000)
- **Slugs**: Lowercase, hyphen-separated (e.g., music-concerts)
- **Color Codes**: Hex format #RRGGBB or #RGB (e.g., #FF5733 or #F57)
- **Pagination**: 1-indexed pages (page=1 for first page), default size=10

### Category Name Rules
- Minimum 2 characters, maximum 100 characters
- Must be unique (case-insensitive check)
- Automatically trimmed of whitespace
- Used to auto-generate slug

### Slug Generation Rules
- Auto-generated from category name
- Lowercase only
- Special characters removed
- Spaces replaced with hyphens
- Duplicate hyphens removed
- Leading/trailing hyphens removed
- Collisions handled by appending numbers (e.g., music-1, music-2)

### Icon URL Validation
- Must be valid HTTP/HTTPS URL ending in image extension (jpg, jpeg, png, gif, svg, webp)
- OR must be path starting with `/icons/` ending in image extension
- Examples:
  - Valid: `https://cdn.nexgate.com/icons/music.svg`
  - Valid: `/icons/music.png`
  - Invalid: `https://example.com/file.pdf`

### Color Code Validation
- Must start with `#`
- Must be 6-character hex (e.g., #FF5733) or 3-character hex (e.g., #F57)
- Case-insensitive (A-F or a-f)
- Examples:
  - Valid: `#FF5733`, `#F57`, `#e91e63`
  - Invalid: `FF5733`, `#GG5733`, `#12345`

### Featured Categories
Categories with `isFeatured: true` are typically displayed prominently in UI:
- Music & Concerts
- Sports & Fitness
- Business & Networking
- Education & Learning

### Event Count
- Automatically updated when events are created/deleted in a category
- Starts at 0 for new categories
- Used for analytics and sorting popular categories