> For the complete documentation index, see [llms.txt](https://tyrix.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tyrix.gitbook.io/docs/script-resources/tyrix-droply/roles.md).

# Roles

Droply resolves four roles. All of them come from the player's live **tyrix\_business** identity — Droply stores no job data of its own.

| Role             | Resolved from                                                                                            |
| ---------------- | -------------------------------------------------------------------------------------------------------- |
| **Server admin** | `exports.tyrix_business:isPlayerAdmin` — the `Config.AdminGroups` / `Config.AdminIdentifiers` allowlist. |
| **Boss**         | `exports.tyrix_business:isBossOf` — `Config.BossGrades` or QBCore's `job.isboss`.                        |
| **Manager**      | Identifier present in the storefront's `managers` list.                                                  |
| **Employee**     | Employed by the business, with grade ≥ the storefront's `min_grade`.                                     |

Resolution short-circuits in that order — boss is checked first, since it is the most powerful role.

## Permission matrix

| Action                                                               | Admin | Boss | Manager | Employee |
| -------------------------------------------------------------------- | :---: | :--: | :-----: | :------: |
| Assign crafting stations to a business                               |   ✅   |   —  |    —    |     —    |
| Storefront profile (name, description, address, phone, logo, banner) |   —   |   ✅  |    —    |     —    |
| Item prices                                                          |   —   |   ✅  |    ✅    |     —    |
| Item descriptions & categories                                       |   —   |   ✅  |    —    |     —    |
| Hide / show items                                                    |   —   |   ✅  |    ✅    |     —    |
| Delivery fee                                                         |   —   |   ✅  |    ✅    |     —    |
| Commission                                                           |   —   |   ✅  |    —    |     —    |
| Minimum grade                                                        |   —   |   ✅  |    —    |     —    |
| Manage managers                                                      |   —   |   ✅  |    —    |     —    |
| Customer blocklist                                                   |   —   |   ✅  |    ✅    |     —    |
| Promotions                                                           |   —   |   ✅  |    —    |     —    |
| Open / close the store                                               |   —   |   ✅  |    ✅    |     —    |
| View the orders queue                                                |   —   |   ✅  |    ✅    |     ✅    |
| Accept & fulfil deliveries                                           |   —   |   ✅  |    ✅    |     ✅    |

Fulfilment additionally requires the employee's grade to meet `min_grade`.

## How the manager subset is enforced

Managers and bosses share one save endpoint, so the server does not rely on the UI to hide fields. When a manager saves a storefront, the identity, branding, and strategy fields are **overwritten with the existing row's values before validation runs** — display name, phone, description, address, logo, banner, commission, and minimum grade. Descriptions, categories, and item-category assignments are nilled so the preserve-when-omitted paths leave them untouched.

The result: a manager can forge any payload they like and still only change the delivery fee, item prices, and hidden items.

## Employees with no storefront

If a player is on a business's job but that business has no storefront row yet, Droply still resolves them as an **employee**. They get no admin access, but fulfilment works the instant a boss opens a storefront — no relog needed.

## Re-checking

Every admin event re-resolves the caller's role server-side, regardless of what the UI allowed. Unauthorised attempts are dropped and written to the `exploit` Discord channel with the player's identifiers.

Rate limiting is applied per player per event on top of the role check — typically 500 ms on reads and 1000 ms on writes.

## Station assignment is admin-only

Bosses cannot change which crafting stations feed their menu; that is deliberate. It means a boss can never widen their own catalogue, only price what an admin has already granted them. Attempts to set `station_ids` through the boss save path are ignored — the existing value is always preserved.
