Files
t5de-hub/packages/db/drizzle/meta/0011_snapshot.json
T
dhkatz e07a6c6dac
Release / release (push) Successful in 13s
CI / test (push) Successful in 1m5s
CI / image (apps/api/Dockerfile, t5de-hub-api) (push) Successful in 4s
CI / image (apps/web/Dockerfile, t5de-hub-web) (push) Successful in 16s
feat: product drafts, moderator edits, info history, unlisted products, tags and categories (#8)
Phase 2 of the plan in `docs/design.md` ("Next"): product info.

**Drafts**
- A new upload is a draft. Only its creator and moderators can see it, and nobody can get or wear it.
- After uploading, the website goes straight to the product's review page, where the creator checks its info and presses Publish.
- Drafts not published within 30 days are deleted (checked every 10 minutes), and their catalogs get `delete` entries in their changes feed.
- The console's overview shows a "Drafts" to-do.

**Editing is a permission check now** (`product:edit`, from #7)
- Moderators can edit anyone's product. They must give a reason, which the creator sees.
- Moderators can lock fields (`product:lock`). Once a field is locked, only people with `product:edit-locked` can change it, so the creator sees it greyed out with "Locked by a moderator."
- Raising a rating to adult is immediate for anyone who can edit. Lowering it takes `product:rate-lower` (moderators), and is refused while any revision's files are rated adult. With cases (phase 3), a creator's request to lower it will open a rating review.

**Info history**
- Every edit, publish, lock change and undo is recorded with who, when, what changed (before and after) and why.
- It's shown on the edit page to the creator and moderators.
- "Undo" puts back what an entry changed, as a new entry, by the same rules (a creator can't undo a moderator's change to a field that's now locked).
- Moderator actions are also in the creator's audit log.

**Unlisted products and tags**
- An unlisted product is left out of search, lists and creator pages, except for its creator. Its link still works and people can still get it.
- Tags: up to 10 per product, lowercased.
- `/products` filters by `tag` and `catalog`, and a product's tags link to the filtered list.
- People who don't manage a product don't see its state labels (draft, unlisted, locks).

**Console → Products**
- Lists your products with drafts included; moderators can switch to everyone's.
- Filters: draft, published, unlisted, locked, deleted, removed, plus search.
- Shows how many libraries each product is in, and an Edit or Review button.

**Category**
- A product can be filed under a different IMVU category from its parent's.
- The choices are every category path the hub has seen on any product's parent, plus each level of those paths. They're limited to the same top-level category as the parent's, so a product stays the same kind (clothing, furniture or rooms), which the proxy relies on for the shop and inventory tabs.
- The list grows as products are uploaded. IMVU's own category tree, if it has a public one, would replace it.
- Category works like the other info fields: it can be locked, it's in the history, and it can be undone. The product list's category filter, and everything that shows a product's categories (including what the proxy gets), use the chosen path.

**Migration** `0011_product_info`: new product columns and the `product_info_change` table. Existing products count as published (with `published_at` set from their creation date) and listed.

**Compatibility**
- `t5de-catalog` needs no change: the hub's new `draft` field in the registration answer is ignored, and the website doesn't rely on it.
- The proxy only loads products from libraries, and drafts can't be added to one.

**Checks**
- 44 API tests pass, including a new one for moderator edits, locks, history, undo, unlisted, tags, the console list and draft purging, and new checks for category choices.
- Type checks pass.
- On a local hub I loaded the pages as the creator, an admin, another person and a signed-out visitor.
- I submitted the forms through the website, the way a browser does without JavaScript: save info, publish, choosing a category (and undoing it), a moderator's save with and without a reason, save locks, and undo, including a creator's undo refused by a lock. Each saved or refused correctly with the right message.
- Not tried: the upload form's redirect after a real upload to a running catalog.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Phase 2 of the plan in `docs/design.md` ("Next"): product info.

**Drafts**
- A new upload is a draft. Only its creator and moderators can see it, and nobody can get or wear it.
- After uploading, the website goes straight to the product's review page, where the creator checks its info and presses Publish.
- Drafts not published within 30 days are deleted (checked every 10 minutes), and their catalogs get `delete` entries in their changes feed.
- The console's overview shows a "Drafts" to-do.

**Editing is a permission check now** (`product:edit`, from #7)
- Moderators can edit anyone's product. They must give a reason, which the creator sees.
- Moderators can lock fields (`product:lock`). Once a field is locked, only people with `product:edit-locked` can change it, so the creator sees it greyed out with "Locked by a moderator."
- Raising a rating to adult is immediate for anyone who can edit. Lowering it takes `product:rate-lower` (moderators), and is refused while any revision's files are rated adult. With cases (phase 3), a creator's request to lower it will open a rating review.

**Info history**
- Every edit, publish, lock change and undo is recorded with who, when, what changed (before and after) and why.
- It's shown on the edit page to the creator and moderators.
- "Undo" puts back what an entry changed, as a new entry, by the same rules (a creator can't undo a moderator's change to a field that's now locked).
- Moderator actions are also in the creator's audit log.

**Unlisted products and tags**
- An unlisted product is left out of search, lists and creator pages, except for its creator. Its link still works and people can still get it.
- Tags: up to 10 per product, lowercased.
- `/products` filters by `tag` and `catalog`, and a product's tags link to the filtered list.
- People who don't manage a product don't see its state labels (draft, unlisted, locks).

**Console → Products**
- Lists your products with drafts included; moderators can switch to everyone's.
- Filters: draft, published, unlisted, locked, deleted, removed, plus search.
- Shows how many libraries each product is in, and an Edit or Review button.

**Category**
- A product can be filed under a different IMVU category from its parent's.
- The choices are every category path the hub has seen on any product's parent, plus each level of those paths. They're limited to the same top-level category as the parent's, so a product stays the same kind (clothing, furniture or rooms), which the proxy relies on for the shop and inventory tabs.
- The list grows as products are uploaded. IMVU's own category tree, if it has a public one, would replace it.
- Category works like the other info fields: it can be locked, it's in the history, and it can be undone. The product list's category filter, and everything that shows a product's categories (including what the proxy gets), use the chosen path.

**Migration** `0011_product_info`: new product columns and the `product_info_change` table. Existing products count as published (with `published_at` set from their creation date) and listed.

**Compatibility**
- `t5de-catalog` needs no change: the hub's new `draft` field in the registration answer is ignored, and the website doesn't rely on it.
- The proxy only loads products from libraries, and drafts can't be added to one.

**Checks**
- 44 API tests pass, including a new one for moderator edits, locks, history, undo, unlisted, tags, the console list and draft purging, and new checks for category choices.
- Type checks pass.
- On a local hub I loaded the pages as the creator, an admin, another person and a signed-out visitor.
- I submitted the forms through the website, the way a browser does without JavaScript: save info, publish, choosing a category (and undoing it), a moderator's save with and without a reason, save locks, and undo, including a creator's undo refused by a lock. Each saved or refused correctly with the right message.
- Not tried: the upload form's redirect after a real upload to a running catalog.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: dhkatz <[email protected]>
2026-11-05 14:23:26 +00:00

2935 lines
73 KiB
JSON

{
"id": "0b410a02-49ab-42cc-82e6-45b3bd265602",
"prevId": "2a4756bc-d197-4321-84ef-a8238ed002d3",
"version": "7",
"dialect": "postgresql",
"tables": {
"public.account": {
"name": "account",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"account_id": {
"name": "account_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"provider_id": {
"name": "provider_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"access_token": {
"name": "access_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"refresh_token": {
"name": "refresh_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"id_token": {
"name": "id_token",
"type": "text",
"primaryKey": false,
"notNull": false
},
"access_token_expires_at": {
"name": "access_token_expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"refresh_token_expires_at": {
"name": "refresh_token_expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"scope": {
"name": "scope",
"type": "text",
"primaryKey": false,
"notNull": false
},
"password": {
"name": "password",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"account_user": {
"name": "account_user",
"columns": [
{
"expression": "user_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"account_user_id_user_id_fk": {
"name": "account_user_id_user_id_fk",
"tableFrom": "account",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.age_check": {
"name": "age_check",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"imvu_id": {
"name": "imvu_id",
"type": "bigint",
"primaryKey": false,
"notNull": false
},
"provider": {
"name": "provider",
"type": "text",
"primaryKey": false,
"notNull": true
},
"method": {
"name": "method",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": true
},
"over_eighteen": {
"name": "over_eighteen",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"provider_ref": {
"name": "provider_ref",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"checked_at": {
"name": "checked_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"age_check_user": {
"name": "age_check_user",
"columns": [
{
"expression": "user_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"age_check_imvu": {
"name": "age_check_imvu",
"columns": [
{
"expression": "imvu_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"age_check_provider_ref": {
"name": "age_check_provider_ref",
"columns": [
{
"expression": "provider",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "provider_ref",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"age_check_user_id_user_id_fk": {
"name": "age_check_user_id_user_id_fk",
"tableFrom": "age_check",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.audit": {
"name": "audit",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"at": {
"name": "at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"actor_id": {
"name": "actor_id",
"type": "text",
"primaryKey": false,
"notNull": false
},
"action": {
"name": "action",
"type": "text",
"primaryKey": false,
"notNull": true
},
"target": {
"name": "target",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"detail": {
"name": "detail",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'{}'::jsonb"
},
"tags": {
"name": "tags",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'{}'::jsonb"
}
},
"indexes": {
"audit_at": {
"name": "audit_at",
"columns": [
{
"expression": "at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"audit_tags": {
"name": "audit_tags",
"columns": [
{
"expression": "tags",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "gin",
"with": {}
}
},
"foreignKeys": {
"audit_actor_id_user_id_fk": {
"name": "audit_actor_id_user_id_fk",
"tableFrom": "audit",
"tableTo": "user",
"columnsFrom": [
"actor_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.catalog": {
"name": "catalog",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"owner_id": {
"name": "owner_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"url": {
"name": "url",
"type": "text",
"primaryKey": false,
"notNull": true
},
"contact": {
"name": "contact",
"type": "text",
"primaryKey": false,
"notNull": true
},
"visibility": {
"name": "visibility",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'public'"
},
"membership": {
"name": "membership",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'open'"
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'pending'"
},
"status_reason": {
"name": "status_reason",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"max_rating": {
"name": "max_rating",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'adult'"
},
"uploads": {
"name": "uploads",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'anyone'"
},
"mirrors": {
"name": "mirrors",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'approve'"
},
"key_hash": {
"name": "key_hash",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"catalog_url": {
"name": "catalog_url",
"columns": [
{
"expression": "url",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"catalog_owner_id_user_id_fk": {
"name": "catalog_owner_id_user_id_fk",
"tableFrom": "catalog",
"tableTo": "user",
"columnsFrom": [
"owner_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.catalog_change": {
"name": "catalog_change",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"catalog_id": {
"name": "catalog_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"data": {
"name": "data",
"type": "jsonb",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"catalog_change_catalog": {
"name": "catalog_change_catalog",
"columns": [
{
"expression": "catalog_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"catalog_change_catalog_id_catalog_id_fk": {
"name": "catalog_change_catalog_id_catalog_id_fk",
"tableFrom": "catalog_change",
"tableTo": "catalog",
"columnsFrom": [
"catalog_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.catalog_invite": {
"name": "catalog_invite",
"schema": "",
"columns": {
"code": {
"name": "code",
"type": "text",
"primaryKey": true,
"notNull": true
},
"catalog_id": {
"name": "catalog_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_by": {
"name": "created_by",
"type": "text",
"primaryKey": false,
"notNull": false
},
"max_uses": {
"name": "max_uses",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"uses": {
"name": "uses",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"revoked_at": {
"name": "revoked_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"catalog_invite_catalog": {
"name": "catalog_invite_catalog",
"columns": [
{
"expression": "catalog_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"catalog_invite_catalog_id_catalog_id_fk": {
"name": "catalog_invite_catalog_id_catalog_id_fk",
"tableFrom": "catalog_invite",
"tableTo": "catalog",
"columnsFrom": [
"catalog_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"catalog_invite_created_by_user_id_fk": {
"name": "catalog_invite_created_by_user_id_fk",
"tableFrom": "catalog_invite",
"tableTo": "user",
"columnsFrom": [
"created_by"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.catalog_member": {
"name": "catalog_member",
"schema": "",
"columns": {
"catalog_id": {
"name": "catalog_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": true
},
"invite": {
"name": "invite",
"type": "text",
"primaryKey": false,
"notNull": false
},
"decided_by": {
"name": "decided_by",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"catalog_member_user": {
"name": "catalog_member_user",
"columns": [
{
"expression": "user_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"catalog_member_catalog_id_catalog_id_fk": {
"name": "catalog_member_catalog_id_catalog_id_fk",
"tableFrom": "catalog_member",
"tableTo": "catalog",
"columnsFrom": [
"catalog_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"catalog_member_user_id_user_id_fk": {
"name": "catalog_member_user_id_user_id_fk",
"tableFrom": "catalog_member",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"catalog_member_decided_by_user_id_fk": {
"name": "catalog_member_decided_by_user_id_fk",
"tableFrom": "catalog_member",
"tableTo": "user",
"columnsFrom": [
"decided_by"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"catalog_member_catalog_id_user_id_pk": {
"name": "catalog_member_catalog_id_user_id_pk",
"columns": [
"catalog_id",
"user_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.device_code": {
"name": "device_code",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"device_code": {
"name": "device_code",
"type": "text",
"primaryKey": false,
"notNull": true
},
"user_code": {
"name": "user_code",
"type": "text",
"primaryKey": false,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": false
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": true
},
"last_polled_at": {
"name": "last_polled_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"polling_interval": {
"name": "polling_interval",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"client_id": {
"name": "client_id",
"type": "text",
"primaryKey": false,
"notNull": false
},
"scope": {
"name": "scope",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"device_code_user_id_user_id_fk": {
"name": "device_code_user_id_user_id_fk",
"tableFrom": "device_code",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.hosted_room": {
"name": "hosted_room",
"schema": "",
"columns": {
"n": {
"name": "n",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"owner_id": {
"name": "owner_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"owner_imvu_id": {
"name": "owner_imvu_id",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"room_pid": {
"name": "room_pid",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"rating": {
"name": "rating",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'general'"
},
"max_users": {
"name": "max_users",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 10
},
"scene": {
"name": "scene",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
},
"scene_hash": {
"name": "scene_hash",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"closed": {
"name": "closed",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"privacy": {
"name": "privacy",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'public'"
},
"moderators": {
"name": "moderators",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
},
"image_hash": {
"name": "image_hash",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"hosted_room_owner": {
"name": "hosted_room_owner",
"columns": [
{
"expression": "owner_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"hosted_room_created": {
"name": "hosted_room_created",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"hosted_room_owner_id_user_id_fk": {
"name": "hosted_room_owner_id_user_id_fk",
"tableFrom": "hosted_room",
"tableTo": "user",
"columnsFrom": [
"owner_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.hosted_room_ban": {
"name": "hosted_room_ban",
"schema": "",
"columns": {
"n": {
"name": "n",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"imvu_id": {
"name": "imvu_id",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"by_imvu_id": {
"name": "by_imvu_id",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"until": {
"name": "until",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"hosted_room_ban_n_hosted_room_n_fk": {
"name": "hosted_room_ban_n_hosted_room_n_fk",
"tableFrom": "hosted_room_ban",
"tableTo": "hosted_room",
"columnsFrom": [
"n"
],
"columnsTo": [
"n"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"hosted_room_ban_n_imvu_id_pk": {
"name": "hosted_room_ban_n_imvu_id_pk",
"columns": [
"n",
"imvu_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.hosted_room_favorite": {
"name": "hosted_room_favorite",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"n": {
"name": "n",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"hosted_room_favorite_user_id_user_id_fk": {
"name": "hosted_room_favorite_user_id_user_id_fk",
"tableFrom": "hosted_room_favorite",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"hosted_room_favorite_n_hosted_room_n_fk": {
"name": "hosted_room_favorite_n_hosted_room_n_fk",
"tableFrom": "hosted_room_favorite",
"tableTo": "hosted_room",
"columnsFrom": [
"n"
],
"columnsTo": [
"n"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"hosted_room_favorite_user_id_n_pk": {
"name": "hosted_room_favorite_user_id_n_pk",
"columns": [
"user_id",
"n"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.hosted_room_image": {
"name": "hosted_room_image",
"schema": "",
"columns": {
"n": {
"name": "n",
"type": "integer",
"primaryKey": true,
"notNull": true
},
"content_type": {
"name": "content_type",
"type": "text",
"primaryKey": false,
"notNull": true
},
"data": {
"name": "data",
"type": "bytea",
"primaryKey": false,
"notNull": true
},
"hash": {
"name": "hash",
"type": "text",
"primaryKey": false,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"hosted_room_image_n_hosted_room_n_fk": {
"name": "hosted_room_image_n_hosted_room_n_fk",
"tableFrom": "hosted_room_image",
"tableTo": "hosted_room",
"columnsFrom": [
"n"
],
"columnsTo": [
"n"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.hosted_room_rating": {
"name": "hosted_room_rating",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"n": {
"name": "n",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"score": {
"name": "score",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"hosted_room_rating_room": {
"name": "hosted_room_rating_room",
"columns": [
{
"expression": "n",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"hosted_room_rating_user_id_user_id_fk": {
"name": "hosted_room_rating_user_id_user_id_fk",
"tableFrom": "hosted_room_rating",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"hosted_room_rating_n_hosted_room_n_fk": {
"name": "hosted_room_rating_n_hosted_room_n_fk",
"tableFrom": "hosted_room_rating",
"tableTo": "hosted_room",
"columnsFrom": [
"n"
],
"columnsTo": [
"n"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"hosted_room_rating_user_id_n_pk": {
"name": "hosted_room_rating_user_id_n_pk",
"columns": [
"user_id",
"n"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.hosted_room_visit": {
"name": "hosted_room_visit",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"n": {
"name": "n",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"imvu_id": {
"name": "imvu_id",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"at": {
"name": "at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"hosted_room_visit_at": {
"name": "hosted_room_visit_at",
"columns": [
{
"expression": "user_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"hosted_room_visit_user_id_user_id_fk": {
"name": "hosted_room_visit_user_id_user_id_fk",
"tableFrom": "hosted_room_visit",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"hosted_room_visit_n_hosted_room_n_fk": {
"name": "hosted_room_visit_n_hosted_room_n_fk",
"tableFrom": "hosted_room_visit",
"tableTo": "hosted_room",
"columnsFrom": [
"n"
],
"columnsTo": [
"n"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"hosted_room_visit_user_id_n_pk": {
"name": "hosted_room_visit_user_id_n_pk",
"columns": [
"user_id",
"n"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.hosting": {
"name": "hosting",
"schema": "",
"columns": {
"catalog_id": {
"name": "catalog_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"product_id": {
"name": "product_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"number": {
"name": "number",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"hosting_product": {
"name": "hosting_product",
"columns": [
{
"expression": "product_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"hosting_catalog_id_catalog_id_fk": {
"name": "hosting_catalog_id_catalog_id_fk",
"tableFrom": "hosting",
"tableTo": "catalog",
"columnsFrom": [
"catalog_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"hosting_catalog_id_product_id_number_pk": {
"name": "hosting_catalog_id_product_id_number_pk",
"columns": [
"catalog_id",
"product_id",
"number"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.hub_setting": {
"name": "hub_setting",
"schema": "",
"columns": {
"key": {
"name": "key",
"type": "text",
"primaryKey": true,
"notNull": true
},
"value": {
"name": "value",
"type": "text",
"primaryKey": false,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.imvu_link": {
"name": "imvu_link",
"schema": "",
"columns": {
"imvu_id": {
"name": "imvu_id",
"type": "bigint",
"primaryKey": true,
"notNull": true
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"pairwise_id": {
"name": "pairwise_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"username": {
"name": "username",
"type": "text",
"primaryKey": false,
"notNull": true
},
"linked_at": {
"name": "linked_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"show_badge": {
"name": "show_badge",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"show_presence": {
"name": "show_presence",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"list_rooms": {
"name": "list_rooms",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
}
},
"indexes": {
"imvu_link_user": {
"name": "imvu_link_user",
"columns": [
{
"expression": "user_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"imvu_link_user_id_user_id_fk": {
"name": "imvu_link_user_id_user_id_fk",
"tableFrom": "imvu_link",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"imvu_link_pairwise_id_unique": {
"name": "imvu_link_pairwise_id_unique",
"nullsNotDistinct": false,
"columns": [
"pairwise_id"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.jwks": {
"name": "jwks",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"public_key": {
"name": "public_key",
"type": "text",
"primaryKey": false,
"notNull": true
},
"private_key": {
"name": "private_key",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"alg": {
"name": "alg",
"type": "text",
"primaryKey": false,
"notNull": false
},
"crv": {
"name": "crv",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.library": {
"name": "library",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"product_id": {
"name": "product_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"stay_on": {
"name": "stay_on",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"added_at": {
"name": "added_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"library_user_id_user_id_fk": {
"name": "library_user_id_user_id_fk",
"tableFrom": "library",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"library_product_id_product_id_fk": {
"name": "library_product_id_product_id_fk",
"tableFrom": "library",
"tableTo": "product",
"columnsFrom": [
"product_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"library_user_id_product_id_pk": {
"name": "library_user_id_product_id_pk",
"columns": [
"user_id",
"product_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.link_challenge": {
"name": "link_challenge",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"imvu_id": {
"name": "imvu_id",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"username": {
"name": "username",
"type": "text",
"primaryKey": false,
"notNull": true
},
"code": {
"name": "code",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"link_challenge_user_id_user_id_fk": {
"name": "link_challenge_user_id_user_id_fk",
"tableFrom": "link_challenge",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"link_challenge_user_id_imvu_id_pk": {
"name": "link_challenge_user_id_imvu_id_pk",
"columns": [
"user_id",
"imvu_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.product": {
"name": "product",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"creator_id": {
"name": "creator_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"rating": {
"name": "rating",
"type": "text",
"primaryKey": false,
"notNull": true
},
"latest": {
"name": "latest",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"status": {
"name": "status",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'published'"
},
"published_at": {
"name": "published_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"listed": {
"name": "listed",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
},
"tags": {
"name": "tags",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
},
"category": {
"name": "category",
"type": "jsonb",
"primaryKey": false,
"notNull": false
},
"locked": {
"name": "locked",
"type": "jsonb",
"primaryKey": false,
"notNull": true,
"default": "'[]'::jsonb"
},
"deleted_at": {
"name": "deleted_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"removed_at": {
"name": "removed_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"removed_reason": {
"name": "removed_reason",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"product_creator": {
"name": "product_creator",
"columns": [
{
"expression": "creator_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"product_created": {
"name": "product_created",
"columns": [
{
"expression": "created_at",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
},
"product_tags": {
"name": "product_tags",
"columns": [
{
"expression": "tags",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "gin",
"with": {}
}
},
"foreignKeys": {
"product_creator_id_user_id_fk": {
"name": "product_creator_id_user_id_fk",
"tableFrom": "product",
"tableTo": "user",
"columnsFrom": [
"creator_id"
],
"columnsTo": [
"id"
],
"onDelete": "restrict",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.product_info_change": {
"name": "product_info_change",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "serial",
"primaryKey": true,
"notNull": true
},
"product_id": {
"name": "product_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"by_id": {
"name": "by_id",
"type": "text",
"primaryKey": false,
"notNull": false
},
"kind": {
"name": "kind",
"type": "text",
"primaryKey": false,
"notNull": true
},
"changes": {
"name": "changes",
"type": "jsonb",
"primaryKey": false,
"notNull": true
},
"reason": {
"name": "reason",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"revert_of": {
"name": "revert_of",
"type": "integer",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"product_info_change_product": {
"name": "product_info_change_product",
"columns": [
{
"expression": "product_id",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"product_info_change_product_id_product_id_fk": {
"name": "product_info_change_product_id_product_id_fk",
"tableFrom": "product_info_change",
"tableTo": "product",
"columnsFrom": [
"product_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"product_info_change_by_id_user_id_fk": {
"name": "product_info_change_by_id_user_id_fk",
"tableFrom": "product_info_change",
"tableTo": "user",
"columnsFrom": [
"by_id"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.product_revision": {
"name": "product_revision",
"schema": "",
"columns": {
"product_id": {
"name": "product_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"number": {
"name": "number",
"type": "integer",
"primaryKey": false,
"notNull": true
},
"files": {
"name": "files",
"type": "jsonb",
"primaryKey": false,
"notNull": true
},
"rating": {
"name": "rating",
"type": "text",
"primaryKey": false,
"notNull": true
},
"parent": {
"name": "parent",
"type": "bigint",
"primaryKey": false,
"notNull": true,
"default": 0
},
"parent_info": {
"name": "parent_info",
"type": "jsonb",
"primaryKey": false,
"notNull": false
},
"notes": {
"name": "notes",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"token": {
"name": "token",
"type": "text",
"primaryKey": false,
"notNull": true
},
"uploaded_by": {
"name": "uploaded_by",
"type": "text",
"primaryKey": false,
"notNull": false
},
"retracted": {
"name": "retracted",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {
"product_revision_product_id_product_id_fk": {
"name": "product_revision_product_id_product_id_fk",
"tableFrom": "product_revision",
"tableTo": "product",
"columnsFrom": [
"product_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"product_revision_uploaded_by_user_id_fk": {
"name": "product_revision_uploaded_by_user_id_fk",
"tableFrom": "product_revision",
"tableTo": "user",
"columnsFrom": [
"uploaded_by"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"product_revision_product_id_number_pk": {
"name": "product_revision_product_id_number_pk",
"columns": [
"product_id",
"number"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.role_assignment": {
"name": "role_assignment",
"schema": "",
"columns": {
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"role": {
"name": "role",
"type": "text",
"primaryKey": false,
"notNull": true
},
"scope_type": {
"name": "scope_type",
"type": "text",
"primaryKey": false,
"notNull": true
},
"scope_id": {
"name": "scope_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"granted_by": {
"name": "granted_by",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"role_assignment_scope": {
"name": "role_assignment_scope",
"columns": [
{
"expression": "scope_type",
"isExpression": false,
"asc": true,
"nulls": "last"
},
{
"expression": "scope_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"role_assignment_user_id_user_id_fk": {
"name": "role_assignment_user_id_user_id_fk",
"tableFrom": "role_assignment",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
},
"role_assignment_granted_by_user_id_fk": {
"name": "role_assignment_granted_by_user_id_fk",
"tableFrom": "role_assignment",
"tableTo": "user",
"columnsFrom": [
"granted_by"
],
"columnsTo": [
"id"
],
"onDelete": "set null",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {
"role_assignment_user_id_role_scope_type_scope_id_pk": {
"name": "role_assignment_user_id_role_scope_type_scope_id_pk",
"columns": [
"user_id",
"role",
"scope_type",
"scope_id"
]
}
},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.room": {
"name": "room",
"schema": "",
"columns": {
"instance_id": {
"name": "instance_id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"owner_imvu_id": {
"name": "owner_imvu_id",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"description": {
"name": "description",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"image_url": {
"name": "image_url",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"privacy": {
"name": "privacy",
"type": "text",
"primaryKey": false,
"notNull": true
},
"type": {
"name": "type",
"type": "text",
"primaryKey": false,
"notNull": true
},
"content_rating": {
"name": "content_rating",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "''"
},
"access_pass": {
"name": "access_pass",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"occupancy": {
"name": "occupancy",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"capacity": {
"name": "capacity",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 0
},
"expired": {
"name": "expired",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"checked_at": {
"name": "checked_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"seen_at": {
"name": "seen_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"room_owner": {
"name": "room_owner",
"columns": [
{
"expression": "owner_imvu_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.room_decoration": {
"name": "room_decoration",
"schema": "",
"columns": {
"instance_id": {
"name": "instance_id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"owner_imvu_id": {
"name": "owner_imvu_id",
"type": "bigint",
"primaryKey": false,
"notNull": true
},
"contents": {
"name": "contents",
"type": "jsonb",
"primaryKey": false,
"notNull": true
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"room_decoration_owner": {
"name": "room_decoration_owner",
"columns": [
{
"expression": "owner_imvu_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.session": {
"name": "session",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"token": {
"name": "token",
"type": "text",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"ip_address": {
"name": "ip_address",
"type": "text",
"primaryKey": false,
"notNull": false
},
"user_agent": {
"name": "user_agent",
"type": "text",
"primaryKey": false,
"notNull": false
},
"user_id": {
"name": "user_id",
"type": "text",
"primaryKey": false,
"notNull": true
},
"impersonated_by": {
"name": "impersonated_by",
"type": "text",
"primaryKey": false,
"notNull": false
}
},
"indexes": {
"session_user": {
"name": "session_user",
"columns": [
{
"expression": "user_id",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {
"session_user_id_user_id_fk": {
"name": "session_user_id_user_id_fk",
"tableFrom": "session",
"tableTo": "user",
"columnsFrom": [
"user_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"session_token_unique": {
"name": "session_token_unique",
"nullsNotDistinct": false,
"columns": [
"token"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.signing_key": {
"name": "signing_key",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"public_key": {
"name": "public_key",
"type": "jsonb",
"primaryKey": false,
"notNull": true
},
"private_key": {
"name": "private_key",
"type": "jsonb",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.user": {
"name": "user",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"name": {
"name": "name",
"type": "text",
"primaryKey": false,
"notNull": true
},
"email": {
"name": "email",
"type": "text",
"primaryKey": false,
"notNull": true
},
"email_verified": {
"name": "email_verified",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": false
},
"image": {
"name": "image",
"type": "text",
"primaryKey": false,
"notNull": false
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"username": {
"name": "username",
"type": "text",
"primaryKey": false,
"notNull": false
},
"display_username": {
"name": "display_username",
"type": "text",
"primaryKey": false,
"notNull": false
},
"role": {
"name": "role",
"type": "text",
"primaryKey": false,
"notNull": true,
"default": "'user'"
},
"banned": {
"name": "banned",
"type": "boolean",
"primaryKey": false,
"notNull": false,
"default": false
},
"ban_reason": {
"name": "ban_reason",
"type": "text",
"primaryKey": false,
"notNull": false
},
"ban_expires": {
"name": "ban_expires",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": false
},
"link_cap": {
"name": "link_cap",
"type": "integer",
"primaryKey": false,
"notNull": true,
"default": 10
},
"approved": {
"name": "approved",
"type": "boolean",
"primaryKey": false,
"notNull": true,
"default": true
}
},
"indexes": {
"user_username_lower": {
"name": "user_username_lower",
"columns": [
{
"expression": "lower(\"username\")",
"asc": true,
"isExpression": true,
"nulls": "last"
}
],
"isUnique": true,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {
"user_email_unique": {
"name": "user_email_unique",
"nullsNotDistinct": false,
"columns": [
"email"
]
},
"user_username_unique": {
"name": "user_username_unique",
"nullsNotDistinct": false,
"columns": [
"username"
]
}
},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
},
"public.verification": {
"name": "verification",
"schema": "",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true
},
"identifier": {
"name": "identifier",
"type": "text",
"primaryKey": false,
"notNull": true
},
"value": {
"name": "value",
"type": "text",
"primaryKey": false,
"notNull": true
},
"expires_at": {
"name": "expires_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true
},
"created_at": {
"name": "created_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
},
"updated_at": {
"name": "updated_at",
"type": "timestamp with time zone",
"primaryKey": false,
"notNull": true,
"default": "now()"
}
},
"indexes": {
"verification_identifier": {
"name": "verification_identifier",
"columns": [
{
"expression": "identifier",
"isExpression": false,
"asc": true,
"nulls": "last"
}
],
"isUnique": false,
"concurrently": false,
"method": "btree",
"with": {}
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"policies": {},
"checkConstraints": {},
"isRLSEnabled": false
}
},
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {},
"_meta": {
"columns": {},
"schemas": {},
"tables": {}
}
}