---
name: Master & Master Data API
description: Full implementation details for the dynamic Master Definition and Master Data Value API added to this project
type: project
originSessionId: 0d46e6bb-7f26-4b4d-86da-46626956f4c9
---
## What was built

A metadata-driven master framework with two layers:
1. **Master Definitions** — define dropdown types dynamically (no hardcoding)
2. **Master Data Values** — manage the actual dropdown values per master

**Why:** To replace hardcoded masters (Location, Discipline, etc.) with a configurable system where new masters and their values can be created without any code changes or deployments.

## Database Tables

### `master_definitions`
Stores the template/type for each master.
- id, master_name (unique, auto-uppercased), display_name, description
- data_type: `text | numeric | code-value`
- selection_type: `single-select | multi-select`
- hierarchy_enabled (boolean), scope: `global | project-specific`
- status: `Active | Inactive`
- business_id (FK → businesses), created_by, updated_by, deleted_by (FK → users)
- softDeletes, timestamps

### `master_data_values`
Stores values (rows) under each master definition.
- id, master_id (FK → master_definitions)
- value_code (nullable), value_label
- parent_value_id (self-referential FK, for hierarchy)
- display_order, status: `Active | Inactive`
- effective_from, effective_to (dates)
- business_id, created_by, updated_by, deleted_by
- softDeletes, timestamps

## Files Created

| Type | Path |
|------|------|
| Migration | `database/migrations/2026_04_28_000001_create_master_definitions_table.php` |
| Migration | `database/migrations/2026_04_28_000002_create_master_data_values_table.php` |
| Model | `app/Models/MasterDefinition.php` |
| Model | `app/Models/MasterDataValue.php` |
| FormRequest | `app/Http/Requests/Masters/StoreMasterDefinitionRequest.php` |
| FormRequest | `app/Http/Requests/Masters/UpdateMasterDefinitionRequest.php` |
| FormRequest | `app/Http/Requests/Masters/StoreMasterDataValueRequest.php` |
| FormRequest | `app/Http/Requests/Masters/BulkStoreMasterDataRequest.php` |
| Controller | `app/Http/Controllers/Masters/MasterDefinitionController.php` |
| Controller | `app/Http/Controllers/Masters/MasterDataController.php` |
| Routes | `routes/Api/masterConfig.php` |
| Updated | `routes/api.php` (added `require masterConfig.php`) |

## API Endpoints (all under JWT middleware)

### Master Definitions
| Method | URL | Action |
|--------|-----|--------|
| GET | `/api/master-definitions` | List all (filters: status, scope, search) |
| POST | `/api/master-definitions` | Create single or multiple master types (bulk) |
| GET | `/api/master-definitions/{id}` | Get single master + value count |
| PUT | `/api/master-definitions/{id}` | Update master |
| DELETE | `/api/master-definitions/{id}` | Soft delete (blocked if has values) |
| GET | `/api/master-definitions/{id}/values` | Get active values (for dropdowns, nested if hierarchy) |

### Master Data
| Method | URL | Action |
|--------|-----|--------|
| GET | `/api/master-data?master_id=X` | List values for a master (filters: status, search) |
| POST | `/api/master-data` | Add single value |
| POST | `/api/master-data/bulk` | Bulk add values |
| GET | `/api/master-data/{id}` | Get single value with parent/children |
| PUT | `/api/master-data/{id}` | Update value |
| DELETE | `/api/master-data/{id}` | Soft delete (blocked if has children) |
| PATCH | `/api/master-data/{id}/toggle` | Toggle Active/Inactive |

## Business Rules Implemented
- `master_name` is always stored in UPPERCASE
- Deleting a master is blocked if it has any values
- Deleting a value is blocked if it has child values
- `GET /values` returns only Active, non-deleted values ordered by display_order
- Multi-tenant: business_id is automatically set from JWT token
- All mutations record created_by / updated_by / deleted_by from Auth::id()
- `POST /api/master-definitions` supports both single and bulk creation (auto-detects based on payload format)

## Usage Examples

### Single Master Definition Creation
```json
POST /api/master-definitions
{
  "display_name": "Location",
  "master_name": "Location",
  "description": "Geographic locations",
  "data_type": "text",
  "selection_type": "single-select",
  "scope": "global",
  "status": "Active"
}
```

### Bulk Master Definition Creation
```json
POST /api/master-definitions
[
  {
    "display_name": "Location",
    "master_name": "Location",
    "description": "Geographic locations",
    "data_type": "text",
    "selection_type": "single-select",
    "scope": "global",
    "status": "Active"
  },
  {
    "display_name": "Department",
    "master_name": "Department",
    "description": "Company departments",
    "data_type": "text",
    "selection_type": "single-select",
    "scope": "global",
    "status": "Active"
  }
]
```

### Bulk Master Data Values Creation
```json
POST /api/master-data/bulk
{
  "master_id": 1,
  "values": [
    {
      "value_label": "New York",
      "value_code": "NY",
      "display_order": 1
    },
    {
      "value_label": "Los Angeles",
      "value_code": "LA",
      "display_order": 2
    }
  ]
}
```

## How to apply
When the user asks about masters, dropdowns, or adding this feature to forms/workflows, reference master_id (not hardcoded values). The `GET /api/master-definitions/{id}/values` endpoint is the one to use for rendering dropdowns at runtime.
