diff --git a/.dependency-cruiser.cjs b/.dependency-cruiser.cjs index 95aab688b..1fa2a245e 100644 --- a/.dependency-cruiser.cjs +++ b/.dependency-cruiser.cjs @@ -1,30 +1,6 @@ -const DOMAIN = [ - 'accounts', - 'antispam', - 'groups', - 'authorization', - 'forums', - 'threads', - 'posts', - 'profile-fields', - 'messages', - 'relations', - 'reputation', - 'signatures', - 'admin', - 'mail', - 'markdown', - 'moderation', - 'notifications', - 'settings', - 'subscriptions', - 'events', - 'tasks', - 'api', - 'install', - 'upgrade', - 'import', -].join('|') +const { domainPackages } = require('./scripts/domain-packages.cjs') + +const DOMAIN = domainPackages().join('|') module.exports = { forbidden: [ diff --git a/.env.example b/.env.example index 8bd8baec1..dbc836138 100644 --- a/.env.example +++ b/.env.example @@ -22,11 +22,11 @@ # postgres = Drizzle + postgres.js against DATABASE_URL. DATA_SOURCE=fixture -# For local development against a real database, `docker-compose.dev.yml` starts +# For local development against a real database, `docker/compose.dev.yml` starts # one on port 55432 with a **named** volume, so the board survives the container # being recreated: # -# docker compose -f docker-compose.dev.yml up -d +# docker compose -f docker/compose.dev.yml up -d # pnpm community migrate # # DATA_SOURCE=postgres @@ -36,7 +36,7 @@ DATA_SOURCE=fixture # !! READ THIS BEFORE SETTING DATABASE_URL !! # ───────────────────────────────────────────────────────────────────────────── # Your own Postgres, with a fixed number of processes in front of it, needs -# nothing special. That is what docker-compose.yml gives you and what +# nothing special. That is what docker/compose.yml gives you and what # docs/self-hosting.md walks through. # # Pointing at a MANAGED database instead? Use the TRANSACTION-MODE POOLER @@ -76,7 +76,7 @@ AUTH_SECRET= # cron caller presents it as "Authorization: Bearer ", or as an # "X-Tick-Secret" header. It is not read from the query string. TICK_SECRET= -# Only read by docker-compose.yml, which interpolates it into the database's +# Only read by docker/compose.yml, which interpolates it into the database's # own password. Hex rather than base64, deliberately: `/` or `+` in a password # breaks the postgres:// URL it is spliced into. # Generate with: openssl rand -hex 32 diff --git a/docs/architecture.md b/docs/architecture.md index f5f8e2c0c..fd02b33bd 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -111,10 +111,16 @@ The load-bearing rules, each a named `error` in The same config also enforces `no-circular` (import cycles are an error anywhere) and `no-deprecated-core`. -`runtime`, `db`, `drivers` — and `demo`, whose seed and reset run SQL and -migrations by nature — sit deliberately outside the protected domain list. -The question that decides which side of the line a package is on: does this -module *choose an implementation*? +The domain list itself is derived, not maintained: +[`scripts/domain-packages.cjs`](../scripts/domain-packages.cjs) reads +`packages/` and subtracts the named infrastructure packages — `core`, `db`, +`drivers`, `runtime`, `testkit`, `ui`, `plugin-kit`, `theme-kit`, +`create-meith`, and `demo`, whose seed and reset run SQL and migrations by +nature. Both dependency-cruiser and the textual guards +(`scripts/guards.mjs`) read that one list, so a new domain package is under +every rule from the moment its directory exists, rather than from the moment +somebody remembers to add it to a list. The question that decides which side +of the line a package is on: does this module *choose an implementation*? ### The floor: `@meith/core` diff --git a/docs/disaster-recovery.md b/docs/disaster-recovery.md index 8be9bc84c..25933f75d 100644 --- a/docs/disaster-recovery.md +++ b/docs/disaster-recovery.md @@ -85,7 +85,7 @@ comes up: ```sh docker compose up -d --no-start web -docker run --rm -v meith_uploads:/u -v "$PWD":/backup alpine \ +docker run --rm -v docker_uploads:/u -v "$PWD":/backup alpine \ tar xzf /backup/uploads-2026-08-20.tar.gz -C /u ``` diff --git a/docs/operating.md b/docs/operating.md index af945c43b..3ac169b4b 100644 --- a/docs/operating.md +++ b/docs/operating.md @@ -193,7 +193,7 @@ Nothing in the database changes: it stores keys, not URLs. [rclone](https://rclone.org): ```sh - docker run --rm -v meith_uploads:/u:ro -v "$PWD/rclone.conf":/config/rclone/rclone.conf \ + docker run --rm -v docker_uploads:/u:ro -v "$PWD/rclone.conf":/config/rclone/rclone.conf \ rclone/rclone copy /u remote:your-bucket ``` @@ -2339,7 +2339,7 @@ container rather than on the host: ```sh docker compose exec -T postgres pg_dump -U community community | gzip > board-$(date +%F).sql.gz -docker run --rm -v meith_uploads:/u -v "$PWD":/out alpine \ +docker run --rm -v docker_uploads:/u -v "$PWD":/out alpine \ tar czf /out/uploads-$(date +%F).tar.gz -C /u . ``` diff --git a/packages/db/migrations/0050_drop_forum_password_grants.sql b/packages/db/migrations/0050_drop_forum_password_grants.sql new file mode 100644 index 000000000..faa17fc2a --- /dev/null +++ b/packages/db/migrations/0050_drop_forum_password_grants.sql @@ -0,0 +1 @@ +DROP TABLE "forum_password_grants" CASCADE; \ No newline at end of file diff --git a/packages/db/migrations/meta/0050_snapshot.json b/packages/db/migrations/meta/0050_snapshot.json new file mode 100644 index 000000000..d57a8763b --- /dev/null +++ b/packages/db/migrations/meta/0050_snapshot.json @@ -0,0 +1,9126 @@ +{ + "id": "aa131dea-82e5-4a04-9255-b0814bee8d39", + "prevId": "f58eab6b-f122-4718-9579-b6c73eeed1a2", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.announcements": { + "name": "announcements", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "announcements_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "forum_id": { + "name": "forum_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body_format": { + "name": "body_format", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "author_user_id": { + "name": "author_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "author_username": { + "name": "author_username", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "starts_at": { + "name": "starts_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ends_at": { + "name": "ends_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "announcements_live_idx": { + "name": "announcements_live_idx", + "columns": [ + { + "expression": "starts_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"announcements\".\"enabled\"", + "concurrently": false, + "method": "btree", + "with": {} + }, + "announcements_forum_idx": { + "name": "announcements_forum_idx", + "columns": [ + { + "expression": "forum_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "announcements_forum_id_forums_id_fk": { + "name": "announcements_forum_id_forums_id_fk", + "tableFrom": "announcements", + "tableTo": "forums", + "columnsFrom": ["forum_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "announcements_author_user_id_users_id_fk": { + "name": "announcements_author_user_id_users_id_fk", + "tableFrom": "announcements", + "tableTo": "users", + "columnsFrom": ["author_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.attachment_orphans": { + "name": "attachment_orphans", + "schema": "", + "columns": { + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "attachment_orphans_age_idx": { + "name": "attachment_orphans_age_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.attachments": { + "name": "attachments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "attachments_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "post_id": { + "name": "post_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "forum_id": { + "name": "forum_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "uploader_user_id": { + "name": "uploader_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size_bytes": { + "name": "size_bytes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_key": { + "name": "source_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thumbnail_key": { + "name": "thumbnail_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "failure_reason": { + "name": "failure_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "download_count": { + "name": "download_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "ready_at": { + "name": "ready_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "attachments_post_idx": { + "name": "attachments_post_idx", + "columns": [ + { + "expression": "post_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "attachments_uploader_idx": { + "name": "attachments_uploader_idx", + "columns": [ + { + "expression": "uploader_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "attachments_pending_idx": { + "name": "attachments_pending_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"attachments\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "attachments_storage_key_key": { + "name": "attachments_storage_key_key", + "columns": [ + { + "expression": "storage_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"attachments\".\"storage_key\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "attachments_source_key_key": { + "name": "attachments_source_key_key", + "columns": [ + { + "expression": "source_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"attachments\".\"source_key\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "attachments_post_id_posts_id_fk": { + "name": "attachments_post_id_posts_id_fk", + "tableFrom": "attachments", + "tableTo": "posts", + "columnsFrom": ["post_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "attachments_forum_id_forums_id_fk": { + "name": "attachments_forum_id_forums_id_fk", + "tableFrom": "attachments", + "tableTo": "forums", + "columnsFrom": ["forum_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "attachments_uploader_user_id_users_id_fk": { + "name": "attachments_uploader_user_id_users_id_fk", + "tableFrom": "attachments", + "tableTo": "users", + "columnsFrom": ["uploader_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.custom_directives": { + "name": "custom_directives", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "custom_directives_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "block": { + "name": "block", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "custom_directives_name_key": { + "name": "custom_directives_name_key", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.digest_runs": { + "name": "digest_runs", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "cadence": { + "name": "cadence", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_sent_at": { + "name": "last_sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "digest_runs_user_id_users_id_fk": { + "name": "digest_runs_user_id_users_id_fk", + "tableFrom": "digest_runs", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "digest_runs_pkey": { + "name": "digest_runs_pkey", + "columns": ["user_id", "cadence"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.post_revisions": { + "name": "post_revisions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "post_revisions_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "post_id": { + "name": "post_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "revision": { + "name": "revision", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "edited_by_user_id": { + "name": "edited_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "edit_reason": { + "name": "edit_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "post_revisions_post_revision_key": { + "name": "post_revisions_post_revision_key", + "columns": [ + { + "expression": "post_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "revision", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "post_revisions_post_id_posts_id_fk": { + "name": "post_revisions_post_id_posts_id_fk", + "tableFrom": "post_revisions", + "tableTo": "posts", + "columnsFrom": ["post_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "post_revisions_edited_by_user_id_users_id_fk": { + "name": "post_revisions_edited_by_user_id_users_id_fk", + "tableFrom": "post_revisions", + "tableTo": "users", + "columnsFrom": ["edited_by_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.posts": { + "name": "posts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "posts_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "thread_id": { + "name": "thread_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "forum_id": { + "name": "forum_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "author_user_id": { + "name": "author_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "author_username": { + "name": "author_username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body_format": { + "name": "body_format", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "message_html": { + "name": "message_html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "render_version": { + "name": "render_version", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "vocab_version": { + "name": "vocab_version", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "visibility": { + "name": "visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'visible'" + }, + "is_first_post": { + "name": "is_first_post", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "ip_prefix": { + "name": "ip_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "edited_at": { + "name": "edited_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "edited_by_user_id": { + "name": "edited_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "edit_reason": { + "name": "edit_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "revision_count": { + "name": "revision_count", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "search_vector": { + "name": "search_vector", + "type": "tsvector", + "primaryKey": false, + "notNull": false + }, + "search_version": { + "name": "search_version", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "legacy_mybb_pid": { + "name": "legacy_mybb_pid", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "posts_thread_visible_idx": { + "name": "posts_thread_visible_idx", + "columns": [ + { + "expression": "thread_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"posts\".\"visibility\" = 'visible'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "posts_thread_all_idx": { + "name": "posts_thread_all_idx", + "columns": [ + { + "expression": "thread_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "posts_author_idx": { + "name": "posts_author_idx", + "columns": [ + { + "expression": "author_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "posts_render_version_idx": { + "name": "posts_render_version_idx", + "columns": [ + { + "expression": "render_version", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "posts_vocab_version_idx": { + "name": "posts_vocab_version_idx", + "columns": [ + { + "expression": "vocab_version", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "posts_search_version_idx": { + "name": "posts_search_version_idx", + "columns": [ + { + "expression": "search_version", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "posts_forum_visibility_idx": { + "name": "posts_forum_visibility_idx", + "columns": [ + { + "expression": "forum_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"posts\".\"visibility\" <> 'visible'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "posts_legacy_mybb_pid_key": { + "name": "posts_legacy_mybb_pid_key", + "columns": [ + { + "expression": "legacy_mybb_pid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"posts\".\"legacy_mybb_pid\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "posts_search_vector_idx": { + "name": "posts_search_vector_idx", + "columns": [ + { + "expression": "search_vector", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + } + }, + "foreignKeys": { + "posts_thread_id_threads_id_fk": { + "name": "posts_thread_id_threads_id_fk", + "tableFrom": "posts", + "tableTo": "threads", + "columnsFrom": ["thread_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "posts_forum_id_forums_id_fk": { + "name": "posts_forum_id_forums_id_fk", + "tableFrom": "posts", + "tableTo": "forums", + "columnsFrom": ["forum_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "posts_author_user_id_users_id_fk": { + "name": "posts_author_user_id_users_id_fk", + "tableFrom": "posts", + "tableTo": "users", + "columnsFrom": ["author_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "posts_edited_by_user_id_users_id_fk": { + "name": "posts_edited_by_user_id_users_id_fk", + "tableFrom": "posts", + "tableTo": "users", + "columnsFrom": ["edited_by_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.report_events": { + "name": "report_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "report_events_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "report_id": { + "name": "report_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "actor_user_id": { + "name": "actor_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "report_events_report_idx": { + "name": "report_events_report_idx", + "columns": [ + { + "expression": "report_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "report_events_report_id_reports_id_fk": { + "name": "report_events_report_id_reports_id_fk", + "tableFrom": "report_events", + "tableTo": "reports", + "columnsFrom": ["report_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "report_events_actor_user_id_users_id_fk": { + "name": "report_events_actor_user_id_users_id_fk", + "tableFrom": "report_events", + "tableTo": "users", + "columnsFrom": ["actor_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reports": { + "name": "reports", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "reports_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "target_kind": { + "name": "target_kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "forum_id": { + "name": "forum_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "thread_id": { + "name": "thread_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "target_label": { + "name": "target_label", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "reporter_user_id": { + "name": "reporter_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'open'" + }, + "assigned_to_user_id": { + "name": "assigned_to_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "resolved_by_user_id": { + "name": "resolved_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "resolved_at": { + "name": "resolved_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()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "reports_open_idx": { + "name": "reports_open_idx", + "columns": [ + { + "expression": "forum_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"reports\".\"status\" = 'open'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "reports_open_global_idx": { + "name": "reports_open_global_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"reports\".\"status\" = 'open' and \"reports\".\"forum_id\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "reports_one_open_per_reporter_key": { + "name": "reports_one_open_per_reporter_key", + "columns": [ + { + "expression": "reporter_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"reports\".\"status\" = 'open' and \"reports\".\"reporter_user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "reports_forum_id_forums_id_fk": { + "name": "reports_forum_id_forums_id_fk", + "tableFrom": "reports", + "tableTo": "forums", + "columnsFrom": ["forum_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "reports_thread_id_threads_id_fk": { + "name": "reports_thread_id_threads_id_fk", + "tableFrom": "reports", + "tableTo": "threads", + "columnsFrom": ["thread_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "reports_reporter_user_id_users_id_fk": { + "name": "reports_reporter_user_id_users_id_fk", + "tableFrom": "reports", + "tableTo": "users", + "columnsFrom": ["reporter_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "reports_assigned_to_user_id_users_id_fk": { + "name": "reports_assigned_to_user_id_users_id_fk", + "tableFrom": "reports", + "tableTo": "users", + "columnsFrom": ["assigned_to_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "reports_resolved_by_user_id_users_id_fk": { + "name": "reports_resolved_by_user_id_users_id_fk", + "tableFrom": "reports", + "tableTo": "users", + "columnsFrom": ["resolved_by_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reputation": { + "name": "reputation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "reputation_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "given_by_user_id": { + "name": "given_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "post_id": { + "name": "post_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "points": { + "name": "points", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "comment": { + "name": "comment", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "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": { + "reputation_profile_unique": { + "name": "reputation_profile_unique", + "columns": [ + { + "expression": "given_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"reputation\".\"post_id\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "reputation_post_unique": { + "name": "reputation_post_unique", + "columns": [ + { + "expression": "given_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "post_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"reputation\".\"post_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "reputation_user_idx": { + "name": "reputation_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reputation_given_idx": { + "name": "reputation_given_idx", + "columns": [ + { + "expression": "given_by_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "reputation_user_id_users_id_fk": { + "name": "reputation_user_id_users_id_fk", + "tableFrom": "reputation", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "reputation_given_by_user_id_users_id_fk": { + "name": "reputation_given_by_user_id_users_id_fk", + "tableFrom": "reputation", + "tableTo": "users", + "columnsFrom": ["given_by_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "reputation_post_id_posts_id_fk": { + "name": "reputation_post_id_posts_id_fk", + "tableFrom": "reputation", + "tableTo": "posts", + "columnsFrom": ["post_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.smilies": { + "name": "smilies", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "smilies_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "src": { + "name": "src", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "alt": { + "name": "alt", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "smilies_code_key": { + "name": "smilies_code_key", + "columns": [ + { + "expression": "code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.thread_prefixes": { + "name": "thread_prefixes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "thread_prefixes_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_order": { + "name": "display_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "forum_path_prefix": { + "name": "forum_path_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "thread_prefixes_order_idx": { + "name": "thread_prefixes_order_idx", + "columns": [ + { + "expression": "display_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.thread_subscriptions": { + "name": "thread_subscriptions", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "thread_id": { + "name": "thread_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'instant'" + }, + "last_notified_post_id": { + "name": "last_notified_post_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "thread_subscriptions_pkey": { + "name": "thread_subscriptions_pkey", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "thread_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "thread_subscriptions_thread_idx": { + "name": "thread_subscriptions_thread_idx", + "columns": [ + { + "expression": "thread_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "thread_subscriptions_user_idx": { + "name": "thread_subscriptions_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "thread_subscriptions_mode_idx": { + "name": "thread_subscriptions_mode_idx", + "columns": [ + { + "expression": "mode", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "thread_subscriptions_user_id_users_id_fk": { + "name": "thread_subscriptions_user_id_users_id_fk", + "tableFrom": "thread_subscriptions", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "thread_subscriptions_thread_id_threads_id_fk": { + "name": "thread_subscriptions_thread_id_threads_id_fk", + "tableFrom": "thread_subscriptions", + "tableTo": "threads", + "columnsFrom": ["thread_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.thread_view_buffer": { + "name": "thread_view_buffer", + "schema": "", + "columns": { + "thread_id": { + "name": "thread_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "pending": { + "name": "pending", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "thread_view_buffer_updated_idx": { + "name": "thread_view_buffer_updated_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "thread_view_buffer_thread_id_threads_id_fk": { + "name": "thread_view_buffer_thread_id_threads_id_fk", + "tableFrom": "thread_view_buffer", + "tableTo": "threads", + "columnsFrom": ["thread_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.threads": { + "name": "threads", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "threads_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "forum_id": { + "name": "forum_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "prefix_id": { + "name": "prefix_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "author_user_id": { + "name": "author_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "author_username": { + "name": "author_username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "visibility": { + "name": "visibility", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'visible'" + }, + "is_sticky": { + "name": "is_sticky", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_locked": { + "name": "is_locked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "first_post_id": { + "name": "first_post_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reply_count": { + "name": "reply_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "view_count": { + "name": "view_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "rating_total": { + "name": "rating_total", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "rating_count": { + "name": "rating_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_post_id": { + "name": "last_post_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_post_user_id": { + "name": "last_post_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_post_username": { + "name": "last_post_username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_post_at": { + "name": "last_post_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "moved_to_thread_id": { + "name": "moved_to_thread_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "legacy_mybb_tid": { + "name": "legacy_mybb_tid", + "type": "integer", + "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": { + "threads_forum_listing_idx": { + "name": "threads_forum_listing_idx", + "columns": [ + { + "expression": "forum_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_sticky", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "last_post_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"threads\".\"visibility\" = 'visible'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "threads_forum_listing_all_idx": { + "name": "threads_forum_listing_all_idx", + "columns": [ + { + "expression": "forum_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "is_sticky", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "last_post_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "threads_author_idx": { + "name": "threads_author_idx", + "columns": [ + { + "expression": "author_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "threads_legacy_mybb_tid_key": { + "name": "threads_legacy_mybb_tid_key", + "columns": [ + { + "expression": "legacy_mybb_tid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"threads\".\"legacy_mybb_tid\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "threads_forum_id_forums_id_fk": { + "name": "threads_forum_id_forums_id_fk", + "tableFrom": "threads", + "tableTo": "forums", + "columnsFrom": ["forum_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "threads_prefix_id_thread_prefixes_id_fk": { + "name": "threads_prefix_id_thread_prefixes_id_fk", + "tableFrom": "threads", + "tableTo": "thread_prefixes", + "columnsFrom": ["prefix_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "threads_author_user_id_users_id_fk": { + "name": "threads_author_user_id_users_id_fk", + "tableFrom": "threads", + "tableTo": "users", + "columnsFrom": ["author_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.threads_read": { + "name": "threads_read", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "thread_id": { + "name": "thread_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "last_read_post_id": { + "name": "last_read_post_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "threads_read_pkey": { + "name": "threads_read_pkey", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "thread_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "threads_read_read_at_idx": { + "name": "threads_read_read_at_idx", + "columns": [ + { + "expression": "read_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "threads_read_user_id_users_id_fk": { + "name": "threads_read_user_id_users_id_fk", + "tableFrom": "threads_read", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "threads_read_thread_id_threads_id_fk": { + "name": "threads_read_thread_id_threads_id_fk", + "tableFrom": "threads_read", + "tableTo": "threads", + "columnsFrom": ["thread_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.word_filters": { + "name": "word_filters", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "word_filters_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "pattern": { + "name": "pattern", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "replacement": { + "name": "replacement", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "whole_word": { + "name": "whole_word", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": 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.admin_sessions": { + "name": "admin_sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "admin_sessions_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "ip_prefix": { + "name": "ip_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "authenticated_at": { + "name": "authenticated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_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": true + }, + "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": { + "admin_sessions_token_hash_key": { + "name": "admin_sessions_token_hash_key", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "admin_sessions_user_idx": { + "name": "admin_sessions_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "admin_sessions_expiry_idx": { + "name": "admin_sessions_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "admin_sessions_user_id_users_id_fk": { + "name": "admin_sessions_user_id_users_id_fk", + "tableFrom": "admin_sessions", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_events": { + "name": "auth_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "auth_events_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "ip_prefix": { + "name": "ip_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "detail": { + "name": "detail", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "at": { + "name": "at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_events_user_idx": { + "name": "auth_events_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auth_events_recent_idx": { + "name": "auth_events_recent_idx", + "columns": [ + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "auth_events_kind_idx": { + "name": "auth_events_kind_idx", + "columns": [ + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "auth_events_user_id_users_id_fk": { + "name": "auth_events_user_id_users_id_fk", + "tableFrom": "auth_events", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ban_filters": { + "name": "ban_filters", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "ban_filters_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pattern": { + "name": "pattern", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "ban_filters_type_idx": { + "name": "ban_filters_type_idx", + "columns": [ + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "ban_filters_type_pattern_key": { + "name": "ban_filters_type_pattern_key", + "columns": [ + { + "expression": "type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "pattern", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "ban_filters_created_by_user_id_users_id_fk": { + "name": "ban_filters_created_by_user_id_users_id_fk", + "tableFrom": "ban_filters", + "tableTo": "users", + "columnsFrom": ["created_by_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.bans": { + "name": "bans", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "bans_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "banned_by_user_id": { + "name": "banned_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "public_reason": { + "name": "public_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previous_primary_group_id": { + "name": "previous_primary_group_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "lifted_at": { + "name": "lifted_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": { + "bans_active_user_key": { + "name": "bans_active_user_key", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"bans\".\"lifted_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "bans_expires_idx": { + "name": "bans_expires_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"bans\".\"lifted_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "bans_user_id_users_id_fk": { + "name": "bans_user_id_users_id_fk", + "tableFrom": "bans", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "bans_banned_by_user_id_users_id_fk": { + "name": "bans_banned_by_user_id_users_id_fk", + "tableFrom": "bans", + "tableTo": "users", + "columnsFrom": ["banned_by_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "bans_previous_primary_group_id_usergroups_id_fk": { + "name": "bans_previous_primary_group_id_usergroups_id_fk", + "tableFrom": "bans", + "tableTo": "usergroups", + "columnsFrom": ["previous_primary_group_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.credential_tokens": { + "name": "credential_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "credential_tokens_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "purpose": { + "name": "purpose", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "consumed_at": { + "name": "consumed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "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()" + } + }, + "indexes": { + "credential_tokens_hash_key": { + "name": "credential_tokens_hash_key", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "credential_tokens_user_purpose_idx": { + "name": "credential_tokens_user_purpose_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "purpose", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "credential_tokens_expires_idx": { + "name": "credential_tokens_expires_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "credential_tokens_user_id_users_id_fk": { + "name": "credential_tokens_user_id_users_id_fk", + "tableFrom": "credential_tokens", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.group_promotions": { + "name": "group_promotions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "group_promotions_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "display_order": { + "name": "display_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "min_post_count": { + "name": "min_post_count", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "min_reputation": { + "name": "min_reputation", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "min_days_registered": { + "name": "min_days_registered", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "from_primary_group_id": { + "name": "from_primary_group_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "to_primary_group_id": { + "name": "to_primary_group_id", + "type": "integer", + "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": { + "group_promotions_order_idx": { + "name": "group_promotions_order_idx", + "columns": [ + { + "expression": "display_order", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "group_promotions_from_primary_group_id_usergroups_id_fk": { + "name": "group_promotions_from_primary_group_id_usergroups_id_fk", + "tableFrom": "group_promotions", + "tableTo": "usergroups", + "columnsFrom": ["from_primary_group_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "group_promotions_to_primary_group_id_usergroups_id_fk": { + "name": "group_promotions_to_primary_group_id_usergroups_id_fk", + "tableFrom": "group_promotions", + "tableTo": "usergroups", + "columnsFrom": ["to_primary_group_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.login_attempts": { + "name": "login_attempts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "login_attempts_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "bucket": { + "name": "bucket", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "succeeded": { + "name": "succeeded", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "login_attempts_bucket_idx": { + "name": "login_attempts_bucket_idx", + "columns": [ + { + "expression": "bucket", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notification_preferences": { + "name": "notification_preferences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "push": { + "name": "push", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "notification_preferences_user_id_users_id_fk": { + "name": "notification_preferences_user_id_users_id_fk", + "tableFrom": "notification_preferences", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "notification_preferences_pkey": { + "name": "notification_preferences_pkey", + "columns": ["user_id", "kind"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notifications": { + "name": "notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "notifications_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "href": { + "name": "href", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "occurrences": { + "name": "occurrences", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "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()" + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "email_sent_at": { + "name": "email_sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "push_sent_at": { + "name": "push_sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "notifications_user_idx": { + "name": "notifications_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_unread_idx": { + "name": "notifications_unread_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"notifications\".\"read_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "notifications_dedupe_idx": { + "name": "notifications_dedupe_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "dedupe_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"notifications\".\"read_at\" is null and \"notifications\".\"dedupe_key\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notifications_user_id_users_id_fk": { + "name": "notifications_user_id_users_id_fk", + "tableFrom": "notifications", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.passkeys": { + "name": "passkeys", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "passkeys_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "credential_id": { + "name": "credential_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sign_count": { + "name": "sign_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "transports": { + "name": "transports", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "passkeys_credential_id_key": { + "name": "passkeys_credential_id_key", + "columns": [ + { + "expression": "credential_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "passkeys_user_idx": { + "name": "passkeys_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "passkeys_user_id_users_id_fk": { + "name": "passkeys_user_id_users_id_fk", + "tableFrom": "passkeys", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.profile_field_groups": { + "name": "profile_field_groups", + "schema": "", + "columns": { + "field_id": { + "name": "field_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "can_view": { + "name": "can_view", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_edit": { + "name": "can_edit", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "profile_field_groups_field_id_profile_fields_id_fk": { + "name": "profile_field_groups_field_id_profile_fields_id_fk", + "tableFrom": "profile_field_groups", + "tableTo": "profile_fields", + "columnsFrom": ["field_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "profile_field_groups_group_id_usergroups_id_fk": { + "name": "profile_field_groups_group_id_usergroups_id_fk", + "tableFrom": "profile_field_groups", + "tableTo": "usergroups", + "columnsFrom": ["group_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "profile_field_groups_pkey": { + "name": "profile_field_groups_pkey", + "columns": ["field_id", "group_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.profile_field_values": { + "name": "profile_field_values", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "field_id": { + "name": "field_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "profile_field_values_user_idx": { + "name": "profile_field_values_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "profile_field_values_user_id_users_id_fk": { + "name": "profile_field_values_user_id_users_id_fk", + "tableFrom": "profile_field_values", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "profile_field_values_field_id_profile_fields_id_fk": { + "name": "profile_field_values_field_id_profile_fields_id_fk", + "tableFrom": "profile_field_values", + "tableTo": "profile_fields", + "columnsFrom": ["field_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "profile_field_values_pkey": { + "name": "profile_field_values_pkey", + "columns": ["user_id", "field_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.profile_fields": { + "name": "profile_fields", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "profile_fields_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'text'" + }, + "options": { + "name": "options", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "max_length": { + "name": "max_length", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "display_order": { + "name": "display_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "required_at_registration": { + "name": "required_at_registration", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "default_visible": { + "name": "default_visible", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "default_editable": { + "name": "default_editable", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "show_in_postbit": { + "name": "show_in_postbit", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": 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": { + "profile_fields_key_unique": { + "name": "profile_fields_key_unique", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "profile_fields_order_idx": { + "name": "profile_fields_order_idx", + "columns": [ + { + "expression": "display_order", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.push_subscriptions": { + "name": "push_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "push_subscriptions_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "endpoint": { + "name": "endpoint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "p256dh": { + "name": "p256dh", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "auth": { + "name": "auth", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "push_subscriptions_endpoint_key": { + "name": "push_subscriptions_endpoint_key", + "columns": [ + { + "expression": "endpoint", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_subscriptions_user_idx": { + "name": "push_subscriptions_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "push_subscriptions_user_id_users_id_fk": { + "name": "push_subscriptions_user_id_users_id_fk", + "tableFrom": "push_subscriptions", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.recovery_codes": { + "name": "recovery_codes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "recovery_codes_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "code_hash": { + "name": "code_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "used_at": { + "name": "used_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": { + "recovery_codes_user_hash_key": { + "name": "recovery_codes_user_hash_key", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "code_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "recovery_codes_unused_idx": { + "name": "recovery_codes_unused_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"recovery_codes\".\"used_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "recovery_codes_user_id_users_id_fk": { + "name": "recovery_codes_user_id_users_id_fk", + "tableFrom": "recovery_codes", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.remember_tokens": { + "name": "remember_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "remember_tokens_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "family_id": { + "name": "family_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "used_at": { + "name": "used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "revoked_reason": { + "name": "revoked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "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()" + } + }, + "indexes": { + "remember_tokens_hash_key": { + "name": "remember_tokens_hash_key", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "remember_tokens_family_idx": { + "name": "remember_tokens_family_idx", + "columns": [ + { + "expression": "family_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "remember_tokens_user_idx": { + "name": "remember_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "remember_tokens_expires_idx": { + "name": "remember_tokens_expires_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "remember_tokens_user_id_users_id_fk": { + "name": "remember_tokens_user_id_users_id_fk", + "tableFrom": "remember_tokens", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sessions": { + "name": "sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "sessions_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "location_path": { + "name": "location_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "location_forum_id": { + "name": "location_forum_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "location_thread_id": { + "name": "location_thread_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "ip_prefix": { + "name": "ip_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "superseded_by_session_id": { + "name": "superseded_by_session_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_seen_at": { + "name": "last_seen_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": true + }, + "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": { + "sessions_token_hash_key": { + "name": "sessions_token_hash_key", + "columns": [ + { + "expression": "token_hash", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_last_seen_idx": { + "name": "sessions_last_seen_idx", + "columns": [ + { + "expression": "last_seen_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_user_idx": { + "name": "sessions_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sessions_expires_idx": { + "name": "sessions_expires_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sessions_user_id_users_id_fk": { + "name": "sessions_user_id_users_id_fk", + "tableFrom": "sessions", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_group_memberships": { + "name": "user_group_memberships", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "is_display_group": { + "name": "is_display_group", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "granted_by_user_id": { + "name": "granted_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "granted_at": { + "name": "granted_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 + }, + "granted_by_plugin": { + "name": "granted_by_plugin", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "grant_reason": { + "name": "grant_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previous_primary_group_id": { + "name": "previous_primary_group_id", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "user_group_memberships_pkey": { + "name": "user_group_memberships_pkey", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_group_memberships_user_idx": { + "name": "user_group_memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_group_memberships_group_idx": { + "name": "user_group_memberships_group_idx", + "columns": [ + { + "expression": "group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_group_memberships_expiry_idx": { + "name": "user_group_memberships_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"user_group_memberships\".\"expires_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_group_memberships_previous_primary_idx": { + "name": "user_group_memberships_previous_primary_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"user_group_memberships\".\"previous_primary_group_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_group_memberships_user_id_users_id_fk": { + "name": "user_group_memberships_user_id_users_id_fk", + "tableFrom": "user_group_memberships", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_group_memberships_group_id_usergroups_id_fk": { + "name": "user_group_memberships_group_id_usergroups_id_fk", + "tableFrom": "user_group_memberships", + "tableTo": "usergroups", + "columnsFrom": ["group_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_group_memberships_granted_by_user_id_users_id_fk": { + "name": "user_group_memberships_granted_by_user_id_users_id_fk", + "tableFrom": "user_group_memberships", + "tableTo": "users", + "columnsFrom": ["granted_by_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "user_group_memberships_previous_primary_group_id_usergroups_id_fk": { + "name": "user_group_memberships_previous_primary_group_id_usergroups_id_fk", + "tableFrom": "user_group_memberships", + "tableTo": "usergroups", + "columnsFrom": ["previous_primary_group_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_identities": { + "name": "user_identities", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "user_identities_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "linked_at": { + "name": "linked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "user_identities_provider_subject_key": { + "name": "user_identities_provider_subject_key", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "subject", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_identities_user_idx": { + "name": "user_identities_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_identities_user_id_users_id_fk": { + "name": "user_identities_user_id_users_id_fk", + "tableFrom": "user_identities", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_relations": { + "name": "user_relations", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "other_user_id": { + "name": "other_user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "user_relations_kind_idx": { + "name": "user_relations_kind_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "other_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "user_relations_reverse_idx": { + "name": "user_relations_reverse_idx", + "columns": [ + { + "expression": "other_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "user_relations_user_id_users_id_fk": { + "name": "user_relations_user_id_users_id_fk", + "tableFrom": "user_relations", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "user_relations_other_user_id_users_id_fk": { + "name": "user_relations_other_user_id_users_id_fk", + "tableFrom": "user_relations", + "tableTo": "users", + "columnsFrom": ["other_user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "user_relations_pkey": { + "name": "user_relations_pkey", + "columns": ["user_id", "other_user_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user_two_factor": { + "name": "user_two_factor", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "sealed_secret": { + "name": "sealed_secret", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "confirmed_at": { + "name": "confirmed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_step": { + "name": "last_step", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "user_two_factor_user_id_users_id_fk": { + "name": "user_two_factor_user_id_users_id_fk", + "tableFrom": "user_two_factor", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.usergroups": { + "name": "usergroups", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "usergroups_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "badge_token": { + "name": "badge_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name_color_light": { + "name": "name_color_light", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name_color_dark": { + "name": "name_color_dark", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "badge_image_light": { + "name": "badge_image_light", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "badge_image_dark": { + "name": "badge_image_dark", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_order": { + "name": "display_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "is_system": { + "name": "is_system", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_staff_group": { + "name": "is_staff_group", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "plugin_grantable": { + "name": "plugin_grantable", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_view": { + "name": "can_view", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_view_threads": { + "name": "can_view_threads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_view_others_threads": { + "name": "can_view_others_threads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_search": { + "name": "can_search", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_post_threads": { + "name": "can_post_threads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_post_replies": { + "name": "can_post_replies", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_post_polls": { + "name": "can_post_polls", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_vote_polls": { + "name": "can_vote_polls", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_rate_threads": { + "name": "can_rate_threads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_edit_own_posts": { + "name": "can_edit_own_posts", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_delete_own_posts": { + "name": "can_delete_own_posts", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_delete_own_threads": { + "name": "can_delete_own_threads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_edit_others_posts": { + "name": "can_edit_others_posts", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_soft_delete_posts": { + "name": "can_soft_delete_posts", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_view_unapproved": { + "name": "can_view_unapproved", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_view_deleted": { + "name": "can_view_deleted", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_approve_content": { + "name": "can_approve_content", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_upload_attachments": { + "name": "can_upload_attachments", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_download_attachments": { + "name": "can_download_attachments", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_subscribe": { + "name": "can_subscribe", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_view_profiles": { + "name": "can_view_profiles", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_view_member_list": { + "name": "can_view_member_list", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_use_private_messages": { + "name": "can_use_private_messages", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_use_signature": { + "name": "can_use_signature", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_upload_avatar": { + "name": "can_upload_avatar", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_report_content": { + "name": "can_report_content", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_view_board_offline": { + "name": "can_view_board_offline", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_bypass_flood_check": { + "name": "can_bypass_flood_check", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_access_mod_cp": { + "name": "can_access_mod_cp", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_warn_users": { + "name": "can_warn_users", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_super_moderator": { + "name": "is_super_moderator", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "is_administrator": { + "name": "is_administrator", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_access_admin_cp": { + "name": "can_access_admin_cp", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "max_posts_per_day": { + "name": "max_posts_per_day", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "edit_time_limit_minutes": { + "name": "edit_time_limit_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attachments_per_post": { + "name": "max_attachments_per_post", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attachment_size_kb": { + "name": "max_attachment_size_kb", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_private_messages_per_day": { + "name": "max_private_messages_per_day", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "can_give_reputation": { + "name": "can_give_reputation", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "max_reputation_per_day": { + "name": "max_reputation_per_day", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "private_message_quota": { + "name": "private_message_quota", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_signature_length": { + "name": "max_signature_length", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "requires_thread_approval": { + "name": "requires_thread_approval", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "requires_post_approval": { + "name": "requires_post_approval", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "requires_approval_on_edit": { + "name": "requires_approval_on_edit", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": 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": { + "usergroups_key_key": { + "name": "usergroups_key_key", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "usergroups_display_order_idx": { + "name": "usergroups_display_order_idx", + "columns": [ + { + "expression": "display_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.users": { + "name": "users", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "users_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "username_lower": { + "name": "username_lower", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_lower": { + "name": "email_lower", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password_algo": { + "name": "password_algo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password_changed_at": { + "name": "password_changed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "primary_group_id": { + "name": "primary_group_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "display_group_id": { + "name": "display_group_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "post_count": { + "name": "post_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "thread_count": { + "name": "thread_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "reputation": { + "name": "reputation", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "warning_points": { + "name": "warning_points", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "signature": { + "name": "signature", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "signature_html": { + "name": "signature_html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signature_render_version": { + "name": "signature_render_version", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "signature_format": { + "name": "signature_format", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "signature_locked": { + "name": "signature_locked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "signature_locked_reason": { + "name": "signature_locked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "avatar_status": { + "name": "avatar_status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'none'" + }, + "avatar_key": { + "name": "avatar_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "avatar_source_key": { + "name": "avatar_source_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "avatar_width": { + "name": "avatar_width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "avatar_height": { + "name": "avatar_height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "avatar_failure_reason": { + "name": "avatar_failure_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "avatar_updated_at": { + "name": "avatar_updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "avatar_locked": { + "name": "avatar_locked", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "avatar_locked_reason": { + "name": "avatar_locked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "registration_ip_prefix": { + "name": "registration_ip_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_ip_prefix": { + "name": "last_ip_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_active_at": { + "name": "last_active_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "email_verified_at": { + "name": "email_verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "suspended_posting_until": { + "name": "suspended_posting_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "moderated_posting_until": { + "name": "moderated_posting_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "timezone": { + "name": "timezone", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'auto'" + }, + "locale": { + "name": "locale", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'auto'" + }, + "posts_per_page": { + "name": "posts_per_page", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "threads_per_page": { + "name": "threads_per_page", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "invisible": { + "name": "invisible", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "location": { + "name": "location", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "website": { + "name": "website", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bio": { + "name": "bio", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "legacy_mybb_uid": { + "name": "legacy_mybb_uid", + "type": "integer", + "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": { + "users_username_lower_key": { + "name": "users_username_lower_key", + "columns": [ + { + "expression": "username_lower", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "users_email_lower_key": { + "name": "users_email_lower_key", + "columns": [ + { + "expression": "email_lower", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "users_legacy_mybb_uid_key": { + "name": "users_legacy_mybb_uid_key", + "columns": [ + { + "expression": "legacy_mybb_uid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"users\".\"legacy_mybb_uid\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "users_primary_group_idx": { + "name": "users_primary_group_idx", + "columns": [ + { + "expression": "primary_group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "users_active_created_idx": { + "name": "users_active_created_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"users\".\"state\" = 'active'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "users_last_active_idx": { + "name": "users_last_active_idx", + "columns": [ + { + "expression": "last_active_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "users_signature_render_version_idx": { + "name": "users_signature_render_version_idx", + "columns": [ + { + "expression": "signature_render_version", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"users\".\"signature\" <> ''", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "users_primary_group_id_usergroups_id_fk": { + "name": "users_primary_group_id_usergroups_id_fk", + "tableFrom": "users", + "tableTo": "usergroups", + "columnsFrom": ["primary_group_id"], + "columnsTo": ["id"], + "onDelete": "restrict", + "onUpdate": "no action" + }, + "users_display_group_id_usergroups_id_fk": { + "name": "users_display_group_id_usergroups_id_fk", + "tableFrom": "users", + "tableTo": "usergroups", + "columnsFrom": ["display_group_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.warning_levels": { + "name": "warning_levels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "warning_levels_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "points": { + "name": "points", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "duration_days": { + "name": "duration_days", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "warning_levels_points_unique": { + "name": "warning_levels_points_unique", + "columns": [ + { + "expression": "points", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.warning_types": { + "name": "warning_types", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "warning_types_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "points": { + "name": "points", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "expiry_days": { + "name": "expiry_days", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "is_active": { + "name": "is_active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "display_order": { + "name": "display_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "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": { + "warning_types_order_idx": { + "name": "warning_types_order_idx", + "columns": [ + { + "expression": "display_order", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.warnings": { + "name": "warnings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "warnings_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "issued_by_user_id": { + "name": "issued_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "type_id": { + "name": "type_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "points": { + "name": "points", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "post_id": { + "name": "post_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "report_id": { + "name": "report_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "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 + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "revoked_by_user_id": { + "name": "revoked_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "revoke_reason": { + "name": "revoke_reason", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "warnings_user_idx": { + "name": "warnings_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "warnings_user_id_users_id_fk": { + "name": "warnings_user_id_users_id_fk", + "tableFrom": "warnings", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "warnings_issued_by_user_id_users_id_fk": { + "name": "warnings_issued_by_user_id_users_id_fk", + "tableFrom": "warnings", + "tableTo": "users", + "columnsFrom": ["issued_by_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "warnings_type_id_warning_types_id_fk": { + "name": "warnings_type_id_warning_types_id_fk", + "tableFrom": "warnings", + "tableTo": "warning_types", + "columnsFrom": ["type_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "warnings_revoked_by_user_id_users_id_fk": { + "name": "warnings_revoked_by_user_id_users_id_fk", + "tableFrom": "warnings", + "tableTo": "users", + "columnsFrom": ["revoked_by_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.private_message_copies": { + "name": "private_message_copies", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "private_message_copies_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "message_id": { + "name": "message_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "folder": { + "name": "folder", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'inbox'" + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'to'" + }, + "read_at": { + "name": "read_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": { + "private_message_copies_folder_idx": { + "name": "private_message_copies_folder_idx", + "columns": [ + { + "expression": "owner_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "folder", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "private_message_copies_unread_idx": { + "name": "private_message_copies_unread_idx", + "columns": [ + { + "expression": "owner_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"private_message_copies\".\"read_at\" is null and \"private_message_copies\".\"folder\" = 'inbox'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "private_message_copies_message_idx": { + "name": "private_message_copies_message_idx", + "columns": [ + { + "expression": "message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "private_message_copies_message_id_private_messages_id_fk": { + "name": "private_message_copies_message_id_private_messages_id_fk", + "tableFrom": "private_message_copies", + "tableTo": "private_messages", + "columnsFrom": ["message_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "private_message_copies_owner_user_id_users_id_fk": { + "name": "private_message_copies_owner_user_id_users_id_fk", + "tableFrom": "private_message_copies", + "tableTo": "users", + "columnsFrom": ["owner_user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "private_message_copies_unique": { + "name": "private_message_copies_unique", + "nullsNotDistinct": false, + "columns": ["message_id", "owner_user_id"] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.private_messages": { + "name": "private_messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "private_messages_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "author_user_id": { + "name": "author_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "author_username": { + "name": "author_username", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body_format": { + "name": "body_format", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "message_html": { + "name": "message_html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "render_version": { + "name": "render_version", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "vocab_version": { + "name": "vocab_version", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "reply_to_id": { + "name": "reply_to_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "receipt_requested": { + "name": "receipt_requested", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "private_messages_render_version_idx": { + "name": "private_messages_render_version_idx", + "columns": [ + { + "expression": "render_version", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "private_messages_vocab_version_idx": { + "name": "private_messages_vocab_version_idx", + "columns": [ + { + "expression": "vocab_version", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "private_messages_author_user_id_users_id_fk": { + "name": "private_messages_author_user_id_users_id_fk", + "tableFrom": "private_messages", + "tableTo": "users", + "columnsFrom": ["author_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "private_messages_reply_to_id_private_messages_id_fk": { + "name": "private_messages_reply_to_id_private_messages_id_fk", + "tableFrom": "private_messages", + "tableTo": "private_messages", + "columnsFrom": ["reply_to_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.admin_log": { + "name": "admin_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "admin_log_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "detail": { + "name": "detail", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "ip_prefix": { + "name": "ip_prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "correlation_id": { + "name": "correlation_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "admin_log_user_idx": { + "name": "admin_log_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "admin_log_action_idx": { + "name": "admin_log_action_idx", + "columns": [ + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "admin_log_forum_scope_idx": { + "name": "admin_log_forum_scope_idx", + "columns": [ + { + "expression": "(\"detail\" -> 'forumIds') jsonb_path_ops", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + } + }, + "foreignKeys": { + "admin_log_user_id_users_id_fk": { + "name": "admin_log_user_id_users_id_fk", + "tableFrom": "admin_log", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.board_stats": { + "name": "board_stats", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "smallint", + "primaryKey": true, + "notNull": true, + "default": 1 + }, + "thread_count": { + "name": "thread_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "post_count": { + "name": "post_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "member_count": { + "name": "member_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "newest_user_id": { + "name": "newest_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "newest_username": { + "name": "newest_username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "most_online_count": { + "name": "most_online_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "most_online_at": { + "name": "most_online_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "computed_at": { + "name": "computed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "board_stats_singleton": { + "name": "board_stats_singleton", + "value": "\"board_stats\".\"id\" = 1" + } + }, + "isRLSEnabled": false + }, + "public.cache_versions": { + "name": "cache_versions", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "bumped_at": { + "name": "bumped_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.captcha_questions": { + "name": "captcha_questions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "captcha_questions_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "question": { + "name": "question", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "answers": { + "name": "answers", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": 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.content_counter_rollups": { + "name": "content_counter_rollups", + "schema": "", + "columns": { + "post_id": { + "name": "post_id", + "type": "integer", + "primaryKey": true, + "notNull": true + }, + "applied_at": { + "name": "applied_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.counter_recount_state": { + "name": "counter_recount_state", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "phase": { + "name": "phase", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'threads'" + }, + "cursor": { + "name": "cursor", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "passes": { + "name": "passes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "corrected": { + "name": "corrected", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "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.jobs": { + "name": "jobs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "jobs_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "run_at": { + "name": "run_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "attempts": { + "name": "attempts", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 5 + }, + "locked_until": { + "name": "locked_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "locked_by": { + "name": "locked_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "correlation_id": { + "name": "correlation_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "jobs_pending_idx": { + "name": "jobs_pending_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "run_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"jobs\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "jobs_idempotency_key": { + "name": "jobs_idempotency_key", + "columns": [ + { + "expression": "idempotency_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"jobs\".\"idempotency_key\" is not null and \"jobs\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "jobs_status_idx": { + "name": "jobs_status_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.mass_mails": { + "name": "mass_mails", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "mass_mails_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_group_id": { + "name": "target_group_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_user_id": { + "name": "last_user_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "queued_count": { + "name": "queued_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'sending'" + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "mass_mails_target_group_id_usergroups_id_fk": { + "name": "mass_mails_target_group_id_usergroups_id_fk", + "tableFrom": "mass_mails", + "tableTo": "usergroups", + "columnsFrom": ["target_group_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + }, + "mass_mails_created_by_user_id_users_id_fk": { + "name": "mass_mails_created_by_user_id_users_id_fk", + "tableFrom": "mass_mails", + "tableTo": "users", + "columnsFrom": ["created_by_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.navigation_item_groups": { + "name": "navigation_item_groups", + "schema": "", + "columns": { + "item_id": { + "name": "item_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "navigation_item_groups_group_idx": { + "name": "navigation_item_groups_group_idx", + "columns": [ + { + "expression": "group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "navigation_item_groups_item_id_navigation_items_id_fk": { + "name": "navigation_item_groups_item_id_navigation_items_id_fk", + "tableFrom": "navigation_item_groups", + "tableTo": "navigation_items", + "columnsFrom": ["item_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "navigation_item_groups_group_id_usergroups_id_fk": { + "name": "navigation_item_groups_group_id_usergroups_id_fk", + "tableFrom": "navigation_item_groups", + "tableTo": "usergroups", + "columnsFrom": ["group_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "navigation_item_groups_item_id_group_id_pk": { + "name": "navigation_item_groups_item_id_group_id_pk", + "columns": ["item_id", "group_id"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.navigation_items": { + "name": "navigation_items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "navigation_items_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "href": { + "name": "href", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_order": { + "name": "display_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "audience": { + "name": "audience", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'all'" + }, + "new_tab": { + "name": "new_tab", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "navigation_items_key_key": { + "name": "navigation_items_key_key", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"navigation_items\".\"key\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "navigation_items_order_idx": { + "name": "navigation_items_order_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "display_order", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "navigation_items_parent_id_fk": { + "name": "navigation_items_parent_id_fk", + "tableFrom": "navigation_items", + "tableTo": "navigation_items", + "columnsFrom": ["parent_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "navigation_items_audience_check": { + "name": "navigation_items_audience_check", + "value": "\"navigation_items\".\"audience\" in ('all', 'guests', 'members', 'staff')" + } + }, + "isRLSEnabled": false + }, + "public.outbox": { + "name": "outbox", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "outbox_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "topic": { + "name": "topic", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "correlation_id": { + "name": "correlation_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dispatched_at": { + "name": "dispatched_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "outbox_pending_idx": { + "name": "outbox_pending_idx", + "columns": [ + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"outbox\".\"dispatched_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.plugin_health": { + "name": "plugin_health", + "schema": "", + "columns": { + "plugin_key": { + "name": "plugin_key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "failures": { + "name": "failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "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.rate_limits": { + "name": "rate_limits", + "schema": "", + "columns": { + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "window_start": { + "name": "window_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "used": { + "name": "used", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "rate_limits_window_idx": { + "name": "rate_limits_window_idx", + "columns": [ + { + "expression": "window_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "rate_limits_scope_subject_window_start_pk": { + "name": "rate_limits_scope_subject_window_start_pk", + "columns": ["scope", "subject", "window_start"] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.searches": { + "name": "searches", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "searches_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "session_key": { + "name": "session_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "terms": { + "name": "terms", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "filters": { + "name": "filters", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "hit_count": { + "name": "hit_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "searches_token_key": { + "name": "searches_token_key", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "searches_user_recent_idx": { + "name": "searches_user_recent_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "searches_session_recent_idx": { + "name": "searches_session_recent_idx", + "columns": [ + { + "expression": "session_key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "searches_user_id_users_id_fk": { + "name": "searches_user_id_users_id_fk", + "tableFrom": "searches", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.setting_groups": { + "name": "setting_groups", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "setting_groups_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_order": { + "name": "display_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "setting_groups_key_key": { + "name": "setting_groups_key_key", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.settings": { + "name": "settings", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_key": { + "name": "group_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "updated_by_user_id": { + "name": "updated_by_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "settings_group_idx": { + "name": "settings_group_idx", + "columns": [ + { + "expression": "group_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "settings_updated_by_user_id_users_id_fk": { + "name": "settings_updated_by_user_id_users_id_fk", + "tableFrom": "settings", + "tableTo": "users", + "columnsFrom": ["updated_by_user_id"], + "columnsTo": ["id"], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.task_log": { + "name": "task_log", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "task_log_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "task_key": { + "name": "task_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "succeeded": { + "name": "succeeded", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "detail": { + "name": "detail", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ran_at": { + "name": "ran_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "task_log_key_ran_idx": { + "name": "task_log_key_ran_idx", + "columns": [ + { + "expression": "task_key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "ran_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tasks": { + "name": "tasks", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "interval_seconds": { + "name": "interval_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "last_run_at": { + "name": "last_run_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_run_at": { + "name": "next_run_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "locked_until": { + "name": "locked_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "consecutive_failures": { + "name": "consecutive_failures", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.themes": { + "name": "themes", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_overrides": { + "name": "token_overrides", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "branding": { + "name": "branding", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "layout_options": { + "name": "layout_options", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "custom_css": { + "name": "custom_css", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "themes_single_default_key": { + "name": "themes_single_default_key", + "columns": [ + { + "expression": "is_default", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"themes\".\"is_default\"", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.forum_moderators": { + "name": "forum_moderators", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "forum_moderators_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "forum_id": { + "name": "forum_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "group_id": { + "name": "group_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cascade_to_subforums": { + "name": "cascade_to_subforums", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_edit_posts": { + "name": "can_edit_posts", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_soft_delete_posts": { + "name": "can_soft_delete_posts", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_restore_posts": { + "name": "can_restore_posts", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_approve_content": { + "name": "can_approve_content", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_open_close_threads": { + "name": "can_open_close_threads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_stick_threads": { + "name": "can_stick_threads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_move_threads": { + "name": "can_move_threads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_merge_threads": { + "name": "can_merge_threads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "can_split_threads": { + "name": "can_split_threads", + "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": { + "forum_moderators_user_key": { + "name": "forum_moderators_user_key", + "columns": [ + { + "expression": "forum_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"forum_moderators\".\"user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "forum_moderators_group_key": { + "name": "forum_moderators_group_key", + "columns": [ + { + "expression": "forum_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"forum_moderators\".\"group_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "forum_moderators_user_idx": { + "name": "forum_moderators_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "forum_moderators_group_idx": { + "name": "forum_moderators_group_idx", + "columns": [ + { + "expression": "group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "forum_moderators_forum_id_forums_id_fk": { + "name": "forum_moderators_forum_id_forums_id_fk", + "tableFrom": "forum_moderators", + "tableTo": "forums", + "columnsFrom": ["forum_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "forum_moderators_user_id_users_id_fk": { + "name": "forum_moderators_user_id_users_id_fk", + "tableFrom": "forum_moderators", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "forum_moderators_group_id_usergroups_id_fk": { + "name": "forum_moderators_group_id_usergroups_id_fk", + "tableFrom": "forum_moderators", + "tableTo": "usergroups", + "columnsFrom": ["group_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.forum_permissions": { + "name": "forum_permissions", + "schema": "", + "columns": { + "forum_id": { + "name": "forum_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "can_view": { + "name": "can_view", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_view_threads": { + "name": "can_view_threads", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_view_others_threads": { + "name": "can_view_others_threads", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_search": { + "name": "can_search", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_post_threads": { + "name": "can_post_threads", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_post_replies": { + "name": "can_post_replies", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_post_polls": { + "name": "can_post_polls", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_vote_polls": { + "name": "can_vote_polls", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_rate_threads": { + "name": "can_rate_threads", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_edit_own_posts": { + "name": "can_edit_own_posts", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_delete_own_posts": { + "name": "can_delete_own_posts", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_delete_own_threads": { + "name": "can_delete_own_threads", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_edit_others_posts": { + "name": "can_edit_others_posts", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_soft_delete_posts": { + "name": "can_soft_delete_posts", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_view_unapproved": { + "name": "can_view_unapproved", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_view_deleted": { + "name": "can_view_deleted", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_approve_content": { + "name": "can_approve_content", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_upload_attachments": { + "name": "can_upload_attachments", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_download_attachments": { + "name": "can_download_attachments", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "can_subscribe": { + "name": "can_subscribe", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "edit_time_limit_minutes": { + "name": "edit_time_limit_minutes", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "max_attachments_per_post": { + "name": "max_attachments_per_post", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "max_attachment_size_kb": { + "name": "max_attachment_size_kb", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "requires_thread_approval": { + "name": "requires_thread_approval", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "requires_post_approval": { + "name": "requires_post_approval", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "requires_approval_on_edit": { + "name": "requires_approval_on_edit", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "forum_permissions_pkey": { + "name": "forum_permissions_pkey", + "columns": [ + { + "expression": "forum_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "forum_permissions_group_idx": { + "name": "forum_permissions_group_idx", + "columns": [ + { + "expression": "group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "forum_permissions_forum_id_forums_id_fk": { + "name": "forum_permissions_forum_id_forums_id_fk", + "tableFrom": "forum_permissions", + "tableTo": "forums", + "columnsFrom": ["forum_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "forum_permissions_group_id_usergroups_id_fk": { + "name": "forum_permissions_group_id_usergroups_id_fk", + "tableFrom": "forum_permissions", + "tableTo": "usergroups", + "columnsFrom": ["group_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.forum_subscriptions": { + "name": "forum_subscriptions", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "forum_id": { + "name": "forum_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'instant'" + }, + "last_notified_post_id": { + "name": "last_notified_post_id", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "forum_subscriptions_pkey": { + "name": "forum_subscriptions_pkey", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "forum_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "forum_subscriptions_forum_idx": { + "name": "forum_subscriptions_forum_idx", + "columns": [ + { + "expression": "forum_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "forum_subscriptions_user_idx": { + "name": "forum_subscriptions_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "forum_subscriptions_mode_idx": { + "name": "forum_subscriptions_mode_idx", + "columns": [ + { + "expression": "mode", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "forum_subscriptions_user_id_users_id_fk": { + "name": "forum_subscriptions_user_id_users_id_fk", + "tableFrom": "forum_subscriptions", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "forum_subscriptions_forum_id_forums_id_fk": { + "name": "forum_subscriptions_forum_id_forums_id_fk", + "tableFrom": "forum_subscriptions", + "tableTo": "forums", + "columnsFrom": ["forum_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.forums": { + "name": "forums", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "integer", + "primaryKey": true, + "notNull": true, + "identity": { + "type": "byDefault", + "name": "forums_id_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'forum'" + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "depth": { + "name": "depth", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "display_order": { + "name": "display_order", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "link_url": { + "name": "link_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "link_hits": { + "name": "link_hits", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "is_open": { + "name": "is_open", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "allow_threads": { + "name": "allow_threads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "allow_replies": { + "name": "allow_replies", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "allow_polls": { + "name": "allow_polls", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "allow_attachments": { + "name": "allow_attachments", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "requires_prefix": { + "name": "requires_prefix", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "moderate_new_threads": { + "name": "moderate_new_threads", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "moderate_new_posts": { + "name": "moderate_new_posts", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "password_hash": { + "name": "password_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thread_count": { + "name": "thread_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "post_count": { + "name": "post_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_post_id": { + "name": "last_post_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_post_thread_id": { + "name": "last_post_thread_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_post_thread_title": { + "name": "last_post_thread_title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_post_user_id": { + "name": "last_post_user_id", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_post_username": { + "name": "last_post_username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_post_at": { + "name": "last_post_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "legacy_mybb_fid": { + "name": "legacy_mybb_fid", + "type": "integer", + "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": { + "forums_parent_slug_key": { + "name": "forums_parent_slug_key", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"forums\".\"parent_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "forums_root_slug_key": { + "name": "forums_root_slug_key", + "columns": [ + { + "expression": "slug", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"forums\".\"parent_id\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "forums_parent_order_idx": { + "name": "forums_parent_order_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "display_order", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "forums_path_idx": { + "name": "forums_path_idx", + "columns": [ + { + "expression": "path", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "forums_legacy_mybb_fid_key": { + "name": "forums_legacy_mybb_fid_key", + "columns": [ + { + "expression": "legacy_mybb_fid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"forums\".\"legacy_mybb_fid\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.forums_read": { + "name": "forums_read", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "forum_id": { + "name": "forum_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "forums_read_pkey": { + "name": "forums_read_pkey", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "forum_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "forums_read_user_id_users_id_fk": { + "name": "forums_read_user_id_users_id_fk", + "tableFrom": "forums_read", + "tableTo": "users", + "columnsFrom": ["user_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "forums_read_forum_id_forums_id_fk": { + "name": "forums_read_forum_id_forums_id_fk", + "tableFrom": "forums_read", + "tableTo": "forums", + "columnsFrom": ["forum_id"], + "columnsTo": ["id"], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} diff --git a/packages/db/migrations/meta/_journal.json b/packages/db/migrations/meta/_journal.json index db6429fca..6180d57b7 100644 --- a/packages/db/migrations/meta/_journal.json +++ b/packages/db/migrations/meta/_journal.json @@ -351,6 +351,13 @@ "when": 1787122304769, "tag": "0049_plugin_health", "breakpoints": true + }, + { + "idx": 50, + "version": "7", + "when": 1787229776853, + "tag": "0050_drop_forum_password_grants", + "breakpoints": true } ] } diff --git a/packages/db/src/schema/structure.ts b/packages/db/src/schema/structure.ts index 665b6864f..c3456d5c6 100644 --- a/packages/db/src/schema/structure.ts +++ b/packages/db/src/schema/structure.ts @@ -130,18 +130,6 @@ export const forumModerators = pgTable( ], ) -export const forumPasswordGrants = pgTable( - 'forum_password_grants', - { - sessionId: integer('session_id').notNull(), - forumId: integer('forum_id') - .notNull() - .references(() => forums.id, { onDelete: 'cascade' }), - grantedAt: timestamp('granted_at', { withTimezone: true }).notNull().defaultNow(), - }, - (t) => [uniqueIndex('forum_password_grants_pkey').on(t.sessionId, t.forumId)], -) - export const forumsRead = pgTable( 'forums_read', { diff --git a/packages/i18n/src/catalogs/en.json b/packages/i18n/src/catalogs/en.json index 4edb2f480..8fdca2692 100644 --- a/packages/i18n/src/catalogs/en.json +++ b/packages/i18n/src/catalogs/en.json @@ -1989,7 +1989,7 @@ "installAction.unknownFailure": "Unknown failure.", "installPreflight.alreadyInstalled.detail": "The installer disabled itself when it finished, and it cannot be run again. Use /admin to configure the board, or the operator CLI if you have lost access.", "installPreflight.alreadyInstalled.title": "This board is already installed", - "installPreflight.authSecret.missingDetail": "Sessions and tokens are signed with it and there is no default, deliberately: a shipped default is a board anybody who has read the source can sign a session for.", + "installPreflight.authSecret.missingDetail": "It signs the unsubscribe links in outgoing mail — sessions do not depend on it, they are random tokens stored hashed in the database — and there is no default, deliberately: a shipped default is a link anybody who has read the source can forge.", "installPreflight.authSecret.missingTitle": "AUTH_SECRET is not set", "installPreflight.authSecret.setTitle": "AUTH_SECRET is set", "installPreflight.blocker.one": "That has to be fixed before this board can be installed. Fix it, redeploy if it was an environment variable, and reload this page.", diff --git a/scripts/domain-packages.cjs b/scripts/domain-packages.cjs new file mode 100644 index 000000000..ea8894892 --- /dev/null +++ b/scripts/domain-packages.cjs @@ -0,0 +1,24 @@ +const { readdirSync } = require('node:fs') +const { join } = require('node:path') + +const INFRASTRUCTURE = new Set([ + 'core', + 'create-meith', + 'db', + 'demo', + 'drivers', + 'plugin-kit', + 'runtime', + 'testkit', + 'theme-kit', + 'ui', +]) + +function domainPackages() { + return readdirSync(join(__dirname, '..', 'packages'), { withFileTypes: true }) + .filter((entry) => entry.isDirectory() && !INFRASTRUCTURE.has(entry.name)) + .map((entry) => entry.name) + .sort() +} + +module.exports = { INFRASTRUCTURE, domainPackages } diff --git a/scripts/guards.mjs b/scripts/guards.mjs index 66554065c..e7e7ebcc1 100644 --- a/scripts/guards.mjs +++ b/scripts/guards.mjs @@ -1,13 +1,14 @@ #!/usr/bin/env node import { readFile } from 'node:fs/promises' +import { domainPackages } from './domain-packages.cjs' import { GUARDS } from './guards.config.mjs' import { repoFiles } from './repo-files.mjs' +const DOMAIN_PATH = new RegExp(`^packages/(${domainPackages().join('|')})/`) + function isDomainPath(rel) { - return /^packages\/(accounts|groups|authorization|forums|threads|posts|markdown|moderation|settings|events|tasks)\//.test( - rel, - ) + return DOMAIN_PATH.test(rel) } const files = await repoFiles()