# Shared: Master & location lookups

Used by multiple PTW Admin pages via `useMasterData()` and `masterApi.js`.

**Frontend service:** `ptw_frontend/src/services/masterApi.js`

---

## Master tables (generic CRUD)

Base path: `/api/ptw/<table>`

| Table | Primary key | Typical use |
|-------|-------------|-------------|
| `job_title` | `job_title_id` | User profiles |
| `roles` | `role_id` | Role assignment |
| `account_status` | `status_id` | Account state |
| `departments` | `department_id` | Org structure |
| `country` | `country_id` | Geography filters |
| `city` | `city_id` | Geography filters |
| `tickets_status` | `status_id` | Ticket workflow |
| `tickets_type` | `type_id` | Ticket categorization |
| `ptw_form_type` | `form_type_id` | Form metadata |
| `ptw_job_type` | `job_type_id` | Permit job types & chart colours |
| `ptw_question_type` | `question_type_id` | Question rendering |
| `ptw_permit_status` | `permit_status_id` | Permit lifecycle labels |

### List (used on most form/permit pages)

```http
GET /api/ptw/ptw_job_type
Authorization: Bearer <admin_token>
```

Response: JSON array of rows.

Optional filters: `?job_type_id=1`, `?job_type_name_like=hot`.

---

## Locations

```http
GET /api/ptw/locations
Authorization: Bearer <admin_token>
```

Response: array of location rows. Frontend normalizes via `normalizeLocationRow`.

Used on **Permits & Submissions** for location filters and permit assignment.

---

## Frontend helper

`useMasterData()` loads all `MASTER_TABLES` in parallel on mount. Pages read e.g. `data.ptw_job_type`, `data.tickets_status` without calling each table individually in page code.

---

## SQL queries

All master tables and `locations` use the **generic CRUD router** (`genericCrudController.js`).

### List all rows

```sql
SELECT * FROM `<table>`;
```

With query filter, e.g. `GET /ptw_job_type?job_type_id=2`:

```sql
SELECT * FROM `ptw_job_type` WHERE `job_type_id` = ?;
```

With LIKE filter, e.g. `?job_type_name_like=hot`:

```sql
SELECT * FROM `ptw_job_type` WHERE `job_type_name` LIKE ?;
-- bound value: '%hot%'
```

### Get one row

```sql
SELECT * FROM `<table>` WHERE `<pk>` = ? LIMIT 1;
```

Example — job type by ID:

```sql
SELECT * FROM `ptw_job_type` WHERE `job_type_id` = ? LIMIT 1;
```

### Create / update / delete

```sql
INSERT INTO `<table>` (`col1`, `col2`) VALUES (?, ?);

UPDATE `<table>` SET `col1` = ? WHERE `<pk>` = ?;

DELETE FROM `<table>` WHERE `<pk>` = ?;
```

### Locations list

```sql
SELECT * FROM `locations`;
-- optional: WHERE `location_id` = ? OR `location_name_like` via query params
```
