> For the complete documentation index, see [llms.txt](https://docs.ohalee.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ohalee.com/products/playerdatahistory/for-developers.md).

# For Developers

{% hint style="info" %}
PlayerDataHistory does not ship a public API artifact or service provider. This page documents its architecture and storage schema so you can integrate by **reading the database** directly.
{% endhint %}

## Architecture

The plugin is split into platform-independent and platform-specific modules:

* **common** — the shared core: command framework, storage layer, action logging, configuration and localisation.
* **bukkit** / **bukkit-loader** — the Bukkit/Spigot/Paper platform and its jar-in-jar loader.
* **velocity** — the Velocity proxy platform.

The core is built on a LuckPerms-style foundation: a **JarInJar loader** unpacks the plugin and downloads its runtime dependencies on first start, a `Storage` abstraction sits over the SQL implementations (H2 and MariaDB via HikariCP), and buffered actions are flushed to storage on the configured interval.

## Storage Schema

All tables use the configured `data.table-prefix` (default `datahistory_`) in place of `{prefix}`. Every log table references `players(id)` by `user_id`.

### `{prefix}players`

| Column     | Type        | Notes               |
| ---------- | ----------- | ------------------- |
| `id`       | INT (PK)    | Internal user id    |
| `username` | VARCHAR(16) | Last known username |
| `uuid`     | VARCHAR(36) | Unique              |
| `date`     | DATETIME    | First seen          |

### `{prefix}sessions`

| Column         | Type        | Notes                          |
| -------------- | ----------- | ------------------------------ |
| `id`           | INT (PK)    |                                |
| `user_id`      | INT (FK)    | → `players.id`                 |
| `ip`           | VARCHAR(32) | Connecting IP                  |
| `connect`      | DATETIME    | Join time                      |
| `disconnect`   | DATETIME    | Leave time (null while online) |
| `playtime`     | BIGINT      | Session playtime               |
| `client_brand` | VARCHAR(64) | Client brand, if known         |
| `version`      | INT         | Protocol version               |

### `{prefix}servers`

| Column    | Type        | Notes                    |
| --------- | ----------- | ------------------------ |
| `user_id` | INT (FK)    | → `players.id`           |
| `depart`  | VARCHAR(32) | Server left              |
| `arrive`  | VARCHAR(32) | Server joined            |
| `date`    | DATETIME    | When the switch happened |

### `{prefix}commands`

| Column    | Type         | Notes            |
| --------- | ------------ | ---------------- |
| `user_id` | INT (FK)     | → `players.id`   |
| `command` | VARCHAR(512) | Command executed |
| `server`  | VARCHAR(64)  | Origin server    |
| `date`    | DATETIME     |                  |

### `{prefix}messages`

| Column    | Type         | Notes          |
| --------- | ------------ | -------------- |
| `user_id` | INT (FK)     | → `players.id` |
| `message` | VARCHAR(512) | Chat message   |
| `server`  | VARCHAR(64)  | Origin server  |
| `date`    | DATETIME     |                |

### `datahistory_web_users`

Stores web-panel accounts created with `/dh register` (`username`, hashed `password`).
