# Database

Koja Spawn Selector creates its tables when the resource starts (and adds the `state` column to an older `koja_spawnselector` table). `sql/koja_spawnselector.sql` has the main table if you prefer to import it.

| Table | What it holds |
| --- | --- |
| `koja_spawnselector` | One row per character: last position, remembered choice, drop record and restrictions |
| `koja_spawnselector_points` | Locations made in the [editor](/new/spawn-selector/admin-tools) or with `SavePoint` / `AddEvent` |
| `koja_spawnselector_images` | Location photos (640 × 360 JPEG as a data URI), by spawn id |
| `koja_spawnselector_log` | One row per spawn, for the Stats tab |

## koja_spawnselector

| Column | What it holds |
| --- | --- |
| `identifier` | Character identifier from koja-lib: ESX `identifier` (with the `char1:` prefix on multicharacter), QBCore `citizenid` |
| `x`, `y`, `z`, `heading` | Last saved position |
| `last_choice` | Id of the location picked last time, for `Config.Open.RememberChoice` |
| `updated_at` | Unix time of the last position save; `0` = no position yet |
| `state` | JSON: `drop` (the last disconnect: kind, reason, time, dead, combat, coords), `lastLock` (from `LockLastLocation`) and `restrictions` (from `SetRestriction`) |

## koja_spawnselector_points

| Column | What it holds |
| --- | --- |
| `id` | Spawn id |
| `data` | JSON spawn definition |
| `expires_at` | Unix time an event ends, `NULL` = permanent |
| `created_by` | Identifier of the admin or the resource that created it |
| `created_at` | Unix time |

## koja_spawnselector_images

| Column | What it holds |
| --- | --- |
| `spawn_id` | Spawn id (config, API or editor) |
| `data` | `data:image/jpeg;base64,...` (max 400 kB) |
| `updated_at` | Unix time, used to refresh cached images |

## koja_spawnselector_log

| Column | What it holds |
| --- | --- |
| `identifier`, `spawn_id`, `category`, `origin` | Who spawned where |
| `created_at` | Unix time (indexed). Rows older than `Config.Stats.KeepDays` are removed on start |

## Framework fallback

A character without a saved position gets "Last location" from the framework when `Config.LastLocation.FrameworkFallback` is on: `users.position` (ESX) or `players.position` (QBCore / QBox). Nothing is ever written to the framework tables.

## Resetting

```sql
-- one character
DELETE FROM `koja_spawnselector` WHERE `identifier` = 'char1:abc123';
-- clear every combat / death lock but keep positions
UPDATE `koja_spawnselector` SET `state` = NULL;
-- empty the stats
TRUNCATE `koja_spawnselector_log`;
```
