# Core Data

URL: https://zerodev.ca/docs/prism/developer-documentation/core-data

> Read and change products, licenses and users from your own module.



Products, licenses, users and roles belong to the `core` module. Work with them through its handlers where one exists, so slugs, keys, events and owner rules are handled the same way the dashboard does.

```js
get catalog() {
    return this.prism.modules.handlers.get("core", "catalog");
}
```

Add `"core"` to your manifest's `requires`. Core is always loaded, but this makes your module load after it.

## Handlers

| Handler    | What it covers                                  |
| ---------- | ----------------------------------------------- |
| `catalog`  | Products, their downloads, reviews and updates. |
| `licenses` | Licenses and keys.                              |
| `checkout` | Pricing, coupons, gateways and fulfilment.      |
| `access`   | Users, roles and permissions.                   |
| `files`    | Uploaded files and download links.              |

## Products

```js
const product = await this.catalog.save({ name: "My Product", price: 9.99, status: "published" });
await this.catalog.save({ price: 4.99 }, product);
const found = await this.catalog.resolve("my-product");
const shown = await this.catalog.find("my-product");
```

| Method                  | What it does                                                                                                                      |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `save(input, existing)` | Create a product, or change `existing`. Makes the slug from the name when left out. Fires `product.created` or `product.updated`. |
| `resolve(reference)`    | Find any product by ID or slug, or return `null`.                                                                                 |
| `find(slug)`            | A published product by slug or ID, in its public shape. Throws a 404 when missing.                                                |
| `catalog(query)`        | `{ rows, total }` of published products in their public shape, featured first.                                                    |
| `public(row)`           | A product row as the storefront API returns it, with sale prices and without download details.                                    |
| `link(id, addonIndex)`  | A download URL for the product or one of its addons.                                                                              |

The `products` model holds every column. See the [product fields](/docs/prism/products#creating-a-product).

## Licenses

```js
const licenses = this.prism.modules.handlers.get("core", "licenses");
const license = await licenses.save({ product_id: product.id, user_id: user.id, addons: [] });
await licenses.deactivate(license.id);
const owned = await licenses.customer(request.actor);
```

| Method                            | What it does                                                                      |
| --------------------------------- | --------------------------------------------------------------------------------- |
| `save(input, existing)`           | Create a license, or change `existing`. A key is generated unless `key` is given. |
| `activate(id)` / `deactivate(id)` | Change the status.                                                                |
| `unique()`                        | A new unused key.                                                                 |
| `describe(row)`                   | A license with its product details.                                               |
| `customer(actor)`                 | Every license the signed-in user owns, as shown on **My Licenses**.               |
| `verifyOwner(id, actor)`          | The license, if the actor owns it and it is active. Throws otherwise.             |

| Field        | What it does                            |
| ------------ | --------------------------------------- |
| `product_id` | Required on create.                     |
| `user_id`    | The `id` of a row in the `staff` model. |
| `status`     | `active`, `inactive` or `deactivated`.  |
| `expires_at` | A date, or `null` for lifetime.         |
| `seats`      | Defaults to `1`.                        |
| `addons`     | Names of the product's addons.          |

## Users

Every account is a row in the `staff` model, customers included. A row with a `role_id` or extra `permissions` is a team member.

```js
const access = this.prism.modules.handlers.get("core", "access");
const user = await access.resolve("customer@example.com");
await access.update(user.id, { points: user.points + 100 });
```

| Method               | What it does                                                                                           |
| -------------------- | ------------------------------------------------------------------------------------------------------ |
| `resolve(reference)` | Find a user by ID, Discord ID, email or name, with their role name.                                    |
| `create(input)`      | Add a user by name, email or Discord ID.                                                               |
| `update(id, input)`  | Change `name`, `email`, `role_id`, `permissions`, `points` or `active`. Disabling ends their sessions. |
| `remove(id)`         | Delete a user and their sign-in account.                                                               |
| `permissions(row)`   | Their role's permissions plus their own.                                                               |

The owner cannot be disabled or removed.

## Purchases

To issue licenses the way a paid checkout does, with points, coupon counts, events and the purchase webhook:

```js
await this.prism.modules.handlers.get("core", "checkout").fulfill({
    customerEmail: "customer@example.com",
    items: [{ productId: product.id, quantity: 1, addons: [] }],
    pointsUsed: 0,
    pointsEarned: 0,
    couponCode: null
});
```

To react to purchases instead, listen for [`checkout.fulfilled`](/docs/prism/developer-documentation/events).
