# Permits & Submissions

| | |
|---|---|
| **Nav ID** | `permits-submissions` |
| **Component** | `AdminPermitsPage.jsx` |
| **Services** | `permitsApi.js`, `formsApi.js`, `masterApi.js`, `usersApi.js` |

Also uses `useMasterData()` for permit status, job types, countries (see [shared-master-data.md](shared-master-data.md)).

---

## Endpoints

### GET `/ptw_permits`

List permits with optional filters and joined `location_name`.

```http
GET /api/ptw/ptw_permits?permit_status_id=2&location_id=3
Authorization: Bearer <admin_token>
```

Supports `column=value` and `column_like=value` on permit columns.

---

### GET `/ptw_permits/:permit_id`

Single permit row.

---

### POST `/ptw_permits`

Create (initialize) a permit.

```json
{
  "permit_status_id": 1,
  "location_id": 3,
  "country_id": 1,
  "department_id": 2,
  "uploader_user_id": 10
}
```

- `uploader_user_id` defaults to JWT user if omitted.
- `permit_number` auto-generated as `PTW-<timestamp>` if omitted.

**Response (201):**

```json
{
  "insertedId": 42,
  "permit_number": "PTW-1719500000000",
  "affectedRows": 1
}
```

---

### PUT `/ptw_permits/:permit_id`

Update permit fields (commonly status transition or validity).

Writable columns: `permit_number`, `uploader_user_id`, `permit_status_id`, `country_id`, `location_id`, `department_id`.

---

### DELETE `/ptw_permits/:permit_id`

Delete permit record.

---

### GET `/ptw_submissions`

List submissions. Filter e.g. `?permit_id=42`.

---

### POST `/submissions`

Full form submission — see [fill-form.md](fill-form.md).

---

### GET `/locations`, `/ptw_form_details`, `/users/:user_id`

Supporting lookups for filters and display names.

---

## Page flow

1. Load permits, master data, locations, forms.
2. Filter by dashboard deep-link, date range, country, location, job type.
3. Create / edit / delete permits.
4. View submission counts via `listSubmissions({ permit_id })`.
5. For active permits, open lifecycle workflows: **Handover**, **Audit** (`permit-audit`), or **Handback** — see [permit-lifecycle.md](permit-lifecycle.md).

**Controller:** `ptwPermitController.js`

---

## SQL queries

### List permits

```sql
SELECT p.*, loc.location_name, loc.country_id AS location_country_id
FROM ptw_permits p
LEFT JOIN locations loc ON loc.location_id = p.location_id
WHERE p.`permit_status_id` = ?    -- optional query filters
  AND p.`location_id` = ?
ORDER BY p.permit_id DESC;
```

### Get one permit

```sql
SELECT * FROM ptw_permits WHERE permit_id = ? LIMIT 1;
```

### Create permit

```sql
INSERT INTO ptw_permits (`permit_number`, `uploader_user_id`, `permit_status_id`, ...)
VALUES (?, ?, ?, ...);
-- permit_number defaults to 'PTW-<timestamp>' if not supplied
```

### Update permit

Validates status FK first:

```sql
SELECT permit_status_id FROM ptw_permit_status WHERE permit_status_id = ? LIMIT 1;

UPDATE ptw_permits
SET `permit_status_id` = ?, `location_id` = ?, ...
WHERE permit_id = ?;
```

### Delete permit (transaction)

```sql
DELETE FROM ptw_opening_closing_map WHERE permit_id = ?;
DELETE FROM ptw_permits WHERE permit_id = ?;
```

### List submissions for a permit

```sql
SELECT * FROM `ptw_submissions` WHERE `permit_id` = ?;
```

### List forms / locations / user (supporting)

```sql
SELECT * FROM `ptw_form_details`;

SELECT * FROM `locations`;

SELECT user_id, employee_name, ... FROM users WHERE user_id = ? LIMIT 1;
```
