diff --git a/apps/docs/src/content/docs/users/things.md b/apps/docs/src/content/docs/users/things.md index ec085529..8e1f3d99 100644 --- a/apps/docs/src/content/docs/users/things.md +++ b/apps/docs/src/content/docs/users/things.md @@ -18,7 +18,8 @@ tracks: **Details**, **Paperwork and warranties**, **Value**, **Meters**, **Loan one type to another, Kept lists the values that will be archived before you save: they stay under **Archived fields** and come back if you switch back. Owners and admins change a built-in under **Settings → Account → Types** with **Customise**, which makes the account's copy; from - then on the copy is the one every list offers, so a customised type shows once. + then on the copy is the one every list offers, so a customised type shows once. The copy keeps + the built-in's name, in each person's language, until someone renames it. - **Label**: on a computer, the **Label** card beside the details shows the label as it prints (QR code, short ID, name), with **Print** and **Download** (a PNG). On a phone, the **Label** row in Details opens it. See [short IDs and labels](/users/short-ids/). diff --git a/apps/server/migrations/0178_customised_type_names.sql b/apps/server/migrations/0178_customised_type_names.sql new file mode 100644 index 00000000..6ef5f49c --- /dev/null +++ b/apps/server/migrations/0178_customised_type_names.sql @@ -0,0 +1,39 @@ +-- Custom SQL migration file, put your code below! -- +-- A customised built-in type keeps its name (#546). kept.customise_type() (0021) copies a +-- built-in into the account with no name and no key of its own, pointing at the built-in through +-- `copied_from_id`, so the copy reads in each person's language until someone renames it. The +-- readers that named a type by its own `builtin_key` alone showed the copy as "No type"; the +-- server's readers now resolve the key through `copied_from_id` (types/graph.ts typeKeySql), and +-- this one, a share link's thing, does the same. +-- +-- Copies made before this release need no change: their rows were right all along (name NULL, +-- copied_from_id set), only the readers were wrong. The search document and the embedding text +-- already read the built-in's names through `copied_from_id` (0016, 0155). +-- Additive: the function's signature, owner and grants are unchanged. +CREATE OR REPLACE FUNCTION kept.share_thing_json(t public.things) RETURNS jsonb +LANGUAGE sql STABLE SET search_path = pg_catalog, public AS $$ + SELECT jsonb_build_object( + 'name', t.name, + 'type', (SELECT jsonb_build_object('icon', ty.icon, 'name', ty.name, + 'builtinKey', coalesce(ty.builtin_key, + (SELECT k.builtin_key FROM public.types k + WHERE k.id = ty.copied_from_id))) + FROM public.types ty WHERE ty.id = t.type_id), + 'path', kept.share_path(t.place_id, t.container_id), + 'quantity', t.quantity, + 'condition', t.condition, + 'description', t.notes, + 'photo', (SELECT jsonb_build_object( + 'fileId', f.id, + 'mime', f.mime, + 'thumb', (SELECT d.storage_key FROM public.file_derivatives d + WHERE d.file_id = f.id AND d.variant = 'thumb'), + 'large', coalesce( + (SELECT d.storage_key FROM public.file_derivatives d + WHERE d.file_id = f.id AND d.variant = 'share'), + (SELECT d.storage_key FROM public.file_derivatives d + WHERE d.file_id = f.id AND d.variant = 'display'))) + FROM public.files f + WHERE f.id = t.cover_file_id AND f.derivative_state = 'ready' + AND f.location_id = t.location_id)) +$$; diff --git a/apps/server/migrations/meta/0178_snapshot.json b/apps/server/migrations/meta/0178_snapshot.json new file mode 100644 index 00000000..554dbcff --- /dev/null +++ b/apps/server/migrations/meta/0178_snapshot.json @@ -0,0 +1,24385 @@ +{ + "id": "110913f3-73c6-4f7d-a6f3-e48bae569ec2", + "prevId": "0dedf0eb-2df9-40ec-8f83-9a9fc77ebfed", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.ai_breakers": { + "name": "ai_breakers", + "schema": "", + "columns": { + "provider_id": { + "name": "provider_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "until": { + "name": "until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "trips": { + "name": "trips", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "recent_errors": { + "name": "recent_errors", + "type": "timestamp with time zone[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::timestamptz[]" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "ai_breakers_provider_id_ai_providers_id_fk": { + "name": "ai_breakers_provider_id_ai_providers_id_fk", + "tableFrom": "ai_breakers", + "columnsFrom": [ + "provider_id" + ], + "tableTo": "ai_providers", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "ai_breakers_reason_chk": { + "name": "ai_breakers_reason_chk", + "value": "\"reason\" IN ('rate_limited', 'quota', 'auth', 'provider_down')" + }, + "ai_breakers_trip_pair_chk": { + "name": "ai_breakers_trip_pair_chk", + "value": "(reason IS NULL) = (until IS NULL)" + }, + "ai_breakers_trips_chk": { + "name": "ai_breakers_trips_chk", + "value": "trips >= 0" + } + }, + "isRLSEnabled": false + }, + "public.ai_budgets": { + "name": "ai_budgets", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "task": { + "name": "task", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "tokens_per_minute": { + "name": "tokens_per_minute", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "tokens_per_day": { + "name": "tokens_per_day", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "tokens_per_month": { + "name": "tokens_per_month", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "monthly_cap_amount": { + "name": "monthly_cap_amount", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": false + }, + "cap_currency": { + "name": "cap_currency", + "type": "char(3)", + "primaryKey": false, + "notNull": false + }, + "paused_until": { + "name": "paused_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "paused_reason": { + "name": "paused_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "warned_80_month": { + "name": "warned_80_month", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "warned_100_month": { + "name": "warned_100_month", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "set_by": { + "name": "set_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "ai_budgets_account_idx": { + "name": "ai_budgets_account_idx", + "columns": [ + { + "expression": "owner_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "ai_budgets_location_idx": { + "name": "ai_budgets_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "ai_budgets_user_idx": { + "name": "ai_budgets_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "ai_budgets_paused_idx": { + "name": "ai_budgets_paused_idx", + "columns": [ + { + "expression": "paused_until", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "paused_until IS NOT NULL", + "concurrently": false + } + }, + "foreignKeys": { + "ai_budgets_owner_account_id_owner_accounts_id_fk": { + "name": "ai_budgets_owner_account_id_owner_accounts_id_fk", + "tableFrom": "ai_budgets", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "ai_budgets_location_id_locations_id_fk": { + "name": "ai_budgets_location_id_locations_id_fk", + "tableFrom": "ai_budgets", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "ai_budgets_user_id_user_id_fk": { + "name": "ai_budgets_user_id_user_id_fk", + "tableFrom": "ai_budgets", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "ai_budgets_cap_currency_currencies_code_fk": { + "name": "ai_budgets_cap_currency_currencies_code_fk", + "tableFrom": "ai_budgets", + "columnsFrom": [ + "cap_currency" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "ai_budgets_scope_uq": { + "name": "ai_budgets_scope_uq", + "columns": [ + "scope", + "owner_account_id", + "location_id", + "user_id", + "task" + ], + "nullsNotDistinct": true + } + }, + "policies": {}, + "checkConstraints": { + "ai_budgets_scope_chk": { + "name": "ai_budgets_scope_chk", + "value": "\"scope\" IN ('instance', 'instance_account', 'account', 'location', 'member', 'user')" + }, + "ai_budgets_task_chk": { + "name": "ai_budgets_task_chk", + "value": "\"task\" IN ('extraction', 'assistant', 'embeddings')" + }, + "ai_budgets_paused_reason_chk": { + "name": "ai_budgets_paused_reason_chk", + "value": "\"paused_reason\" IN ('manual', 'cap_money', 'cap_tokens', 'tokens_day')" + }, + "ai_budgets_tpm_chk": { + "name": "ai_budgets_tpm_chk", + "value": "tokens_per_minute > 0" + }, + "ai_budgets_tpd_chk": { + "name": "ai_budgets_tpd_chk", + "value": "tokens_per_day > 0" + }, + "ai_budgets_month_tokens_chk": { + "name": "ai_budgets_month_tokens_chk", + "value": "tokens_per_month > 0" + }, + "ai_budgets_money_chk": { + "name": "ai_budgets_money_chk", + "value": "monthly_cap_amount >= 0" + }, + "ai_budgets_money_pair_chk": { + "name": "ai_budgets_money_pair_chk", + "value": "(monthly_cap_amount IS NULL) = (cap_currency IS NULL)" + }, + "ai_budgets_pause_pair_chk": { + "name": "ai_budgets_pause_pair_chk", + "value": "(paused_until IS NULL) = (paused_reason IS NULL)" + }, + "ai_budgets_scope_ids_chk": { + "name": "ai_budgets_scope_ids_chk", + "value": "CASE scope\n WHEN 'instance' THEN owner_account_id IS NULL AND location_id IS NULL AND user_id IS NULL\n WHEN 'instance_account' THEN location_id IS NULL AND user_id IS NULL\n WHEN 'account' THEN owner_account_id IS NOT NULL AND location_id IS NULL AND user_id IS NULL\n WHEN 'location' THEN owner_account_id IS NOT NULL AND location_id IS NOT NULL AND user_id IS NULL\n WHEN 'member' THEN owner_account_id IS NOT NULL AND location_id IS NULL AND user_id IS NOT NULL\n ELSE owner_account_id IS NULL AND location_id IS NULL AND user_id IS NOT NULL END" + }, + "ai_budgets_minute_day_chk": { + "name": "ai_budgets_minute_day_chk", + "value": "(tokens_per_minute IS NULL AND tokens_per_day IS NULL)\n OR (scope IN ('instance', 'account') AND task IS NOT NULL)" + } + }, + "isRLSEnabled": false + }, + "public.ai_cost_windows": { + "name": "ai_cost_windows", + "schema": "", + "columns": { + "bucket": { + "name": "bucket", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "month_start": { + "name": "month_start", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "currency": { + "name": "currency", + "type": "char(3)", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "numeric(16, 6)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "ai_cost_windows_pk": { + "name": "ai_cost_windows_pk", + "columns": [ + "bucket", + "month_start", + "currency" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ai_leases": { + "name": "ai_leases", + "schema": "", + "columns": { + "lease_key": { + "name": "lease_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slot": { + "name": "slot", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "job_id": { + "name": "job_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": { + "ai_leases_pk": { + "name": "ai_leases_pk", + "columns": [ + "lease_key", + "slot" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "ai_leases_slot_chk": { + "name": "ai_leases_slot_chk", + "value": "slot BETWEEN 1 AND 4" + } + }, + "isRLSEnabled": false + }, + "public.ai_model_prices": { + "name": "ai_model_prices", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "provider_kind": { + "name": "provider_kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "input_per_mtok": { + "name": "input_per_mtok", + "type": "numeric(16, 6)", + "primaryKey": false, + "notNull": true + }, + "output_per_mtok": { + "name": "output_per_mtok", + "type": "numeric(16, 6)", + "primaryKey": false, + "notNull": true + }, + "reasoning_per_mtok": { + "name": "reasoning_per_mtok", + "type": "numeric(16, 6)", + "primaryKey": false, + "notNull": false + }, + "cached_input_per_mtok": { + "name": "cached_input_per_mtok", + "type": "numeric(16, 6)", + "primaryKey": false, + "notNull": false + }, + "per_image": { + "name": "per_image", + "type": "numeric(16, 6)", + "primaryKey": false, + "notNull": false + }, + "currency": { + "name": "currency", + "type": "char(3)", + "primaryKey": false, + "notNull": true + }, + "effective_from": { + "name": "effective_from", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "superseded_at": { + "name": "superseded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "listing_fetched_at": { + "name": "listing_fetched_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "ai_model_prices_current_uq": { + "name": "ai_model_prices_current_uq", + "columns": [ + { + "expression": "provider_kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "model", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "superseded_at IS NULL", + "concurrently": false + } + }, + "foreignKeys": { + "ai_model_prices_currency_currencies_code_fk": { + "name": "ai_model_prices_currency_currencies_code_fk", + "tableFrom": "ai_model_prices", + "columnsFrom": [ + "currency" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "ai_model_prices_version_uq": { + "name": "ai_model_prices_version_uq", + "columns": [ + "provider_kind", + "model", + "version" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "ai_model_prices_source_chk": { + "name": "ai_model_prices_source_chk", + "value": "\"source\" IN ('admin', 'provider_listing')" + }, + "ai_model_prices_kind_chk": { + "name": "ai_model_prices_kind_chk", + "value": "provider_kind IN ('openai', 'anthropic', 'google', 'openai_compatible', 'openrouter', 'groq')" + }, + "ai_model_prices_model_chk": { + "name": "ai_model_prices_model_chk", + "value": "char_length(model) BETWEEN 1 AND 120" + }, + "ai_model_prices_version_chk": { + "name": "ai_model_prices_version_chk", + "value": "version >= 1" + }, + "ai_model_prices_rates_chk": { + "name": "ai_model_prices_rates_chk", + "value": "input_per_mtok >= 0 AND output_per_mtok >= 0 AND reasoning_per_mtok >= 0\n AND cached_input_per_mtok >= 0 AND per_image >= 0" + }, + "ai_model_prices_listing_chk": { + "name": "ai_model_prices_listing_chk", + "value": "source = 'admin' OR listing_fetched_at IS NOT NULL" + }, + "ai_model_prices_superseded_chk": { + "name": "ai_model_prices_superseded_chk", + "value": "superseded_at IS NULL OR superseded_at >= effective_from" + } + }, + "isRLSEnabled": false + }, + "public.ai_provider_limits": { + "name": "ai_provider_limits", + "schema": "", + "columns": { + "provider_id": { + "name": "provider_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "limit_tokens": { + "name": "limit_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "remaining_tokens": { + "name": "remaining_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reset_at": { + "name": "reset_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "output_limit_tokens": { + "name": "output_limit_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "output_used": { + "name": "output_used", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "output_window_start": { + "name": "output_window_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "ai_provider_limits_provider_id_ai_providers_id_fk": { + "name": "ai_provider_limits_provider_id_ai_providers_id_fk", + "tableFrom": "ai_provider_limits", + "columnsFrom": [ + "provider_id" + ], + "tableTo": "ai_providers", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.ai_providers": { + "name": "ai_providers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model_list": { + "name": "model_list", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "model_list_at": { + "name": "model_list_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "base_url": { + "name": "base_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key_ciphertext": { + "name": "key_ciphertext", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "key_version": { + "name": "key_version", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "key_hint": { + "name": "key_hint", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "models": { + "name": "models", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "capabilities": { + "name": "capabilities", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "reasoning": { + "name": "reasoning", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'low'" + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "ai_providers_active_uq": { + "name": "ai_providers_active_uq", + "columns": [ + { + "expression": "scope", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(owner_account_id, user_id, '00000000-0000-0000-0000-000000000000'::uuid)", + "isExpression": true, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "disabled_at IS NULL", + "concurrently": false + }, + "ai_providers_account_idx": { + "name": "ai_providers_account_idx", + "columns": [ + { + "expression": "owner_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "ai_providers_user_idx": { + "name": "ai_providers_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "ai_providers_owner_account_id_owner_accounts_id_fk": { + "name": "ai_providers_owner_account_id_owner_accounts_id_fk", + "tableFrom": "ai_providers", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "ai_providers_user_id_user_id_fk": { + "name": "ai_providers_user_id_user_id_fk", + "tableFrom": "ai_providers", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "ai_providers_scope_chk": { + "name": "ai_providers_scope_chk", + "value": "\"scope\" IN ('instance', 'account', 'user')" + }, + "ai_providers_kind_chk": { + "name": "ai_providers_kind_chk", + "value": "\"kind\" IN ('openai', 'anthropic', 'google', 'openai_compatible', 'openrouter', 'groq')" + }, + "ai_providers_reasoning_chk": { + "name": "ai_providers_reasoning_chk", + "value": "reasoning IN ('provider-default', 'none', 'minimal', 'low', 'medium', 'high')" + }, + "ai_providers_label_chk": { + "name": "ai_providers_label_chk", + "value": "char_length(label) <= 60" + }, + "ai_providers_base_url_chk": { + "name": "ai_providers_base_url_chk", + "value": "base_url IS NULL OR (base_url ~ '^https?://' AND char_length(base_url) <= 300)" + }, + "ai_providers_key_hint_chk": { + "name": "ai_providers_key_hint_chk", + "value": "key_hint ~ '^[A-Za-z0-9_-]{0,4}$'" + }, + "ai_providers_models_chk": { + "name": "ai_providers_models_chk", + "value": "jsonb_typeof(models) = 'object'" + }, + "ai_providers_capabilities_chk": { + "name": "ai_providers_capabilities_chk", + "value": "jsonb_typeof(capabilities) = 'object'" + }, + "ai_providers_scope_ids_chk": { + "name": "ai_providers_scope_ids_chk", + "value": "CASE scope WHEN 'instance' THEN owner_account_id IS NULL AND user_id IS NULL\n WHEN 'account' THEN owner_account_id IS NOT NULL AND user_id IS NULL\n ELSE user_id IS NOT NULL AND owner_account_id IS NULL END" + }, + "ai_providers_key_pair_chk": { + "name": "ai_providers_key_pair_chk", + "value": "(key_ciphertext IS NULL) = (key_version IS NULL)" + }, + "ai_providers_compatible_chk": { + "name": "ai_providers_compatible_chk", + "value": "kind <> 'openai_compatible' OR base_url IS NOT NULL" + }, + "ai_providers_keyed_chk": { + "name": "ai_providers_keyed_chk", + "value": "kind = 'openai_compatible' OR key_ciphertext IS NOT NULL OR disabled_at IS NOT NULL" + } + }, + "isRLSEnabled": false + }, + "public.ai_usage_months": { + "name": "ai_usage_months", + "schema": "", + "columns": { + "month": { + "name": "month", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "paying_scope": { + "name": "paying_scope", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "paying_account_id": { + "name": "paying_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "paying_user_id": { + "name": "paying_user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "task": { + "name": "task", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_kind": { + "name": "provider_kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cost_currency": { + "name": "cost_currency", + "type": "char(3)", + "primaryKey": false, + "notNull": false + }, + "calls": { + "name": "calls", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "sent_calls": { + "name": "sent_calls", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "tokens": { + "name": "tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "input_tokens": { + "name": "input_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "output_tokens": { + "name": "output_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "reasoning_tokens": { + "name": "reasoning_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "cached_tokens": { + "name": "cached_tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "images": { + "name": "images", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "cost_amount": { + "name": "cost_amount", + "type": "numeric(18, 6)", + "primaryKey": false, + "notNull": false + }, + "unknown_cost_calls": { + "name": "unknown_cost_calls", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "outcomes": { + "name": "outcomes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "ai_usage_months_owner_idx": { + "name": "ai_usage_months_owner_idx", + "columns": [ + { + "expression": "owner_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "month", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "ai_usage_months_location_idx": { + "name": "ai_usage_months_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "month", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "ai_usage_months_user_idx": { + "name": "ai_usage_months_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "month", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "ai_usage_months_payer_idx": { + "name": "ai_usage_months_payer_idx", + "columns": [ + { + "expression": "paying_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "month", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "ai_usage_months_uq": { + "name": "ai_usage_months_uq", + "columns": [ + "month", + "paying_scope", + "paying_account_id", + "paying_user_id", + "location_id", + "user_id", + "task", + "provider_kind", + "model", + "cost_currency" + ], + "nullsNotDistinct": true + } + }, + "policies": {}, + "checkConstraints": { + "ai_usage_months_paying_scope_chk": { + "name": "ai_usage_months_paying_scope_chk", + "value": "\"paying_scope\" IN ('instance', 'account', 'user')" + } + }, + "isRLSEnabled": false + }, + "public.ai_usage_windows": { + "name": "ai_usage_windows", + "schema": "", + "columns": { + "bucket": { + "name": "bucket", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "window_kind": { + "name": "window_kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "window_start": { + "name": "window_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "tokens": { + "name": "tokens", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "calls": { + "name": "calls", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "ai_usage_windows_start_idx": { + "name": "ai_usage_windows_start_idx", + "columns": [ + { + "expression": "window_kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "window_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "ai_usage_windows_pk": { + "name": "ai_usage_windows_pk", + "columns": [ + "bucket", + "window_kind", + "window_start" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "ai_usage_windows_window_kind_chk": { + "name": "ai_usage_windows_window_kind_chk", + "value": "\"window_kind\" IN ('minute', 'day', 'month')" + } + }, + "isRLSEnabled": false + }, + "public.llm_calls": { + "name": "llm_calls", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "uuidv7()" + }, + "at": { + "name": "at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "date_trunc('milliseconds', now())" + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempt": { + "name": "attempt", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "task": { + "name": "task", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "budget_task": { + "name": "budget_task", + "type": "text", + "primaryKey": false, + "notNull": false, + "generated": { + "type": "stored", + "as": "CASE WHEN task LIKE 'extract\\_%' OR task = 'enrich_aliases' THEN 'extraction'\n WHEN task LIKE 'assistant\\_%' THEN 'assistant'\n WHEN task LIKE 'embed\\_%' THEN 'embeddings' ELSE 'test' END" + } + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "paying_scope": { + "name": "paying_scope", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "paying_account_id": { + "name": "paying_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "paying_user_id": { + "name": "paying_user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "fell_back": { + "name": "fell_back", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "provider_id": { + "name": "provider_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "provider_kind": { + "name": "provider_kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reasoning": { + "name": "reasoning", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prompt_version": { + "name": "prompt_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent": { + "name": "sent", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "estimate_tokens": { + "name": "estimate_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "input_tokens": { + "name": "input_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "output_tokens": { + "name": "output_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reasoning_tokens": { + "name": "reasoning_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "cached_input_tokens": { + "name": "cached_input_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "usage_estimated": { + "name": "usage_estimated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image_count": { + "name": "image_count", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "image_tokens_each": { + "name": "image_tokens_each", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "image_bytes": { + "name": "image_bytes", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "attachment_ids": { + "name": "attachment_ids", + "type": "uuid[]", + "primaryKey": false, + "notNull": false + }, + "latency_ms": { + "name": "latency_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "finish_reason": { + "name": "finish_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "outcome": { + "name": "outcome", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "error_code": { + "name": "error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "http_status": { + "name": "http_status", + "type": "smallint", + "primaryKey": false, + "notNull": false + }, + "cost_amount": { + "name": "cost_amount", + "type": "numeric(16, 6)", + "primaryKey": false, + "notNull": false + }, + "cost_currency": { + "name": "cost_currency", + "type": "char(3)", + "primaryKey": false, + "notNull": false + }, + "cost_source": { + "name": "cost_source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "price_id": { + "name": "price_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "extraction_id": { + "name": "extraction_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "thread_id": { + "name": "thread_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "rl_remaining_tokens": { + "name": "rl_remaining_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rl_reset_at": { + "name": "rl_reset_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "llm_calls_user_idx": { + "name": "llm_calls_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "llm_calls_location_idx": { + "name": "llm_calls_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "llm_calls_owner_idx": { + "name": "llm_calls_owner_idx", + "columns": [ + { + "expression": "owner_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "llm_calls_payer_idx": { + "name": "llm_calls_payer_idx", + "columns": [ + { + "expression": "paying_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "llm_calls_instance_idx": { + "name": "llm_calls_instance_idx", + "columns": [ + { + "expression": "at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "paying_scope = 'instance'", + "concurrently": false + }, + "llm_calls_thing_idx": { + "name": "llm_calls_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "thing_id IS NOT NULL", + "concurrently": false + }, + "llm_calls_extraction_idx": { + "name": "llm_calls_extraction_idx", + "columns": [ + { + "expression": "extraction_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "extraction_id IS NOT NULL", + "concurrently": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "llm_calls_pk": { + "name": "llm_calls_pk", + "columns": [ + "id", + "at" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "llm_calls_task_chk": { + "name": "llm_calls_task_chk", + "value": "\"task\" IN ('extract_thing', 'extract_receipt', 'extract_label', 'extract_reading', 'assistant_turn', 'assistant_followup', 'embed_thing', 'embed_query', 'connection_test', 'enrich_aliases', 'extract_room', 'extract_room_merge', 'extract_plan')" + }, + "llm_calls_outcome_chk": { + "name": "llm_calls_outcome_chk", + "value": "\"outcome\" IN ('ok', 'refused', 'rate_limited', 'over_budget', 'provider_error', 'timeout', 'schema_invalid', 'truncated')" + }, + "llm_calls_cost_source_chk": { + "name": "llm_calls_cost_source_chk", + "value": "\"cost_source\" IN ('provider', 'price_table', 'price_table_later', 'unknown', 'not_sent')" + }, + "llm_calls_paying_scope_chk": { + "name": "llm_calls_paying_scope_chk", + "value": "\"paying_scope\" IN ('instance', 'account', 'user')" + }, + "llm_calls_request_id_chk": { + "name": "llm_calls_request_id_chk", + "value": "char_length(request_id) <= 64" + }, + "llm_calls_attempt_chk": { + "name": "llm_calls_attempt_chk", + "value": "attempt BETWEEN 1 AND 20" + }, + "llm_calls_prompt_version_chk": { + "name": "llm_calls_prompt_version_chk", + "value": "char_length(prompt_version) <= 20" + }, + "llm_calls_image_count_chk": { + "name": "llm_calls_image_count_chk", + "value": "image_count >= 0" + }, + "llm_calls_finish_reason_chk": { + "name": "llm_calls_finish_reason_chk", + "value": "char_length(finish_reason) <= 40" + }, + "llm_calls_error_code_chk": { + "name": "llm_calls_error_code_chk", + "value": "error_code ~ '^[a-z0-9_]{1,40}$'" + }, + "llm_calls_cost_pair_chk": { + "name": "llm_calls_cost_pair_chk", + "value": "(cost_amount IS NULL) = (cost_currency IS NULL)" + }, + "llm_calls_not_sent_chk": { + "name": "llm_calls_not_sent_chk", + "value": "sent OR (input_tokens IS NULL AND output_tokens IS NULL AND cost_amount IS NULL)" + }, + "llm_calls_sent_source_chk": { + "name": "llm_calls_sent_source_chk", + "value": "sent = (cost_source <> 'not_sent')" + }, + "llm_calls_price_chk": { + "name": "llm_calls_price_chk", + "value": "cost_source NOT IN ('price_table', 'price_table_later') OR price_id IS NOT NULL" + }, + "llm_calls_payer_chk": { + "name": "llm_calls_payer_chk", + "value": "CASE paying_scope\n WHEN 'instance' THEN paying_account_id IS NULL AND paying_user_id IS NULL\n WHEN 'account' THEN paying_account_id IS NOT NULL AND paying_user_id IS NULL\n ELSE paying_user_id IS NOT NULL AND paying_account_id IS NULL END" + } + }, + "isRLSEnabled": false + }, + "public.admin_alerts": { + "name": "admin_alerts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "first_at": { + "name": "first_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_at": { + "name": "last_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "mailed_at": { + "name": "mailed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "admin_alerts_dedupe_key_unique": { + "name": "admin_alerts_dedupe_key_unique", + "columns": [ + "dedupe_key" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "admin_alerts_kind_chk": { + "name": "admin_alerts_kind_chk", + "value": "\"kind\" IN ('failed_jobs_rising', 'audit_default_partition', 'llm_default_partition', 'ai_instance_cap_warning', 'ai_instance_cap_reached', 'ai_instance_key_rejected', 'backup_failed', 'reminders_not_scanned', 'backup_stale', 'disk_space_low', 'bucket_versioning_off', 'restore_drill_due', 'backup_suspicious_size', 'backup_verify_failed', 'webhook_failing')" + }, + "admin_alerts_count_chk": { + "name": "admin_alerts_count_chk", + "value": "count >= 1" + }, + "admin_alerts_seen_chk": { + "name": "admin_alerts_seen_chk", + "value": "last_at >= first_at" + } + }, + "isRLSEnabled": false + }, + "public.assistant_messages": { + "name": "assistant_messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "thread_id": { + "name": "thread_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "turn_id": { + "name": "turn_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "step": { + "name": "step", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "parts": { + "name": "parts", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "cited_location_ids": { + "name": "cited_location_ids", + "type": "uuid[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::uuid[]" + }, + "redacted_at": { + "name": "redacted_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": { + "assistant_messages_thread_idx": { + "name": "assistant_messages_thread_idx", + "columns": [ + { + "expression": "thread_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, + "with": {}, + "method": "btree", + "concurrently": false + }, + "assistant_messages_turn_idx": { + "name": "assistant_messages_turn_idx", + "columns": [ + { + "expression": "turn_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "assistant_messages_thread_fk": { + "name": "assistant_messages_thread_fk", + "tableFrom": "assistant_messages", + "columnsFrom": [ + "user_id", + "thread_id" + ], + "tableTo": "assistant_threads", + "columnsTo": [ + "user_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "assistant_messages_turn_fk": { + "name": "assistant_messages_turn_fk", + "tableFrom": "assistant_messages", + "columnsFrom": [ + "user_id", + "turn_id" + ], + "tableTo": "assistant_turns", + "columnsTo": [ + "user_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "assistant_messages_user_id_uq": { + "name": "assistant_messages_user_id_uq", + "columns": [ + "user_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "assistant_messages_role_chk": { + "name": "assistant_messages_role_chk", + "value": "\"role\" IN ('user', 'assistant', 'tool')" + }, + "assistant_messages_parts_chk": { + "name": "assistant_messages_parts_chk", + "value": "jsonb_typeof(parts) = 'array'" + }, + "assistant_messages_step_chk": { + "name": "assistant_messages_step_chk", + "value": "step BETWEEN 0 AND 20" + } + }, + "isRLSEnabled": false + }, + "public.assistant_proposals": { + "name": "assistant_proposals", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thread_id": { + "name": "thread_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "turn_id": { + "name": "turn_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "batch_id": { + "name": "batch_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "tool": { + "name": "tool", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "args": { + "name": "args", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "args_hash": { + "name": "args_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "before": { + "name": "before", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "refs": { + "name": "refs", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'open'" + }, + "result": { + "name": "result", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "audit_event_id": { + "name": "audit_event_id", + "type": "uuid", + "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()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "assistant_proposals_thread_idx": { + "name": "assistant_proposals_thread_idx", + "columns": [ + { + "expression": "thread_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "assistant_proposals_turn_idx": { + "name": "assistant_proposals_turn_idx", + "columns": [ + { + "expression": "turn_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "assistant_proposals_open_idx": { + "name": "assistant_proposals_open_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "status = 'open'", + "concurrently": false + }, + "assistant_proposals_location_idx": { + "name": "assistant_proposals_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "assistant_proposals_location_id_locations_id_fk": { + "name": "assistant_proposals_location_id_locations_id_fk", + "tableFrom": "assistant_proposals", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "assistant_proposals_thread_fk": { + "name": "assistant_proposals_thread_fk", + "tableFrom": "assistant_proposals", + "columnsFrom": [ + "user_id", + "thread_id" + ], + "tableTo": "assistant_threads", + "columnsTo": [ + "user_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "assistant_proposals_turn_fk": { + "name": "assistant_proposals_turn_fk", + "tableFrom": "assistant_proposals", + "columnsFrom": [ + "user_id", + "turn_id" + ], + "tableTo": "assistant_turns", + "columnsTo": [ + "user_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "assistant_proposals_status_chk": { + "name": "assistant_proposals_status_chk", + "value": "\"status\" IN ('open', 'confirmed', 'cancelled', 'expired', 'conflict', 'failed')" + }, + "assistant_proposals_tool_chk": { + "name": "assistant_proposals_tool_chk", + "value": "tool ~ '^[a-z][a-z0-9_]{0,63}$'" + }, + "assistant_proposals_args_chk": { + "name": "assistant_proposals_args_chk", + "value": "jsonb_typeof(args) = 'object'" + }, + "assistant_proposals_args_hash_chk": { + "name": "assistant_proposals_args_hash_chk", + "value": "args_hash ~ '^[0-9a-f]{64}$'" + }, + "assistant_proposals_objects_chk": { + "name": "assistant_proposals_objects_chk", + "value": "jsonb_typeof(before) = 'object' AND jsonb_typeof(refs) = 'object'" + } + }, + "isRLSEnabled": false + }, + "public.assistant_threads": { + "name": "assistant_threads", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "context": { + "name": "context", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "locale": { + "name": "locale", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "search_tsv": { + "name": "search_tsv", + "type": "tsvector", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now() + interval '90 days'" + }, + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "assistant_threads_user_idx": { + "name": "assistant_threads_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "updated_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "assistant_threads_tsv_idx": { + "name": "assistant_threads_tsv_idx", + "columns": [ + { + "expression": "search_tsv", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "gin", + "concurrently": false + }, + "assistant_threads_expiry_idx": { + "name": "assistant_threads_expiry_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "assistant_threads_user_id_user_id_fk": { + "name": "assistant_threads_user_id_user_id_fk", + "tableFrom": "assistant_threads", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "assistant_threads_user_id_uq": { + "name": "assistant_threads_user_id_uq", + "columns": [ + "user_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "assistant_threads_title_chk": { + "name": "assistant_threads_title_chk", + "value": "char_length(title) <= 120" + }, + "assistant_threads_context_chk": { + "name": "assistant_threads_context_chk", + "value": "jsonb_typeof(context) = 'object'" + }, + "assistant_threads_locale_chk": { + "name": "assistant_threads_locale_chk", + "value": "char_length(locale) BETWEEN 1 AND 20" + } + }, + "isRLSEnabled": false + }, + "public.assistant_tool_results": { + "name": "assistant_tool_results", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "message_id": { + "name": "message_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "call_id": { + "name": "call_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tool": { + "name": "tool", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "output": { + "name": "output", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "redacted_at": { + "name": "redacted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "assistant_tool_results_message_idx": { + "name": "assistant_tool_results_message_idx", + "columns": [ + { + "expression": "message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "assistant_tool_results_redact_idx": { + "name": "assistant_tool_results_redact_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "redacted_at IS NULL", + "concurrently": false + } + }, + "foreignKeys": { + "assistant_tool_results_message_fk": { + "name": "assistant_tool_results_message_fk", + "tableFrom": "assistant_tool_results", + "columnsFrom": [ + "user_id", + "message_id" + ], + "tableTo": "assistant_messages", + "columnsTo": [ + "user_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "assistant_tool_results_call_id_chk": { + "name": "assistant_tool_results_call_id_chk", + "value": "char_length(call_id) BETWEEN 1 AND 100" + }, + "assistant_tool_results_tool_chk": { + "name": "assistant_tool_results_tool_chk", + "value": "tool ~ '^[a-z][a-z0-9_]{0,63}$'" + }, + "assistant_tool_results_redacted_chk": { + "name": "assistant_tool_results_redacted_chk", + "value": "(output IS NULL) = (redacted_at IS NOT NULL)" + } + }, + "isRLSEnabled": false + }, + "public.assistant_turns": { + "name": "assistant_turns", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "thread_id": { + "name": "thread_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "status_reason": { + "name": "status_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "paused_until": { + "name": "paused_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "steps": { + "name": "steps", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "location_ids": { + "name": "location_ids", + "type": "uuid[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::uuid[]" + }, + "finished_at": { + "name": "finished_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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "assistant_turns_one_live_uq": { + "name": "assistant_turns_one_live_uq", + "columns": [ + { + "expression": "thread_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "status IN ('queued', 'running', 'waiting_provider')", + "concurrently": false + }, + "assistant_turns_thread_idx": { + "name": "assistant_turns_thread_idx", + "columns": [ + { + "expression": "thread_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "assistant_turns_thread_fk": { + "name": "assistant_turns_thread_fk", + "tableFrom": "assistant_turns", + "columnsFrom": [ + "user_id", + "thread_id" + ], + "tableTo": "assistant_threads", + "columnsTo": [ + "user_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "assistant_turns_user_id_uq": { + "name": "assistant_turns_user_id_uq", + "columns": [ + "user_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "assistant_turns_status_chk": { + "name": "assistant_turns_status_chk", + "value": "\"status\" IN ('queued', 'running', 'waiting_provider', 'paused_budget', 'done', 'failed', 'cancelled')" + }, + "assistant_turns_status_reason_chk": { + "name": "assistant_turns_status_reason_chk", + "value": "char_length(status_reason) <= 60" + }, + "assistant_turns_steps_chk": { + "name": "assistant_turns_steps_chk", + "value": "steps BETWEEN 0 AND 20" + } + }, + "isRLSEnabled": false + }, + "public.audit_event_subjects": { + "name": "audit_event_subjects", + "schema": "", + "columns": { + "event_id": { + "name": "event_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_at": { + "name": "event_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "audit_event_subjects_thing_idx": { + "name": "audit_event_subjects_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "audit_event_subjects_event_fk": { + "name": "audit_event_subjects_event_fk", + "tableFrom": "audit_event_subjects", + "columnsFrom": [ + "event_id", + "event_at", + "location_id" + ], + "tableTo": "audit_events", + "columnsTo": [ + "id", + "at", + "location_id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "audit_event_subjects_event_id_event_at_thing_id_pk": { + "name": "audit_event_subjects_event_id_event_at_thing_id_pk", + "columns": [ + "event_id", + "event_at", + "thing_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audit_events": { + "name": "audit_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": false, + "notNull": true, + "default": "uuidv7()" + }, + "at": { + "name": "at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "date_trunc('milliseconds', now())" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "actor_type": { + "name": "actor_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entity_id": { + "name": "entity_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "root_thing_id": { + "name": "root_thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "diff": { + "name": "diff", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "undo_of": { + "name": "undo_of", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "undoable_until": { + "name": "undoable_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "audit_events_entity_idx": { + "name": "audit_events_entity_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "entity_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "audit_events_location_at_idx": { + "name": "audit_events_location_at_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "audit_events_actor_idx": { + "name": "audit_events_actor_idx", + "columns": [ + { + "expression": "actor_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "actor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "audit_events_root_thing_idx": { + "name": "audit_events_root_thing_idx", + "columns": [ + { + "expression": "root_thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "root_thing_id IS NOT NULL", + "concurrently": false + }, + "audit_events_account_at_idx": { + "name": "audit_events_account_at_idx", + "columns": [ + { + "expression": "owner_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "location_id IS NULL", + "concurrently": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "audit_events_id_at_pk": { + "name": "audit_events_id_at_pk", + "columns": [ + "id", + "at" + ] + } + }, + "uniqueConstraints": { + "audit_events_id_at_location_uq": { + "name": "audit_events_id_at_location_uq", + "columns": [ + "id", + "at", + "location_id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "audit_events_actor_type_chk": { + "name": "audit_events_actor_type_chk", + "value": "\"actor_type\" IN ('user', 'token', 'system', 'import')" + } + }, + "isRLSEnabled": false + }, + "auth.account": { + "name": "account", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "password": { + "name": "password", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "account_userId_idx": { + "name": "account_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.jwks": { + "name": "jwks", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "private_key": { + "name": "private_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "alg": { + "name": "alg", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "crv": { + "name": "crv", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.oauth_access_token": { + "name": "oauth_access_token", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "authorization_code_id": { + "name": "authorization_code_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "resources": { + "name": "resources", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "requested_user_info_claims": { + "name": "requested_user_info_claims", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "refresh_id": { + "name": "refresh_id", + "type": "uuid", + "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 + }, + "revoked": { + "name": "revoked", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "confirmation": { + "name": "confirmation", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "oauthAccessToken_clientId_idx": { + "name": "oauthAccessToken_clientId_idx", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "oauthAccessToken_sessionId_idx": { + "name": "oauthAccessToken_sessionId_idx", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "oauthAccessToken_userId_idx": { + "name": "oauthAccessToken_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "oauthAccessToken_authorizationCodeId_idx": { + "name": "oauthAccessToken_authorizationCodeId_idx", + "columns": [ + { + "expression": "authorization_code_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "oauthAccessToken_refreshId_idx": { + "name": "oauthAccessToken_refreshId_idx", + "columns": [ + { + "expression": "refresh_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "oauth_access_token_client_id_oauth_client_client_id_fk": { + "name": "oauth_access_token_client_id_oauth_client_client_id_fk", + "tableFrom": "oauth_access_token", + "columnsFrom": [ + "client_id" + ], + "tableTo": "oauth_client", + "schemaTo": "auth", + "columnsTo": [ + "client_id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "oauth_access_token_session_id_session_id_fk": { + "name": "oauth_access_token_session_id_session_id_fk", + "tableFrom": "oauth_access_token", + "columnsFrom": [ + "session_id" + ], + "tableTo": "session", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "oauth_access_token_user_id_user_id_fk": { + "name": "oauth_access_token_user_id_user_id_fk", + "tableFrom": "oauth_access_token", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "oauth_access_token_refresh_id_oauth_refresh_token_id_fk": { + "name": "oauth_access_token_refresh_id_oauth_refresh_token_id_fk", + "tableFrom": "oauth_access_token", + "columnsFrom": [ + "refresh_id" + ], + "tableTo": "oauth_refresh_token", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "oauth_access_token_token_unique": { + "name": "oauth_access_token_token_unique", + "columns": [ + "token" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.oauth_client": { + "name": "oauth_client", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_secret": { + "name": "client_secret", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_discovery_id": { + "name": "client_discovery_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "disabled": { + "name": "disabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "skip_consent": { + "name": "skip_consent", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "enable_end_session": { + "name": "enable_end_session", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "subject_type": { + "name": "subject_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "client_credentials_scopes": { + "name": "client_credentials_scopes", + "type": "text[]", + "primaryKey": false, + "notNull": false, + "default": "'{}'" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uri": { + "name": "uri", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contacts": { + "name": "contacts", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "tos": { + "name": "tos", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "policy": { + "name": "policy", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "software_id": { + "name": "software_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "software_version": { + "name": "software_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "software_statement": { + "name": "software_statement", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "redirect_uris": { + "name": "redirect_uris", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "post_logout_redirect_uris": { + "name": "post_logout_redirect_uris", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "backchannel_logout_uri": { + "name": "backchannel_logout_uri", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "backchannel_logout_session_required": { + "name": "backchannel_logout_session_required", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "token_endpoint_auth_method": { + "name": "token_endpoint_auth_method", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "application_type": { + "name": "application_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "jwks": { + "name": "jwks", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "jwks_uri": { + "name": "jwks_uri", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "grant_types": { + "name": "grant_types", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "response_types": { + "name": "response_types", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "require_pkce": { + "name": "require_pkce", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "dpop_bound_access_tokens": { + "name": "dpop_bound_access_tokens", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "oauthClient_userId_idx": { + "name": "oauthClient_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "oauth_client_user_id_user_id_fk": { + "name": "oauth_client_user_id_user_id_fk", + "tableFrom": "oauth_client", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "oauth_client_client_id_unique": { + "name": "oauth_client_client_id_unique", + "columns": [ + "client_id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.oauth_client_assertion": { + "name": "oauth_client_assertion", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.oauth_client_resource": { + "name": "oauth_client_resource", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "resource_id": { + "name": "resource_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "oauthClientResource_clientId_resourceId_uidx": { + "name": "oauthClientResource_clientId_resourceId_uidx", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "resource_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "concurrently": false + }, + "oauthClientResource_clientId_idx": { + "name": "oauthClientResource_clientId_idx", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "oauthClientResource_resourceId_idx": { + "name": "oauthClientResource_resourceId_idx", + "columns": [ + { + "expression": "resource_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "oauth_client_resource_client_id_oauth_client_client_id_fk": { + "name": "oauth_client_resource_client_id_oauth_client_client_id_fk", + "tableFrom": "oauth_client_resource", + "columnsFrom": [ + "client_id" + ], + "tableTo": "oauth_client", + "schemaTo": "auth", + "columnsTo": [ + "client_id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "oauth_client_resource_resource_id_oauth_resource_identifier_fk": { + "name": "oauth_client_resource_resource_id_oauth_resource_identifier_fk", + "tableFrom": "oauth_client_resource", + "columnsFrom": [ + "resource_id" + ], + "tableTo": "oauth_resource", + "schemaTo": "auth", + "columnsTo": [ + "identifier" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.oauth_consent": { + "name": "oauth_consent", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "resources": { + "name": "resources", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "requested_user_info_claims": { + "name": "requested_user_info_claims", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "oauthConsent_clientId_idx": { + "name": "oauthConsent_clientId_idx", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "oauthConsent_userId_idx": { + "name": "oauthConsent_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "oauth_consent_client_id_oauth_client_client_id_fk": { + "name": "oauth_consent_client_id_oauth_client_client_id_fk", + "tableFrom": "oauth_consent", + "columnsFrom": [ + "client_id" + ], + "tableTo": "oauth_client", + "schemaTo": "auth", + "columnsTo": [ + "client_id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "oauth_consent_user_id_user_id_fk": { + "name": "oauth_consent_user_id_user_id_fk", + "tableFrom": "oauth_consent", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.oauth_refresh_token": { + "name": "oauth_refresh_token", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "authorization_code_id": { + "name": "authorization_code_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "resources": { + "name": "resources", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "requested_user_info_claims": { + "name": "requested_user_info_claims", + "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 + }, + "revoked": { + "name": "revoked", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "rotated_at": { + "name": "rotated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "rotation_replay_response": { + "name": "rotation_replay_response", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rotation_replay_expires_at": { + "name": "rotation_replay_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "auth_time": { + "name": "auth_time", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "confirmation": { + "name": "confirmation", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "scopes": { + "name": "scopes", + "type": "text[]", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "oauthRefreshToken_clientId_idx": { + "name": "oauthRefreshToken_clientId_idx", + "columns": [ + { + "expression": "client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "oauthRefreshToken_sessionId_idx": { + "name": "oauthRefreshToken_sessionId_idx", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "oauthRefreshToken_userId_idx": { + "name": "oauthRefreshToken_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "oauthRefreshToken_authorizationCodeId_idx": { + "name": "oauthRefreshToken_authorizationCodeId_idx", + "columns": [ + { + "expression": "authorization_code_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "oauth_refresh_token_client_id_oauth_client_client_id_fk": { + "name": "oauth_refresh_token_client_id_oauth_client_client_id_fk", + "tableFrom": "oauth_refresh_token", + "columnsFrom": [ + "client_id" + ], + "tableTo": "oauth_client", + "schemaTo": "auth", + "columnsTo": [ + "client_id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "oauth_refresh_token_session_id_session_id_fk": { + "name": "oauth_refresh_token_session_id_session_id_fk", + "tableFrom": "oauth_refresh_token", + "columnsFrom": [ + "session_id" + ], + "tableTo": "session", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "oauth_refresh_token_user_id_user_id_fk": { + "name": "oauth_refresh_token_user_id_user_id_fk", + "tableFrom": "oauth_refresh_token", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "oauth_refresh_token_token_unique": { + "name": "oauth_refresh_token_token_unique", + "columns": [ + "token" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.oauth_resource": { + "name": "oauth_resource", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token_ttl": { + "name": "access_token_ttl", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refresh_token_ttl": { + "name": "refresh_token_ttl", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "signing_algorithm": { + "name": "signing_algorithm", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signing_key_id": { + "name": "signing_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "allowed_scopes": { + "name": "allowed_scopes", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "custom_claims": { + "name": "custom_claims", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "dpop_bound_access_tokens_required": { + "name": "dpop_bound_access_tokens_required", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "disabled": { + "name": "disabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "policy_version": { + "name": "policy_version", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 1 + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "oauth_resource_identifier_unique": { + "name": "oauth_resource_identifier_unique", + "columns": [ + "identifier" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.passkey": { + "name": "passkey", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "public_key": { + "name": "public_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "credential_id": { + "name": "credential_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "counter": { + "name": "counter", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "device_type": { + "name": "device_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "backed_up": { + "name": "backed_up", + "type": "boolean", + "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": false + }, + "aaguid": { + "name": "aaguid", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "passkey_userId_idx": { + "name": "passkey_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "passkey_credentialID_idx": { + "name": "passkey_credentialID_idx", + "columns": [ + { + "expression": "credential_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "passkey_user_id_user_id_fk": { + "name": "passkey_user_id_user_id_fk", + "tableFrom": "passkey", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.rate_limit": { + "name": "rate_limit", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "last_request": { + "name": "last_request", + "type": "bigint", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "rate_limit_key_unique": { + "name": "rate_limit_key_unique", + "columns": [ + "key" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.session": { + "name": "session", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "ip_address": { + "name": "ip_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "session_userId_idx": { + "name": "session_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_token_unique": { + "name": "session_token_unique", + "columns": [ + "token" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.session_mfa": { + "name": "session_mfa", + "schema": "auth", + "columns": { + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "satisfied_at": { + "name": "satisfied_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "session_mfa_session_id_session_id_fk": { + "name": "session_mfa_session_id_session_id_fk", + "tableFrom": "session_mfa", + "columnsFrom": [ + "session_id" + ], + "tableTo": "session", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.sign_in_failures": { + "name": "sign_in_failures", + "schema": "auth", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "window_start": { + "name": "window_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "last_failure_at": { + "name": "last_failure_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.two_factor": { + "name": "two_factor", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "secret": { + "name": "secret", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "backup_codes": { + "name": "backup_codes", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "verified": { + "name": "verified", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "failed_verification_count": { + "name": "failed_verification_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "locked_until": { + "name": "locked_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "twoFactor_secret_idx": { + "name": "twoFactor_secret_idx", + "columns": [ + { + "expression": "secret", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "twoFactor_userId_idx": { + "name": "twoFactor_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "two_factor_user_id_user_id_fk": { + "name": "two_factor_user_id_user_id_fk", + "tableFrom": "two_factor", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.user": { + "name": "user", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "two_factor_enabled": { + "name": "two_factor_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_username": { + "name": "display_username", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "banned": { + "name": "banned", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "ban_reason": { + "name": "ban_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ban_expires": { + "name": "ban_expires", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "columns": [ + "email" + ], + "nullsNotDistinct": false + }, + "user_username_unique": { + "name": "user_username_unique", + "columns": [ + "username" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.user_deletion": { + "name": "user_deletion", + "schema": "auth", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "requested_at": { + "name": "requested_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "purge_after": { + "name": "purge_after", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_deletion_user_id_user_id_fk": { + "name": "user_deletion_user_id_user_id_fk", + "tableFrom": "user_deletion", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "auth.verification": { + "name": "verification", + "schema": "auth", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()::text" + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "verification_identifier_idx": { + "name": "verification_identifier_idx", + "columns": [ + { + "expression": "identifier", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.extractions": { + "name": "extractions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "attachment_id": { + "name": "attachment_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "purchase_id": { + "name": "purchase_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "meter_id": { + "name": "meter_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "service_record_id": { + "name": "service_record_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "room_capture_id": { + "name": "room_capture_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "floor_plan_id": { + "name": "floor_plan_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempt": { + "name": "attempt", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "status_reason": { + "name": "status_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "paused_until": { + "name": "paused_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "llm_call_id": { + "name": "llm_call_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "output_cap": { + "name": "output_cap", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "result": { + "name": "result", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "applied": { + "name": "applied", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "requested_by": { + "name": "requested_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "extractions_room_capture_idx": { + "name": "extractions_room_capture_idx", + "columns": [ + { + "expression": "room_capture_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "room_capture_id IS NOT NULL", + "concurrently": false + }, + "extractions_floor_plan_idx": { + "name": "extractions_floor_plan_idx", + "columns": [ + { + "expression": "floor_plan_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "floor_plan_id IS NOT NULL", + "concurrently": false + }, + "extractions_live_uq": { + "name": "extractions_live_uq", + "columns": [ + { + "expression": "attachment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "status IN ('queued', 'running', 'paused_budget', 'waiting_provider')", + "concurrently": false + }, + "extractions_thing_idx": { + "name": "extractions_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "thing_id IS NOT NULL", + "concurrently": false + }, + "extractions_purchase_idx": { + "name": "extractions_purchase_idx", + "columns": [ + { + "expression": "purchase_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "purchase_id IS NOT NULL", + "concurrently": false + }, + "extractions_service_record_idx": { + "name": "extractions_service_record_idx", + "columns": [ + { + "expression": "service_record_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "service_record_id IS NOT NULL", + "concurrently": false + }, + "extractions_paused_idx": { + "name": "extractions_paused_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "status = 'paused_budget'", + "concurrently": false + } + }, + "foreignKeys": { + "extractions_location_id_locations_id_fk": { + "name": "extractions_location_id_locations_id_fk", + "tableFrom": "extractions", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "extractions_attachment_fk": { + "name": "extractions_attachment_fk", + "tableFrom": "extractions", + "columnsFrom": [ + "location_id", + "attachment_id" + ], + "tableTo": "attachments", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "extractions_thing_fk": { + "name": "extractions_thing_fk", + "tableFrom": "extractions", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "extractions_purchase_fk": { + "name": "extractions_purchase_fk", + "tableFrom": "extractions", + "columnsFrom": [ + "location_id", + "purchase_id" + ], + "tableTo": "purchases", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "extractions_meter_fk": { + "name": "extractions_meter_fk", + "tableFrom": "extractions", + "columnsFrom": [ + "location_id", + "meter_id" + ], + "tableTo": "meters", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "extractions_service_record_fk": { + "name": "extractions_service_record_fk", + "tableFrom": "extractions", + "columnsFrom": [ + "location_id", + "service_record_id" + ], + "tableTo": "service_records", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "extractions_room_capture_fk": { + "name": "extractions_room_capture_fk", + "tableFrom": "extractions", + "columnsFrom": [ + "location_id", + "room_capture_id" + ], + "tableTo": "room_captures", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "extractions_floor_plan_fk": { + "name": "extractions_floor_plan_fk", + "tableFrom": "extractions", + "columnsFrom": [ + "location_id", + "floor_plan_id" + ], + "tableTo": "floor_plans", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "extractions_location_id_uq": { + "name": "extractions_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + }, + "extractions_attempt_uq": { + "name": "extractions_attempt_uq", + "columns": [ + "attachment_id", + "attempt" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "extractions_mode_chk": { + "name": "extractions_mode_chk", + "value": "\"mode\" IN ('thing', 'receipt', 'label', 'reading', 'room', 'plan')" + }, + "extractions_status_chk": { + "name": "extractions_status_chk", + "value": "\"status\" IN ('queued', 'running', 'succeeded', 'failed', 'paused_budget', 'waiting_provider', 'no_provider', 'superseded')" + }, + "extractions_attempt_chk": { + "name": "extractions_attempt_chk", + "value": "attempt BETWEEN 1 AND 50" + }, + "extractions_status_reason_chk": { + "name": "extractions_status_reason_chk", + "value": "char_length(status_reason) <= 60" + }, + "extractions_output_cap_chk": { + "name": "extractions_output_cap_chk", + "value": "output_cap BETWEEN 64 AND 200000" + }, + "extractions_one_draft_chk": { + "name": "extractions_one_draft_chk", + "value": "num_nonnulls(thing_id, purchase_id, meter_id, service_record_id) <= 1" + }, + "extractions_result_chk": { + "name": "extractions_result_chk", + "value": "result IS NULL OR jsonb_typeof(result) = 'object'" + }, + "extractions_applied_chk": { + "name": "extractions_applied_chk", + "value": "jsonb_typeof(applied) = 'object'" + } + }, + "isRLSEnabled": false + }, + "public.file_text": { + "name": "file_text", + "schema": "", + "columns": { + "file_id": { + "name": "file_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tsv": { + "name": "tsv", + "type": "tsvector", + "primaryKey": false, + "notNull": false, + "generated": { + "type": "stored", + "as": "to_tsvector('simple', kept.search_text(left(text, 100000)))" + } + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "file_text_tsv_idx": { + "name": "file_text_tsv_idx", + "columns": [ + { + "expression": "tsv", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "gin", + "concurrently": false + }, + "file_text_location_idx": { + "name": "file_text_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "file_text_file_fk": { + "name": "file_text_file_fk", + "tableFrom": "file_text", + "columnsFrom": [ + "location_id", + "file_id" + ], + "tableTo": "files", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "file_text_source_chk": { + "name": "file_text_source_chk", + "value": "\"source\" IN ('pdf', 'extraction')" + }, + "file_text_text_chk": { + "name": "file_text_text_chk", + "value": "char_length(text) <= 200000" + } + }, + "isRLSEnabled": false + }, + "public.inbox_items": { + "name": "inbox_items", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "purchase_id": { + "name": "purchase_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "meter_reading_id": { + "name": "meter_reading_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "extraction_id": { + "name": "extraction_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "other_thing_id": { + "name": "other_thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "room_capture_id": { + "name": "room_capture_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "code": { + "name": "code", + "type": "char(6)", + "primaryKey": false, + "notNull": false + }, + "batch_id": { + "name": "batch_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "resolved_by": { + "name": "resolved_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "resolution": { + "name": "resolution", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "inbox_open_subject_uq": { + "name": "inbox_open_subject_uq", + "columns": [ + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(thing_id, purchase_id, meter_reading_id)", + "isExpression": true, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(other_thing_id, '00000000-0000-0000-0000-000000000000'::uuid)", + "isExpression": true, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(code, '')", + "isExpression": true, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "resolved_at IS NULL", + "concurrently": false + }, + "inbox_open_loc_idx": { + "name": "inbox_open_loc_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "resolved_at IS NULL", + "concurrently": false + }, + "inbox_open_mine_idx": { + "name": "inbox_open_mine_idx", + "columns": [ + { + "expression": "created_by", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "resolved_at IS NULL", + "concurrently": false + }, + "inbox_resolved_idx": { + "name": "inbox_resolved_idx", + "columns": [ + { + "expression": "resolved_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "resolved_at IS NOT NULL", + "concurrently": false + }, + "inbox_items_thing_idx": { + "name": "inbox_items_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "thing_id IS NOT NULL", + "concurrently": false + } + }, + "foreignKeys": { + "inbox_items_location_id_locations_id_fk": { + "name": "inbox_items_location_id_locations_id_fk", + "tableFrom": "inbox_items", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "inbox_items_thing_fk": { + "name": "inbox_items_thing_fk", + "tableFrom": "inbox_items", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "inbox_items_purchase_fk": { + "name": "inbox_items_purchase_fk", + "tableFrom": "inbox_items", + "columnsFrom": [ + "location_id", + "purchase_id" + ], + "tableTo": "purchases", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "inbox_items_meter_reading_fk": { + "name": "inbox_items_meter_reading_fk", + "tableFrom": "inbox_items", + "columnsFrom": [ + "location_id", + "meter_reading_id" + ], + "tableTo": "meter_readings", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "inbox_items_extraction_fk": { + "name": "inbox_items_extraction_fk", + "tableFrom": "inbox_items", + "columnsFrom": [ + "location_id", + "extraction_id" + ], + "tableTo": "extractions", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "inbox_items_room_capture_fk": { + "name": "inbox_items_room_capture_fk", + "tableFrom": "inbox_items", + "columnsFrom": [ + "location_id", + "room_capture_id" + ], + "tableTo": "room_captures", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "inbox_items_other_thing_fk": { + "name": "inbox_items_other_thing_fk", + "tableFrom": "inbox_items", + "columnsFrom": [ + "location_id", + "other_thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "inbox_items_location_id_uq": { + "name": "inbox_items_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "inbox_items_kind_chk": { + "name": "inbox_items_kind_chk", + "value": "\"kind\" IN ('draft', 'reading', 'label_claim', 'currency', 'duplicate', 'receipt', 'sync_drop', 'room')" + }, + "inbox_items_resolution_chk": { + "name": "inbox_items_resolution_chk", + "value": "\"resolution\" IN ('accepted', 'edited', 'discarded', 'merged', 'linked', 'restored', 'dismissed')" + }, + "inbox_items_code_chk": { + "name": "inbox_items_code_chk", + "value": "code ~ '^[0-9A-HJKMNP-TV-Z]{6}$'" + }, + "inbox_items_payload_chk": { + "name": "inbox_items_payload_chk", + "value": "jsonb_typeof(payload) = 'object'" + }, + "inbox_items_resolved_chk": { + "name": "inbox_items_resolved_chk", + "value": "(resolved_at IS NULL) = (resolution IS NULL)" + }, + "inbox_items_subject_chk": { + "name": "inbox_items_subject_chk", + "value": "kind = 'sync_drop' OR num_nonnulls(thing_id, purchase_id, meter_reading_id, code, room_capture_id) >= 1" + } + }, + "isRLSEnabled": false + }, + "public.template_locations": { + "name": "template_locations", + "schema": "", + "columns": { + "template_id": { + "name": "template_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "template_locations_location_idx": { + "name": "template_locations_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "template_locations_location_id_locations_id_fk": { + "name": "template_locations_location_id_locations_id_fk", + "tableFrom": "template_locations", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "template_locations_template_fk": { + "name": "template_locations_template_fk", + "tableFrom": "template_locations", + "columnsFrom": [ + "owner_account_id", + "template_id" + ], + "tableTo": "templates", + "columnsTo": [ + "owner_account_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "template_locations_pk": { + "name": "template_locations_pk", + "columns": [ + "template_id", + "location_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.templates": { + "name": "templates", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type_id": { + "name": "type_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "applies_to": { + "name": "applies_to", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'thing'" + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "archived_at": { + "name": "archived_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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "templates_type_idx": { + "name": "templates_type_idx", + "columns": [ + { + "expression": "type_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "templates_owner_account_id_owner_accounts_id_fk": { + "name": "templates_owner_account_id_owner_accounts_id_fk", + "tableFrom": "templates", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "templates_type_id_types_id_fk": { + "name": "templates_type_id_types_id_fk", + "tableFrom": "templates", + "columnsFrom": [ + "type_id" + ], + "tableTo": "types", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "templates_owner_account_id_uq": { + "name": "templates_owner_account_id_uq", + "columns": [ + "owner_account_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "templates_applies_to_chk": { + "name": "templates_applies_to_chk", + "value": "applies_to IN ('thing', 'place')" + }, + "templates_name_chk": { + "name": "templates_name_chk", + "value": "char_length(name) BETWEEN 1 AND 80" + }, + "templates_payload_chk": { + "name": "templates_payload_chk", + "value": "jsonb_typeof(payload) = 'object'" + } + }, + "isRLSEnabled": false + }, + "public.condition_report_rooms": { + "name": "condition_report_rooms", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "report_id": { + "name": "report_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "condition": { + "name": "condition", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sort": { + "name": "sort", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "condition_report_rooms_place_uq": { + "name": "condition_report_rooms_place_uq", + "columns": [ + { + "expression": "report_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "place_id IS NOT NULL", + "concurrently": false + }, + "condition_report_rooms_report_idx": { + "name": "condition_report_rooms_report_idx", + "columns": [ + { + "expression": "report_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "condition_report_rooms_place_idx": { + "name": "condition_report_rooms_place_idx", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "condition_report_rooms_report_fk": { + "name": "condition_report_rooms_report_fk", + "tableFrom": "condition_report_rooms", + "columnsFrom": [ + "location_id", + "report_id" + ], + "tableTo": "condition_reports", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "condition_report_rooms_location_id_uq": { + "name": "condition_report_rooms_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "condition_report_rooms_condition_chk": { + "name": "condition_report_rooms_condition_chk", + "value": "\"condition\" IN ('good', 'fair', 'poor', 'damaged')" + }, + "condition_report_rooms_name_chk": { + "name": "condition_report_rooms_name_chk", + "value": "char_length(btrim(name)) BETWEEN 1 AND 200" + }, + "condition_report_rooms_note_chk": { + "name": "condition_report_rooms_note_chk", + "value": "char_length(note) <= 4000" + } + }, + "isRLSEnabled": false + }, + "public.condition_reports": { + "name": "condition_reports", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "held_on": { + "name": "held_on", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "finished_by": { + "name": "finished_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "condition_reports_location_idx": { + "name": "condition_reports_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "held_on", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "condition_reports_location_id_locations_id_fk": { + "name": "condition_reports_location_id_locations_id_fk", + "tableFrom": "condition_reports", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "condition_reports_location_id_uq": { + "name": "condition_reports_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "condition_reports_kind_chk": { + "name": "condition_reports_kind_chk", + "value": "\"kind\" IN ('move_in', 'move_out')" + }, + "condition_reports_notes_chk": { + "name": "condition_reports_notes_chk", + "value": "char_length(notes) <= 4000" + }, + "condition_reports_finished_chk": { + "name": "condition_reports_finished_chk", + "value": "(finished_at IS NULL) = (finished_by IS NULL)" + } + }, + "isRLSEnabled": false + }, + "public.stock_rules": { + "name": "stock_rules", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "min_quantity": { + "name": "min_quantity", + "type": "numeric(12, 3)", + "primaryKey": false, + "notNull": true + }, + "low_since": { + "name": "low_since", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "stock_rules_location_idx": { + "name": "stock_rules_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "stock_rules_location_id_locations_id_fk": { + "name": "stock_rules_location_id_locations_id_fk", + "tableFrom": "stock_rules", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "stock_rules_thing_fk": { + "name": "stock_rules_thing_fk", + "tableFrom": "stock_rules", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "stock_rules_thing_uq": { + "name": "stock_rules_thing_uq", + "columns": [ + "thing_id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "stock_rules_min_quantity_chk": { + "name": "stock_rules_min_quantity_chk", + "value": "min_quantity > 0 AND min_quantity <= 1000000" + } + }, + "isRLSEnabled": false + }, + "public.currencies": { + "name": "currencies", + "schema": "", + "columns": { + "code": { + "name": "code", + "type": "char(3)", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "minor_units": { + "name": "minor_units", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "symbol": { + "name": "symbol", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "currencies_code_chk": { + "name": "currencies_code_chk", + "value": "code ~ '^[A-Z]{3}$'" + }, + "currencies_minor_units_chk": { + "name": "currencies_minor_units_chk", + "value": "minor_units BETWEEN 0 AND 4" + } + }, + "isRLSEnabled": false + }, + "public.embedding_state": { + "name": "embedding_state", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "model_key": { + "name": "model_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pending": { + "name": "pending", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_run_at": { + "name": "last_run_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "paused_reason": { + "name": "paused_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "paused_until": { + "name": "paused_until", + "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": { + "embedding_state_location_id_locations_id_fk": { + "name": "embedding_state_location_id_locations_id_fk", + "tableFrom": "embedding_state", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "embedding_state_model_key_chk": { + "name": "embedding_state_model_key_chk", + "value": "char_length(model_key) BETWEEN 1 AND 200" + }, + "embedding_state_source_chk": { + "name": "embedding_state_source_chk", + "value": "source IN ('provider', 'local')" + }, + "embedding_state_pending_chk": { + "name": "embedding_state_pending_chk", + "value": "pending >= 0" + }, + "embedding_state_paused_reason_chk": { + "name": "embedding_state_paused_reason_chk", + "value": "char_length(paused_reason) <= 60" + } + }, + "isRLSEnabled": false + }, + "public.thing_embeddings": { + "name": "thing_embeddings", + "schema": "", + "columns": { + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "model_key": { + "name": "model_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dims": { + "name": "dims", + "type": "smallint", + "primaryKey": false, + "notNull": true + }, + "content_hash": { + "name": "content_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "embedding": { + "name": "embedding", + "type": "vector", + "primaryKey": false, + "notNull": true + }, + "embedded_at": { + "name": "embedded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "thing_embeddings_loc_model_idx": { + "name": "thing_embeddings_loc_model_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "model_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "thing_embeddings_thing_fk": { + "name": "thing_embeddings_thing_fk", + "tableFrom": "thing_embeddings", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "thing_embeddings_pk": { + "name": "thing_embeddings_pk", + "columns": [ + "thing_id", + "model_key" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "thing_embeddings_model_key_chk": { + "name": "thing_embeddings_model_key_chk", + "value": "char_length(model_key) BETWEEN 1 AND 200" + }, + "thing_embeddings_dims_chk": { + "name": "thing_embeddings_dims_chk", + "value": "dims BETWEEN 1 AND 2000" + }, + "thing_embeddings_hash_chk": { + "name": "thing_embeddings_hash_chk", + "value": "content_hash ~ '^[0-9a-f]{64}$'" + }, + "thing_embeddings_vector_chk": { + "name": "thing_embeddings_vector_chk", + "value": "vector_dims(embedding) = dims" + } + }, + "isRLSEnabled": false + }, + "public.attachments": { + "name": "attachments", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "file_id": { + "name": "file_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "purchase_id": { + "name": "purchase_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "meter_reading_id": { + "name": "meter_reading_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "warranty_id": { + "name": "warranty_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "claim_id": { + "name": "claim_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "loan_id": { + "name": "loan_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "incident_id": { + "name": "incident_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "valuation_id": { + "name": "valuation_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "service_record_id": { + "name": "service_record_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "expiring_document_id": { + "name": "expiring_document_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "fuel_entry_id": { + "name": "fuel_entry_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "condition_room_id": { + "name": "condition_room_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "floor_plan_id": { + "name": "floor_plan_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sort": { + "name": "sort", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "in_review": { + "name": "in_review", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "attachments_warranty_idx": { + "name": "attachments_warranty_idx", + "columns": [ + { + "expression": "warranty_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_claim_idx": { + "name": "attachments_claim_idx", + "columns": [ + { + "expression": "claim_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_loan_idx": { + "name": "attachments_loan_idx", + "columns": [ + { + "expression": "loan_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_incident_idx": { + "name": "attachments_incident_idx", + "columns": [ + { + "expression": "incident_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_valuation_idx": { + "name": "attachments_valuation_idx", + "columns": [ + { + "expression": "valuation_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_service_record_idx": { + "name": "attachments_service_record_idx", + "columns": [ + { + "expression": "service_record_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_expiring_document_idx": { + "name": "attachments_expiring_document_idx", + "columns": [ + { + "expression": "expiring_document_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_fuel_entry_idx": { + "name": "attachments_fuel_entry_idx", + "columns": [ + { + "expression": "fuel_entry_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_condition_room_idx": { + "name": "attachments_condition_room_idx", + "columns": [ + { + "expression": "condition_room_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_floor_plan_idx": { + "name": "attachments_floor_plan_idx", + "columns": [ + { + "expression": "floor_plan_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_file_idx": { + "name": "attachments_file_idx", + "columns": [ + { + "expression": "file_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_thing_idx": { + "name": "attachments_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_place_idx": { + "name": "attachments_place_idx", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_purchase_idx": { + "name": "attachments_purchase_idx", + "columns": [ + { + "expression": "purchase_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_meter_reading_idx": { + "name": "attachments_meter_reading_idx", + "columns": [ + { + "expression": "meter_reading_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "attachments_location_idx": { + "name": "attachments_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "attachments_location_id_locations_id_fk": { + "name": "attachments_location_id_locations_id_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "attachments_thing_fk": { + "name": "attachments_thing_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_place_fk": { + "name": "attachments_place_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_purchase_fk": { + "name": "attachments_purchase_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "purchase_id" + ], + "tableTo": "purchases", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_meter_reading_fk": { + "name": "attachments_meter_reading_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "meter_reading_id" + ], + "tableTo": "meter_readings", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_warranty_fk": { + "name": "attachments_warranty_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "warranty_id" + ], + "tableTo": "warranties", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_claim_fk": { + "name": "attachments_claim_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "claim_id" + ], + "tableTo": "claims", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_loan_fk": { + "name": "attachments_loan_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "loan_id" + ], + "tableTo": "loans", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_incident_fk": { + "name": "attachments_incident_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "incident_id" + ], + "tableTo": "incidents", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_valuation_fk": { + "name": "attachments_valuation_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "valuation_id" + ], + "tableTo": "valuations", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_service_record_fk": { + "name": "attachments_service_record_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "service_record_id" + ], + "tableTo": "service_records", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_expiring_document_fk": { + "name": "attachments_expiring_document_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "expiring_document_id" + ], + "tableTo": "expiring_documents", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_fuel_entry_fk": { + "name": "attachments_fuel_entry_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "fuel_entry_id" + ], + "tableTo": "fuel_entries", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_condition_room_fk": { + "name": "attachments_condition_room_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "condition_room_id" + ], + "tableTo": "condition_report_rooms", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "attachments_floor_plan_fk": { + "name": "attachments_floor_plan_fk", + "tableFrom": "attachments", + "columnsFrom": [ + "location_id", + "floor_plan_id" + ], + "tableTo": "floor_plans", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "attachments_location_id_uq": { + "name": "attachments_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "attachments_role_chk": { + "name": "attachments_role_chk", + "value": "\"role\" IN ('photo', 'receipt', 'invoice', 'manual', 'warranty_doc', 'proof', 'condition_out', 'condition_in', 'registration', 'document')" + }, + "attachments_file_or_url_chk": { + "name": "attachments_file_or_url_chk", + "value": "num_nonnulls(file_id, url) = 1" + }, + "attachments_one_subject_chk": { + "name": "attachments_one_subject_chk", + "value": "num_nonnulls(thing_id, place_id, purchase_id, meter_reading_id, warranty_id, claim_id,\n loan_id, incident_id, valuation_id, service_record_id,\n expiring_document_id, fuel_entry_id, condition_room_id,\n floor_plan_id) <= 1" + }, + "attachments_name_chk": { + "name": "attachments_name_chk", + "value": "name IS NULL OR char_length(name) BETWEEN 1 AND 200" + }, + "attachments_url_chk": { + "name": "attachments_url_chk", + "value": "url IS NULL OR (url ~ '^https?://' AND char_length(url) <= 2000)" + } + }, + "isRLSEnabled": false + }, + "public.file_derivatives": { + "name": "file_derivatives", + "schema": "", + "columns": { + "file_id": { + "name": "file_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "variant": { + "name": "variant", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "bytes": { + "name": "bytes", + "type": "bigint", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "file_derivatives_storage_key_idx": { + "name": "file_derivatives_storage_key_idx", + "columns": [ + { + "expression": "storage_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "file_derivatives_file_fk": { + "name": "file_derivatives_file_fk", + "tableFrom": "file_derivatives", + "columnsFrom": [ + "location_id", + "file_id" + ], + "tableTo": "files", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "file_derivatives_pk": { + "name": "file_derivatives_pk", + "columns": [ + "file_id", + "variant" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "file_derivatives_variant_chk": { + "name": "file_derivatives_variant_chk", + "value": "\"variant\" IN ('display', 'thumb', 'share', 'poster')" + }, + "file_derivatives_size_chk": { + "name": "file_derivatives_size_chk", + "value": "width > 0 AND height > 0 AND bytes > 0" + } + }, + "isRLSEnabled": false + }, + "public.files": { + "name": "files", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "char(64)", + "primaryKey": false, + "notNull": true + }, + "bytes": { + "name": "bytes", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "mime": { + "name": "mime", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "class": { + "name": "class", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "has_gps": { + "name": "has_gps", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "derivative_state": { + "name": "derivative_state", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "attached_at": { + "name": "attached_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "files_storage_key_idx": { + "name": "files_storage_key_idx", + "columns": [ + { + "expression": "storage_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "files_unattached_idx": { + "name": "files_unattached_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "files_location_id_locations_id_fk": { + "name": "files_location_id_locations_id_fk", + "tableFrom": "files", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "files_location_sha_uq": { + "name": "files_location_sha_uq", + "columns": [ + "location_id", + "sha256" + ], + "nullsNotDistinct": false + }, + "files_location_id_uq": { + "name": "files_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "files_class_chk": { + "name": "files_class_chk", + "value": "\"class\" IN ('evidence', 'photo', 'document', 'video')" + }, + "files_derivative_state_chk": { + "name": "files_derivative_state_chk", + "value": "\"derivative_state\" IN ('ready', 'unavailable', 'not_applicable')" + }, + "files_sha256_chk": { + "name": "files_sha256_chk", + "value": "sha256 ~ '^[0-9a-f]{64}$'" + }, + "files_bytes_chk": { + "name": "files_bytes_chk", + "value": "bytes > 0" + }, + "files_storage_key_chk": { + "name": "files_storage_key_chk", + "value": "char_length(storage_key) BETWEEN 1 AND 300" + }, + "files_mime_chk": { + "name": "files_mime_chk", + "value": "char_length(mime) BETWEEN 1 AND 100" + }, + "files_size_chk": { + "name": "files_size_chk", + "value": "(width IS NULL OR width > 0) AND (height IS NULL OR height > 0)" + } + }, + "isRLSEnabled": false + }, + "public.floor_plans": { + "name": "floor_plans", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'reading'" + }, + "turn": { + "name": "turn", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "keep_plan": { + "name": "keep_plan", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "result": { + "name": "result", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "applied_event_id": { + "name": "applied_event_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "floor_plans_location_idx": { + "name": "floor_plans_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "floor_plans_location_id_locations_id_fk": { + "name": "floor_plans_location_id_locations_id_fk", + "tableFrom": "floor_plans", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "floor_plans_location_id_uq": { + "name": "floor_plans_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "floor_plans_status_chk": { + "name": "floor_plans_status_chk", + "value": "\"status\" IN ('reading', 'ready', 'failed', 'off', 'applied', 'discarded')" + }, + "floor_plans_turn_chk": { + "name": "floor_plans_turn_chk", + "value": "turn IN (0, 90, 180, 270)" + }, + "floor_plans_result_chk": { + "name": "floor_plans_result_chk", + "value": "result IS NULL OR jsonb_typeof(result) = 'object'" + } + }, + "isRLSEnabled": false + }, + "public.fuel_entries": { + "name": "fuel_entries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "taken_at": { + "name": "taken_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "numeric(10, 3)", + "primaryKey": false, + "notNull": true + }, + "unit": { + "name": "unit", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "currency": { + "name": "currency", + "type": "char(3)", + "primaryKey": false, + "notNull": false + }, + "cost": { + "name": "cost", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": false + }, + "is_full": { + "name": "is_full", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "missed_before": { + "name": "missed_before", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "vendor_id": { + "name": "vendor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "meter_reading_id": { + "name": "meter_reading_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logged_by": { + "name": "logged_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "fuel_entries_thing_idx": { + "name": "fuel_entries_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "taken_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "fuel_entries_vendor_idx": { + "name": "fuel_entries_vendor_idx", + "columns": [ + { + "expression": "vendor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "fuel_entries_reading_uq": { + "name": "fuel_entries_reading_uq", + "columns": [ + { + "expression": "meter_reading_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "meter_reading_id IS NOT NULL", + "concurrently": false + } + }, + "foreignKeys": { + "fuel_entries_location_id_locations_id_fk": { + "name": "fuel_entries_location_id_locations_id_fk", + "tableFrom": "fuel_entries", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "fuel_entries_currency_currencies_code_fk": { + "name": "fuel_entries_currency_currencies_code_fk", + "tableFrom": "fuel_entries", + "columnsFrom": [ + "currency" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "fuel_entries_vendor_id_vendors_id_fk": { + "name": "fuel_entries_vendor_id_vendors_id_fk", + "tableFrom": "fuel_entries", + "columnsFrom": [ + "vendor_id" + ], + "tableTo": "vendors", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "fuel_entries_thing_fk": { + "name": "fuel_entries_thing_fk", + "tableFrom": "fuel_entries", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "fuel_entries_location_id_uq": { + "name": "fuel_entries_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "fuel_entries_amount_chk": { + "name": "fuel_entries_amount_chk", + "value": "amount > 0" + }, + "fuel_entries_unit_chk": { + "name": "fuel_entries_unit_chk", + "value": "unit IN ('L', 'kWh', 'gal')" + }, + "fuel_entries_cost_chk": { + "name": "fuel_entries_cost_chk", + "value": "cost >= 0" + }, + "fuel_entries_money_chk": { + "name": "fuel_entries_money_chk", + "value": "(cost IS NULL) = (currency IS NULL)" + }, + "fuel_entries_note_chk": { + "name": "fuel_entries_note_chk", + "value": "char_length(note) <= 500" + } + }, + "isRLSEnabled": false + }, + "public.import_runs": { + "name": "import_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_version": { + "name": "source_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "mapping": { + "name": "mapping", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "choices": { + "name": "choices", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "rows": { + "name": "rows", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "dry_run_report": { + "name": "dry_run_report", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "progress": { + "name": "progress", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "total": { + "name": "total", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "archive_bytes": { + "name": "archive_bytes", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "archive_sha256": { + "name": "archive_sha256", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "archive_ready_at": { + "name": "archive_ready_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "inspect": { + "name": "inspect", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "secrets_key_ciphertext": { + "name": "secrets_key_ciphertext", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "key_version": { + "name": "key_version", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "new_location": { + "name": "new_location", + "type": "jsonb", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "import_runs_location_idx": { + "name": "import_runs_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "import_runs_draft_idx": { + "name": "import_runs_draft_idx", + "columns": [ + { + "expression": "created_by", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "location_id IS NULL", + "concurrently": false + } + }, + "foreignKeys": { + "import_runs_location_id_locations_id_fk": { + "name": "import_runs_location_id_locations_id_fk", + "tableFrom": "import_runs", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "import_runs_location_id_uq": { + "name": "import_runs_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "import_runs_source_chk": { + "name": "import_runs_source_chk", + "value": "\"source\" IN ('csv', 'homebox_zip', 'homebox_api', 'kept_zip', 'lubelogger_csv')" + }, + "import_runs_status_chk": { + "name": "import_runs_status_chk", + "value": "\"status\" IN ('draft', 'checked', 'running', 'done', 'failed', 'cancelled')" + }, + "import_runs_source_version_chk": { + "name": "import_runs_source_version_chk", + "value": "char_length(source_version) <= 40" + }, + "import_runs_mapping_chk": { + "name": "import_runs_mapping_chk", + "value": "jsonb_typeof(mapping) = 'object'" + }, + "import_runs_choices_chk": { + "name": "import_runs_choices_chk", + "value": "jsonb_typeof(choices) = 'object'" + }, + "import_runs_rows_chk": { + "name": "import_runs_rows_chk", + "value": "rows IS NULL OR jsonb_typeof(rows) = 'array'" + }, + "import_runs_progress_chk": { + "name": "import_runs_progress_chk", + "value": "progress >= 0 AND (total IS NULL OR progress <= total)" + }, + "import_runs_error_chk": { + "name": "import_runs_error_chk", + "value": "char_length(error) <= 500" + }, + "import_runs_target_chk": { + "name": "import_runs_target_chk", + "value": "location_id IS NOT NULL OR status IN ('draft', 'failed', 'cancelled')\n OR (status = 'checked' AND new_location IS NOT NULL)" + }, + "import_runs_new_location_chk": { + "name": "import_runs_new_location_chk", + "value": "new_location IS NULL OR (jsonb_typeof(new_location) = 'object'\n AND source = 'homebox_zip' AND location_id IS NULL)" + }, + "import_runs_archive_chk": { + "name": "import_runs_archive_chk", + "value": "(archive_bytes IS NULL AND archive_sha256 IS NULL AND archive_ready_at IS NULL)\n OR source IN ('homebox_zip', 'kept_zip')" + }, + "import_runs_archive_bytes_chk": { + "name": "import_runs_archive_bytes_chk", + "value": "archive_bytes >= 0" + }, + "import_runs_archive_sha256_chk": { + "name": "import_runs_archive_sha256_chk", + "value": "archive_sha256 ~ '^[0-9a-f]{64}$'" + }, + "import_runs_inspect_chk": { + "name": "import_runs_inspect_chk", + "value": "inspect IS NULL OR jsonb_typeof(inspect) = 'object'" + }, + "import_runs_secrets_key_chk": { + "name": "import_runs_secrets_key_chk", + "value": "(secrets_key_ciphertext IS NULL) = (key_version IS NULL)\n AND (secrets_key_ciphertext IS NULL OR source = 'kept_zip')" + } + }, + "isRLSEnabled": false + }, + "public.import_source_ids": { + "name": "import_source_ids", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_id": { + "name": "source_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entity_id": { + "name": "entity_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "run_id": { + "name": "run_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "import_source_ids_run_idx": { + "name": "import_source_ids_run_idx", + "columns": [ + { + "expression": "run_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "import_source_ids_entity_idx": { + "name": "import_source_ids_entity_idx", + "columns": [ + { + "expression": "entity_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "import_source_ids_location_id_locations_id_fk": { + "name": "import_source_ids_location_id_locations_id_fk", + "tableFrom": "import_source_ids", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "import_source_ids_run_fk": { + "name": "import_source_ids_run_fk", + "tableFrom": "import_source_ids", + "columnsFrom": [ + "location_id", + "run_id" + ], + "tableTo": "import_runs", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "import_source_ids_pk": { + "name": "import_source_ids_pk", + "columns": [ + "location_id", + "source", + "source_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "import_source_ids_source_chk": { + "name": "import_source_ids_source_chk", + "value": "\"source\" IN ('csv', 'homebox_zip', 'homebox_api', 'kept_zip', 'lubelogger_csv', 'homebox')" + }, + "import_source_ids_entity_type_chk": { + "name": "import_source_ids_entity_type_chk", + "value": "\"entity_type\" IN ('thing', 'place', 'purchase', 'attachment', 'file', 'tag', 'type', 'type_field', 'brand', 'vendor', 'person', 'template', 'meter', 'reading', 'box_check', 'stock_rule', 'warranty', 'service_record', 'schedule', 'loan', 'claim', 'incident', 'valuation', 'expiring_document', 'fuel_entry', 'service_line')" + }, + "import_source_ids_source_id_chk": { + "name": "import_source_ids_source_id_chk", + "value": "char_length(source_id) BETWEEN 1 AND 200" + } + }, + "isRLSEnabled": false + }, + "public.kit_parts": { + "name": "kit_parts", + "schema": "", + "columns": { + "kit_id": { + "name": "kit_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(12, 3)", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "kit_parts_location_idx": { + "name": "kit_parts_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "kit_parts_thing_id_things_id_fk": { + "name": "kit_parts_thing_id_things_id_fk", + "tableFrom": "kit_parts", + "columnsFrom": [ + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "kit_parts_kit_fk": { + "name": "kit_parts_kit_fk", + "tableFrom": "kit_parts", + "columnsFrom": [ + "location_id", + "kit_id" + ], + "tableTo": "kits", + "columnsTo": [ + "location_id", + "thing_id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "kit_parts_pk": { + "name": "kit_parts_pk", + "columns": [ + "kit_id", + "thing_id" + ] + } + }, + "uniqueConstraints": { + "kit_parts_thing_uq": { + "name": "kit_parts_thing_uq", + "columns": [ + "thing_id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "kit_parts_quantity_chk": { + "name": "kit_parts_quantity_chk", + "value": "quantity > 0" + }, + "kit_parts_not_itself_chk": { + "name": "kit_parts_not_itself_chk", + "value": "thing_id <> kit_id" + } + }, + "isRLSEnabled": false + }, + "public.kits": { + "name": "kits", + "schema": "", + "columns": { + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "kits_location_idx": { + "name": "kits_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "kits_location_id_locations_id_fk": { + "name": "kits_location_id_locations_id_fk", + "tableFrom": "kits", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "kits_thing_fk": { + "name": "kits_thing_fk", + "tableFrom": "kits", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "kits_location_id_uq": { + "name": "kits_location_id_uq", + "columns": [ + "location_id", + "thing_id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.label_batch_codes": { + "name": "label_batch_codes", + "schema": "", + "columns": { + "batch_id": { + "name": "batch_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "code": { + "name": "code", + "type": "char(6)", + "primaryKey": false, + "notNull": true + }, + "sort": { + "name": "sort", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "label_batch_codes_code_idx": { + "name": "label_batch_codes_code_idx", + "columns": [ + { + "expression": "code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "label_batch_codes_code_short_ids_code_fk": { + "name": "label_batch_codes_code_short_ids_code_fk", + "tableFrom": "label_batch_codes", + "columnsFrom": [ + "code" + ], + "tableTo": "short_ids", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "label_batch_codes_batch_fk": { + "name": "label_batch_codes_batch_fk", + "tableFrom": "label_batch_codes", + "columnsFrom": [ + "location_id", + "batch_id" + ], + "tableTo": "label_batches", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "label_batch_codes_pk": { + "name": "label_batch_codes_pk", + "columns": [ + "batch_id", + "code" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.label_batches": { + "name": "label_batches", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "stock": { + "name": "stock", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start_cell": { + "name": "start_cell", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "code_count": { + "name": "code_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "printed_confirmed_at": { + "name": "printed_confirmed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "dismissed_at": { + "name": "dismissed_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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "label_batches_location_idx": { + "name": "label_batches_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "label_batches_location_id_locations_id_fk": { + "name": "label_batches_location_id_locations_id_fk", + "tableFrom": "label_batches", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "label_batches_location_id_uq": { + "name": "label_batches_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "label_batches_kind_chk": { + "name": "label_batches_kind_chk", + "value": "\"kind\" IN ('things', 'places', 'blank')" + }, + "label_batches_stock_chk": { + "name": "label_batches_stock_chk", + "value": "stock ~ '^[a-z0-9_]{1,40}$'" + }, + "label_batches_start_cell_chk": { + "name": "label_batches_start_cell_chk", + "value": "start_cell BETWEEN 1 AND 200" + }, + "label_batches_code_count_chk": { + "name": "label_batches_code_count_chk", + "value": "code_count BETWEEN 1 AND 1000" + } + }, + "isRLSEnabled": false + }, + "public.handovers": { + "name": "handovers", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "direction": { + "name": "direction", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "person_id": { + "name": "person_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "root_thing_id": { + "name": "root_thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "due_on": { + "name": "due_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "lead_days": { + "name": "lead_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "condition_out": { + "name": "condition_out", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "handovers_person_idx": { + "name": "handovers_person_idx", + "columns": [ + { + "expression": "person_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "handovers_root_idx": { + "name": "handovers_root_idx", + "columns": [ + { + "expression": "root_thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "handovers_location_id_locations_id_fk": { + "name": "handovers_location_id_locations_id_fk", + "tableFrom": "handovers", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "handovers_root_thing_id_things_id_fk": { + "name": "handovers_root_thing_id_things_id_fk", + "tableFrom": "handovers", + "columnsFrom": [ + "root_thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "handovers_location_id_uq": { + "name": "handovers_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "handovers_direction_chk": { + "name": "handovers_direction_chk", + "value": "\"direction\" IN ('out', 'in')" + }, + "handovers_condition_out_chk": { + "name": "handovers_condition_out_chk", + "value": "\"condition_out\" IN ('new', 'good', 'fair', 'poor', 'broken')" + }, + "handovers_lead_days_chk": { + "name": "handovers_lead_days_chk", + "value": "lead_days BETWEEN 0 AND 60" + }, + "handovers_notes_chk": { + "name": "handovers_notes_chk", + "value": "char_length(notes) <= 2000" + } + }, + "isRLSEnabled": false + }, + "public.loans": { + "name": "loans", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "direction": { + "name": "direction", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "person_id": { + "name": "person_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "due_on": { + "name": "due_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "returned_at": { + "name": "returned_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "return_place_id": { + "name": "return_place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "return_container_id": { + "name": "return_container_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "previous_place_id": { + "name": "previous_place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "previous_container_id": { + "name": "previous_container_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "split_from_thing_id": { + "name": "split_from_thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "lead_days": { + "name": "lead_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "handover_id": { + "name": "handover_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "path_at_lend": { + "name": "path_at_lend", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "outcome": { + "name": "outcome", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "condition_out": { + "name": "condition_out", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "condition_in": { + "name": "condition_in", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "return_notes": { + "name": "return_notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "damaged": { + "name": "damaged", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "taken_back_by": { + "name": "taken_back_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "loans_handover_idx": { + "name": "loans_handover_idx", + "columns": [ + { + "expression": "handover_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "loans_one_open_uq": { + "name": "loans_one_open_uq", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "returned_at IS NULL", + "concurrently": false + }, + "loans_due_idx": { + "name": "loans_due_idx", + "columns": [ + { + "expression": "due_on", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "returned_at IS NULL", + "concurrently": false + }, + "loans_person_idx": { + "name": "loans_person_idx", + "columns": [ + { + "expression": "person_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "loans_thing_idx": { + "name": "loans_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "loans_location_id_locations_id_fk": { + "name": "loans_location_id_locations_id_fk", + "tableFrom": "loans", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "loans_handover_id_handovers_id_fk": { + "name": "loans_handover_id_handovers_id_fk", + "tableFrom": "loans", + "columnsFrom": [ + "handover_id" + ], + "tableTo": "handovers", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "loans_thing_fk": { + "name": "loans_thing_fk", + "tableFrom": "loans", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "loans_location_id_uq": { + "name": "loans_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "loans_direction_chk": { + "name": "loans_direction_chk", + "value": "\"direction\" IN ('out', 'in')" + }, + "loans_outcome_chk": { + "name": "loans_outcome_chk", + "value": "\"outcome\" IN ('returned', 'lost')" + }, + "loans_condition_out_chk": { + "name": "loans_condition_out_chk", + "value": "\"condition_out\" IN ('new', 'good', 'fair', 'poor', 'broken')" + }, + "loans_condition_in_chk": { + "name": "loans_condition_in_chk", + "value": "\"condition_in\" IN ('new', 'good', 'fair', 'poor', 'broken')" + }, + "loans_return_notes_chk": { + "name": "loans_return_notes_chk", + "value": "char_length(return_notes) <= 2000" + }, + "loans_path_chk": { + "name": "loans_path_chk", + "value": "char_length(path_at_lend) <= 1000" + }, + "loans_lead_days_chk": { + "name": "loans_lead_days_chk", + "value": "lead_days BETWEEN 0 AND 60" + }, + "loans_notes_chk": { + "name": "loans_notes_chk", + "value": "char_length(notes) <= 2000" + }, + "loans_due_chk": { + "name": "loans_due_chk", + "value": "due_on IS NULL OR due_on >= (started_at AT TIME ZONE 'UTC')::date - 1" + }, + "loans_returned_chk": { + "name": "loans_returned_chk", + "value": "returned_at IS NULL OR returned_at >= started_at" + }, + "loans_return_where_chk": { + "name": "loans_return_where_chk", + "value": "num_nonnulls(return_place_id, return_container_id) <= 1" + } + }, + "isRLSEnabled": false + }, + "public.mailbox_messages": { + "name": "mailbox_messages", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "mailbox_id": { + "name": "mailbox_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "uid_validity": { + "name": "uid_validity", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "uid": { + "name": "uid", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "from_address": { + "name": "from_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "received_at": { + "name": "received_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "outcome": { + "name": "outcome", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "purchase_id": { + "name": "purchase_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "mailbox_messages_recent_idx": { + "name": "mailbox_messages_recent_idx", + "columns": [ + { + "expression": "mailbox_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "mailbox_messages_mailbox_fk": { + "name": "mailbox_messages_mailbox_fk", + "tableFrom": "mailbox_messages", + "columnsFrom": [ + "location_id", + "mailbox_id" + ], + "tableTo": "mailboxes", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "mailbox_messages_uid_uq": { + "name": "mailbox_messages_uid_uq", + "columns": [ + "mailbox_id", + "uid_validity", + "uid" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "mailbox_messages_outcome_chk": { + "name": "mailbox_messages_outcome_chk", + "value": "\"outcome\" IN ('receipt', 'no_receipt', 'sender_not_allowed', 'too_large', 'failed')" + }, + "mailbox_messages_from_chk": { + "name": "mailbox_messages_from_chk", + "value": "from_address IS NULL OR char_length(from_address) <= 254" + }, + "mailbox_messages_subject_chk": { + "name": "mailbox_messages_subject_chk", + "value": "subject IS NULL OR char_length(subject) <= 200" + } + }, + "isRLSEnabled": false + }, + "public.mailboxes": { + "name": "mailboxes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'imap'" + }, + "host": { + "name": "host", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "folder": { + "name": "folder", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "allowed_senders": { + "name": "allowed_senders", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "config_ciphertext": { + "name": "config_ciphertext", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "key_version": { + "name": "key_version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "disabled_reason": { + "name": "disabled_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uid_validity": { + "name": "uid_validity", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "last_uid": { + "name": "last_uid", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "last_polled_at": { + "name": "last_polled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "mailboxes_location_id_locations_id_fk": { + "name": "mailboxes_location_id_locations_id_fk", + "tableFrom": "mailboxes", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "mailboxes_location_uq": { + "name": "mailboxes_location_uq", + "columns": [ + "location_id" + ], + "nullsNotDistinct": false + }, + "mailboxes_location_id_uq": { + "name": "mailboxes_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "mailboxes_kind_chk": { + "name": "mailboxes_kind_chk", + "value": "\"kind\" IN ('imap')" + }, + "mailboxes_disabled_reason_chk": { + "name": "mailboxes_disabled_reason_chk", + "value": "\"disabled_reason\" IN ('creator_left', 'auth_failed')" + }, + "mailboxes_host_chk": { + "name": "mailboxes_host_chk", + "value": "char_length(host) BETWEEN 1 AND 253" + }, + "mailboxes_username_chk": { + "name": "mailboxes_username_chk", + "value": "char_length(username) BETWEEN 1 AND 254" + }, + "mailboxes_folder_chk": { + "name": "mailboxes_folder_chk", + "value": "char_length(folder) BETWEEN 1 AND 200" + }, + "mailboxes_senders_chk": { + "name": "mailboxes_senders_chk", + "value": "cardinality(allowed_senders) <= 20" + }, + "mailboxes_key_version_chk": { + "name": "mailboxes_key_version_chk", + "value": "key_version >= 1" + }, + "mailboxes_disabled_chk": { + "name": "mailboxes_disabled_chk", + "value": "active OR disabled_reason IS NOT NULL" + }, + "mailboxes_last_error_chk": { + "name": "mailboxes_last_error_chk", + "value": "last_error IS NULL OR char_length(last_error) <= 32" + } + }, + "isRLSEnabled": false + }, + "public.map_nodes": { + "name": "map_nodes", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "x_cm": { + "name": "x_cm", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "z_cm": { + "name": "z_cm", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "w_cm": { + "name": "w_cm", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "d_cm": { + "name": "d_cm", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "rot": { + "name": "rot", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "room_kind": { + "name": "room_kind", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "surface": { + "name": "surface", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "host_id": { + "name": "host_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "height_cm": { + "name": "height_cm", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "placed_by_kept": { + "name": "placed_by_kept", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "map_nodes_place_uq": { + "name": "map_nodes_place_uq", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "concurrently": false + }, + "map_nodes_thing_uq": { + "name": "map_nodes_thing_uq", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "concurrently": false + }, + "map_nodes_location_idx": { + "name": "map_nodes_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "map_nodes_location_id_locations_id_fk": { + "name": "map_nodes_location_id_locations_id_fk", + "tableFrom": "map_nodes", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "map_nodes_place_fk": { + "name": "map_nodes_place_fk", + "tableFrom": "map_nodes", + "columnsFrom": [ + "location_id", + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "map_nodes_thing_fk": { + "name": "map_nodes_thing_fk", + "tableFrom": "map_nodes", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "map_nodes_room_kind_chk": { + "name": "map_nodes_room_kind_chk", + "value": "\"room_kind\" IN ('room', 'balcony', 'terrace', 'garden')" + }, + "map_nodes_surface_chk": { + "name": "map_nodes_surface_chk", + "value": "\"surface\" IN ('wood', 'tile', 'concrete', 'deck', 'grass')" + }, + "map_nodes_one_subject_chk": { + "name": "map_nodes_one_subject_chk", + "value": "num_nonnulls(place_id, thing_id) = 1" + }, + "map_nodes_rot_chk": { + "name": "map_nodes_rot_chk", + "value": "rot IN (0, 90, 180, 270)" + }, + "map_nodes_xz_chk": { + "name": "map_nodes_xz_chk", + "value": "x_cm BETWEEN 0 AND 100000 AND z_cm BETWEEN 0 AND 100000" + }, + "map_nodes_size_chk": { + "name": "map_nodes_size_chk", + "value": "(w_cm IS NULL AND d_cm IS NULL) OR (w_cm BETWEEN 50 AND 10000 AND d_cm BETWEEN 50 AND 10000)" + }, + "map_nodes_model_chk": { + "name": "map_nodes_model_chk", + "value": "model IS NULL OR model ~ '^[a-z][a-z0-9_]{0,39}$'" + }, + "map_nodes_room_chk": { + "name": "map_nodes_room_chk", + "value": "(room_kind IS NULL AND surface IS NULL) OR w_cm IS NOT NULL" + }, + "map_nodes_height_chk": { + "name": "map_nodes_height_chk", + "value": "height_cm IS NULL OR (height_cm BETWEEN 0 AND 300 AND w_cm IS NULL AND host_id IS NULL)" + }, + "map_nodes_not_own_host_chk": { + "name": "map_nodes_not_own_host_chk", + "value": "host_id IS NULL OR host_id <> coalesce(place_id, thing_id)" + } + }, + "isRLSEnabled": false + }, + "public.meter_events": { + "name": "meter_events", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "meter_id": { + "name": "meter_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "at": { + "name": "at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "offset": { + "name": "offset", + "type": "numeric(14, 3)", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "meter_events_meter_idx": { + "name": "meter_events_meter_idx", + "columns": [ + { + "expression": "meter_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "meter_events_meter_fk": { + "name": "meter_events_meter_fk", + "tableFrom": "meter_events", + "columnsFrom": [ + "location_id", + "meter_id" + ], + "tableTo": "meters", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "meter_events_kind_chk": { + "name": "meter_events_kind_chk", + "value": "\"kind\" IN ('replaced')" + } + }, + "isRLSEnabled": false + }, + "public.meter_readings": { + "name": "meter_readings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "meter_id": { + "name": "meter_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "numeric(14, 3)", + "primaryKey": false, + "notNull": true + }, + "taken_at": { + "name": "taken_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "received_at": { + "name": "received_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'manual'" + }, + "logged_by": { + "name": "logged_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'accepted'" + }, + "review_reason": { + "name": "review_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "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()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "meter_readings_meter_taken_idx": { + "name": "meter_readings_meter_taken_idx", + "columns": [ + { + "expression": "meter_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "taken_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "meter_readings_meter_fk": { + "name": "meter_readings_meter_fk", + "tableFrom": "meter_readings", + "columnsFrom": [ + "location_id", + "meter_id" + ], + "tableTo": "meters", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "meter_readings_location_id_uq": { + "name": "meter_readings_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "meter_readings_source_chk": { + "name": "meter_readings_source_chk", + "value": "\"source\" IN ('manual', 'photo', 'fuel', 'service', 'import', 'home_assistant')" + }, + "meter_readings_state_chk": { + "name": "meter_readings_state_chk", + "value": "\"state\" IN ('accepted', 'needs_review')" + }, + "meter_readings_value_chk": { + "name": "meter_readings_value_chk", + "value": "value >= 0" + }, + "meter_readings_note_chk": { + "name": "meter_readings_note_chk", + "value": "char_length(note) <= 500" + }, + "meter_readings_review_reason_chk": { + "name": "meter_readings_review_reason_chk", + "value": "char_length(review_reason) <= 200" + } + }, + "isRLSEnabled": false + }, + "public.meters": { + "name": "meters", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "unit": { + "name": "unit", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "offset": { + "name": "offset", + "type": "numeric(14, 3)", + "primaryKey": false, + "notNull": true, + "default": "'0'" + }, + "max_per_day": { + "name": "max_per_day", + "type": "numeric(14, 3)", + "primaryKey": false, + "notNull": false + }, + "nudge_days": { + "name": "nudge_days", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 30 + }, + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "meters_thing_idx": { + "name": "meters_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "meters_thing_fk": { + "name": "meters_thing_fk", + "tableFrom": "meters", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "meters_location_id_uq": { + "name": "meters_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "meters_kind_chk": { + "name": "meters_kind_chk", + "value": "\"kind\" IN ('distance', 'hours', 'custom')" + }, + "meters_unit_chk": { + "name": "meters_unit_chk", + "value": "char_length(unit) BETWEEN 1 AND 12" + }, + "meters_label_chk": { + "name": "meters_label_chk", + "value": "label IS NULL OR char_length(label) BETWEEN 1 AND 80" + }, + "meters_max_per_day_chk": { + "name": "meters_max_per_day_chk", + "value": "max_per_day IS NULL OR max_per_day > 0" + }, + "meters_nudge_days_chk": { + "name": "meters_nudge_days_chk", + "value": "nudge_days IS NULL OR nudge_days BETWEEN 7 AND 365" + } + }, + "isRLSEnabled": false + }, + "public.export_runs": { + "name": "export_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "include_secrets": { + "name": "include_secrets", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "incident_id": { + "name": "incident_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "thing_ids": { + "name": "thing_ids", + "type": "uuid[]", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "progress_done": { + "name": "progress_done", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "progress_total": { + "name": "progress_total", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "storage_key": { + "name": "storage_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "bytes": { + "name": "bytes", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token_expires_at": { + "name": "token_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 + }, + "downloads": { + "name": "downloads", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_downloaded_at": { + "name": "last_downloaded_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()" + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now() + interval '7 days'" + }, + "options": { + "name": "options", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "secrets_key_ciphertext": { + "name": "secrets_key_ciphertext", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "key_version": { + "name": "key_version", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "export_runs_location_idx": { + "name": "export_runs_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "export_runs_expires_idx": { + "name": "export_runs_expires_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "export_runs_creator_idx": { + "name": "export_runs_creator_idx", + "columns": [ + { + "expression": "created_by", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "export_runs_location_id_locations_id_fk": { + "name": "export_runs_location_id_locations_id_fk", + "tableFrom": "export_runs", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "export_runs_created_by_user_id_fk": { + "name": "export_runs_created_by_user_id_fk", + "tableFrom": "export_runs", + "columnsFrom": [ + "created_by" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "export_runs_token_hash_uq": { + "name": "export_runs_token_hash_uq", + "columns": [ + "token_hash" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "export_runs_kind_chk": { + "name": "export_runs_kind_chk", + "value": "\"kind\" IN ('claim_pack', 'location', 'me')" + }, + "export_runs_status_chk": { + "name": "export_runs_status_chk", + "value": "\"status\" IN ('queued', 'running', 'done', 'failed', 'cancelled', 'expired')" + }, + "export_runs_secrets_chk": { + "name": "export_runs_secrets_chk", + "value": "NOT include_secrets OR kind <> 'claim_pack'" + }, + "export_runs_scope_chk": { + "name": "export_runs_scope_chk", + "value": "num_nonnulls(incident_id, thing_ids) <= 1" + }, + "export_runs_progress_chk": { + "name": "export_runs_progress_chk", + "value": "progress_done >= 0 AND progress_total >= 0 AND progress_done <= progress_total" + }, + "export_runs_error_chk": { + "name": "export_runs_error_chk", + "value": "error ~ '^[a-z_]{1,32}$'" + }, + "export_runs_token_hash_chk": { + "name": "export_runs_token_hash_chk", + "value": "token_hash ~ '^[0-9a-f]{64}$'" + }, + "export_runs_storage_key_chk": { + "name": "export_runs_storage_key_chk", + "value": "storage_key IS NULL OR storage_key = 'x/' || id::text || '.zip'" + }, + "export_runs_thing_ids_chk": { + "name": "export_runs_thing_ids_chk", + "value": "cardinality(thing_ids) BETWEEN 1 AND 1000" + }, + "export_runs_kind_scope_chk": { + "name": "export_runs_kind_scope_chk", + "value": "kind = 'claim_pack' OR num_nonnulls(incident_id, thing_ids) = 0" + }, + "export_runs_options_chk": { + "name": "export_runs_options_chk", + "value": "jsonb_typeof(options) = 'object'" + }, + "export_runs_sha256_chk": { + "name": "export_runs_sha256_chk", + "value": "sha256 ~ '^[0-9a-f]{64}$'" + }, + "export_runs_secrets_key_chk": { + "name": "export_runs_secrets_key_chk", + "value": "(secrets_key_ciphertext IS NULL) = (key_version IS NULL)\n AND (secrets_key_ciphertext IS NULL OR include_secrets)" + } + }, + "isRLSEnabled": false + }, + "public.fx_rates": { + "name": "fx_rates", + "schema": "", + "columns": { + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "from_ccy": { + "name": "from_ccy", + "type": "char(3)", + "primaryKey": false, + "notNull": true + }, + "to_ccy": { + "name": "to_ccy", + "type": "char(3)", + "primaryKey": false, + "notNull": true + }, + "rate": { + "name": "rate", + "type": "numeric(18, 8)", + "primaryKey": false, + "notNull": true + }, + "valid_from": { + "name": "valid_from", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "fx_rates_owner_account_id_owner_accounts_id_fk": { + "name": "fx_rates_owner_account_id_owner_accounts_id_fk", + "tableFrom": "fx_rates", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "fx_rates_from_ccy_currencies_code_fk": { + "name": "fx_rates_from_ccy_currencies_code_fk", + "tableFrom": "fx_rates", + "columnsFrom": [ + "from_ccy" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "fx_rates_to_ccy_currencies_code_fk": { + "name": "fx_rates_to_ccy_currencies_code_fk", + "tableFrom": "fx_rates", + "columnsFrom": [ + "to_ccy" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + } + }, + "compositePrimaryKeys": { + "fx_rates_pk": { + "name": "fx_rates_pk", + "columns": [ + "owner_account_id", + "from_ccy", + "to_ccy", + "valid_from" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "fx_rates_rate_chk": { + "name": "fx_rates_rate_chk", + "value": "rate > 0" + }, + "fx_rates_pair_chk": { + "name": "fx_rates_pair_chk", + "value": "from_ccy <> to_ccy" + } + }, + "isRLSEnabled": false + }, + "public.incident_things": { + "name": "incident_things", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "incident_id": { + "name": "incident_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "incident_things_thing_idx": { + "name": "incident_things_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "incident_things_incident_fk": { + "name": "incident_things_incident_fk", + "tableFrom": "incident_things", + "columnsFrom": [ + "location_id", + "incident_id" + ], + "tableTo": "incidents", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "incident_things_thing_fk": { + "name": "incident_things_thing_fk", + "tableFrom": "incident_things", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "incident_things_pk": { + "name": "incident_things_pk", + "columns": [ + "incident_id", + "thing_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.incidents": { + "name": "incidents", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "occurred_on": { + "name": "occurred_on", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "police_reference": { + "name": "police_reference", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "insurer_reference": { + "name": "insurer_reference", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "incidents_location_idx": { + "name": "incidents_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_on", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "incidents_location_id_locations_id_fk": { + "name": "incidents_location_id_locations_id_fk", + "tableFrom": "incidents", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "incidents_location_id_uq": { + "name": "incidents_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "incidents_kind_chk": { + "name": "incidents_kind_chk", + "value": "\"kind\" IN ('burglary', 'fire', 'flood', 'loss', 'other')" + }, + "incidents_police_reference_chk": { + "name": "incidents_police_reference_chk", + "value": "char_length(police_reference) <= 100" + }, + "incidents_insurer_reference_chk": { + "name": "incidents_insurer_reference_chk", + "value": "char_length(insurer_reference) <= 100" + }, + "incidents_notes_chk": { + "name": "incidents_notes_chk", + "value": "char_length(notes) <= 5000" + } + }, + "isRLSEnabled": false + }, + "public.valuations": { + "name": "valuations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": true + }, + "currency": { + "name": "currency", + "type": "char(3)", + "primaryKey": false, + "notNull": true + }, + "valued_on": { + "name": "valued_on", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "valuations_thing_idx": { + "name": "valuations_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "valued_on", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "valuations_location_id_locations_id_fk": { + "name": "valuations_location_id_locations_id_fk", + "tableFrom": "valuations", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "valuations_currency_currencies_code_fk": { + "name": "valuations_currency_currencies_code_fk", + "tableFrom": "valuations", + "columnsFrom": [ + "currency" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "valuations_thing_fk": { + "name": "valuations_thing_fk", + "tableFrom": "valuations", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "valuations_location_id_uq": { + "name": "valuations_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "valuations_source_chk": { + "name": "valuations_source_chk", + "value": "\"source\" IN ('purchase', 'appraisal', 'estimate', 'insurer')" + }, + "valuations_value_chk": { + "name": "valuations_value_chk", + "value": "value >= 0" + }, + "valuations_notes_chk": { + "name": "valuations_notes_chk", + "value": "char_length(notes) <= 2000" + } + }, + "isRLSEnabled": false + }, + "public.move_boxes": { + "name": "move_boxes", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "move_id": { + "name": "move_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "container_id": { + "name": "container_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "number": { + "name": "number", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'packed'" + }, + "destination_place_id": { + "name": "destination_place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "state_at": { + "name": "state_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "state_by": { + "name": "state_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "move_boxes_container_idx": { + "name": "move_boxes_container_idx", + "columns": [ + { + "expression": "container_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "move_boxes_destination_idx": { + "name": "move_boxes_destination_idx", + "columns": [ + { + "expression": "destination_place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "move_boxes_container_id_things_id_fk": { + "name": "move_boxes_container_id_things_id_fk", + "tableFrom": "move_boxes", + "columnsFrom": [ + "container_id" + ], + "tableTo": "things", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "move_boxes_destination_place_id_places_id_fk": { + "name": "move_boxes_destination_place_id_places_id_fk", + "tableFrom": "move_boxes", + "columnsFrom": [ + "destination_place_id" + ], + "tableTo": "places", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "move_boxes_move_fk": { + "name": "move_boxes_move_fk", + "tableFrom": "move_boxes", + "columnsFrom": [ + "location_id", + "move_id" + ], + "tableTo": "moves", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "move_boxes_pk": { + "name": "move_boxes_pk", + "columns": [ + "move_id", + "container_id" + ] + } + }, + "uniqueConstraints": { + "move_boxes_number_uq": { + "name": "move_boxes_number_uq", + "columns": [ + "move_id", + "number" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "move_boxes_state_chk": { + "name": "move_boxes_state_chk", + "value": "\"state\" IN ('packed', 'in_transit', 'unpacked')" + }, + "move_boxes_number_chk": { + "name": "move_boxes_number_chk", + "value": "number BETWEEN 1 AND 999" + } + }, + "isRLSEnabled": false + }, + "public.moves": { + "name": "moves", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "to_location_id": { + "name": "to_location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "finished_at": { + "name": "finished_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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "moves_location_idx": { + "name": "moves_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "moves_to_location_idx": { + "name": "moves_to_location_idx", + "columns": [ + { + "expression": "to_location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "moves_location_id_locations_id_fk": { + "name": "moves_location_id_locations_id_fk", + "tableFrom": "moves", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "moves_to_location_id_locations_id_fk": { + "name": "moves_to_location_id_locations_id_fk", + "tableFrom": "moves", + "columnsFrom": [ + "to_location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "moves_location_id_uq": { + "name": "moves_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "moves_status_chk": { + "name": "moves_status_chk", + "value": "\"status\" IN ('active', 'done')" + }, + "moves_name_chk": { + "name": "moves_name_chk", + "value": "char_length(btrim(name)) BETWEEN 1 AND 200" + }, + "moves_finished_chk": { + "name": "moves_finished_chk", + "value": "(status = 'done') = (finished_at IS NOT NULL)" + } + }, + "isRLSEnabled": false + }, + "public.calendar_feeds": { + "name": "calendar_feeds", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_fetched_at": { + "name": "last_fetched_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "fetches": { + "name": "fetches", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "calendar_feeds_user_idx": { + "name": "calendar_feeds_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "calendar_feeds_user_id_user_id_fk": { + "name": "calendar_feeds_user_id_user_id_fk", + "tableFrom": "calendar_feeds", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "calendar_feeds_token_hash_uq": { + "name": "calendar_feeds_token_hash_uq", + "columns": [ + "token_hash" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "calendar_feeds_token_hash_chk": { + "name": "calendar_feeds_token_hash_chk", + "value": "token_hash ~ '^[0-9a-f]{64}$'" + }, + "calendar_feeds_fetches_chk": { + "name": "calendar_feeds_fetches_chk", + "value": "fetches >= 0" + } + }, + "isRLSEnabled": false + }, + "public.notification_channels": { + "name": "notification_channels", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "display_host": { + "name": "display_host", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "config_ciphertext": { + "name": "config_ciphertext", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "key_version": { + "name": "key_version", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "verified_at": { + "name": "verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "failing_since": { + "name": "failing_since", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "notification_channels_email_uq": { + "name": "notification_channels_email_uq", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "kind = 'email'", + "concurrently": false + }, + "notification_channels_webpush_uq": { + "name": "notification_channels_webpush_uq", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "kind = 'webpush'", + "concurrently": false + }, + "notification_channels_user_idx": { + "name": "notification_channels_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "notification_channels_user_id_user_id_fk": { + "name": "notification_channels_user_id_user_id_fk", + "tableFrom": "notification_channels", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "notification_channels_kind_chk": { + "name": "notification_channels_kind_chk", + "value": "\"kind\" IN ('email', 'webpush', 'webhook', 'ntfy', 'telegram', 'apprise')" + }, + "notification_channels_label_chk": { + "name": "notification_channels_label_chk", + "value": "char_length(label) <= 60" + }, + "notification_channels_display_host_chk": { + "name": "notification_channels_display_host_chk", + "value": "char_length(display_host) <= 255" + }, + "notification_channels_config_chk": { + "name": "notification_channels_config_chk", + "value": "(kind IN ('webhook', 'ntfy', 'telegram', 'apprise')) = (config_ciphertext IS NOT NULL)\n AND (config_ciphertext IS NULL) = (key_version IS NULL)" + } + }, + "isRLSEnabled": false + }, + "public.notification_preferences": { + "name": "notification_preferences", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "channel": { + "name": "channel", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "notification_preferences_location_idx": { + "name": "notification_preferences_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "notification_preferences_user_id_user_id_fk": { + "name": "notification_preferences_user_id_user_id_fk", + "tableFrom": "notification_preferences", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "notification_preferences_location_id_locations_id_fk": { + "name": "notification_preferences_location_id_locations_id_fk", + "tableFrom": "notification_preferences", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "notification_preferences_uq": { + "name": "notification_preferences_uq", + "columns": [ + "user_id", + "location_id", + "kind", + "channel" + ], + "nullsNotDistinct": true + } + }, + "policies": {}, + "checkConstraints": { + "notification_preferences_kind_chk": { + "name": "notification_preferences_kind_chk", + "value": "\"kind\" IN ('schedule', 'warranty', 'registration', 'document', 'loan', 'thing_expiry', 'reading_stale', 'stock', 'membership', 'ai_cap', 'ai_summary')" + }, + "notification_preferences_channel_chk": { + "name": "notification_preferences_channel_chk", + "value": "\"channel\" IN ('inapp', 'email', 'webpush', 'webhook', 'ntfy', 'telegram', 'apprise')" + }, + "notification_preferences_account_chk": { + "name": "notification_preferences_account_chk", + "value": "kind <> 'ai_summary' OR location_id IS NULL" + } + }, + "isRLSEnabled": false + }, + "public.push_subscriptions": { + "name": "push_subscriptions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "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 + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_success_at": { + "name": "last_success_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "failures": { + "name": "failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "push_subscriptions_user_idx": { + "name": "push_subscriptions_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "push_subscriptions_user_id_user_id_fk": { + "name": "push_subscriptions_user_id_user_id_fk", + "tableFrom": "push_subscriptions", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "push_subscriptions_endpoint_uq": { + "name": "push_subscriptions_endpoint_uq", + "columns": [ + "endpoint" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "push_subscriptions_endpoint_chk": { + "name": "push_subscriptions_endpoint_chk", + "value": "endpoint ~ '^https://' AND char_length(endpoint) <= 1000" + }, + "push_subscriptions_keys_chk": { + "name": "push_subscriptions_keys_chk", + "value": "char_length(p256dh) <= 200 AND char_length(auth) <= 100" + }, + "push_subscriptions_label_chk": { + "name": "push_subscriptions_label_chk", + "value": "char_length(label) <= 60" + }, + "push_subscriptions_failures_chk": { + "name": "push_subscriptions_failures_chk", + "value": "failures >= 0" + } + }, + "isRLSEnabled": false + }, + "public.backup_runs": { + "name": "backup_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'running'" + }, + "started_at": { + "name": "started_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 + }, + "storage_mode": { + "name": "storage_mode", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target": { + "name": "target", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "snapshot_id": { + "name": "snapshot_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "db_bytes": { + "name": "db_bytes", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "bytes_added": { + "name": "bytes_added", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "bytes_total": { + "name": "bytes_total", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "files_total": { + "name": "files_total", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "files_new": { + "name": "files_new", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "missing": { + "name": "missing", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "readable_locations": { + "name": "readable_locations", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "readable_bytes": { + "name": "readable_bytes", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "same_volume": { + "name": "same_volume", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "bucket_versioning_ok": { + "name": "bucket_versioning_ok", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "from_version": { + "name": "from_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "to_version": { + "name": "to_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "verified_at": { + "name": "verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "detail": { + "name": "detail", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "backup_runs_started_idx": { + "name": "backup_runs_started_idx", + "columns": [ + { + "expression": "started_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "backup_runs_kind_idx": { + "name": "backup_runs_kind_idx", + "columns": [ + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "started_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "backup_runs_kind_chk": { + "name": "backup_runs_kind_chk", + "value": "\"kind\" IN ('nightly', 'manual', 'pre_upgrade', 'drill', 'verify')" + }, + "backup_runs_status_chk": { + "name": "backup_runs_status_chk", + "value": "\"status\" IN ('running', 'ok', 'warning', 'failed')" + }, + "backup_runs_storage_mode_chk": { + "name": "backup_runs_storage_mode_chk", + "value": "\"storage_mode\" IN ('local', 's3')" + }, + "backup_runs_target_chk": { + "name": "backup_runs_target_chk", + "value": "char_length(target) BETWEEN 1 AND 300" + }, + "backup_runs_snapshot_id_chk": { + "name": "backup_runs_snapshot_id_chk", + "value": "snapshot_id ~ '^[0-9a-f]{8,64}$'" + }, + "backup_runs_error_chk": { + "name": "backup_runs_error_chk", + "value": "error ~ '^[a-z_]{1,48}$'" + }, + "backup_runs_detail_chk": { + "name": "backup_runs_detail_chk", + "value": "jsonb_typeof(detail) = 'object'" + }, + "backup_runs_finished_chk": { + "name": "backup_runs_finished_chk", + "value": "(status = 'running') = (finished_at IS NULL)" + }, + "backup_runs_missing_chk": { + "name": "backup_runs_missing_chk", + "value": "missing >= 0" + } + }, + "isRLSEnabled": false + }, + "public.release_history": { + "name": "release_history", + "schema": "", + "columns": { + "version": { + "name": "version", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "revision": { + "name": "revision", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_migration": { + "name": "last_migration", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "first_migrated_at": { + "name": "first_migrated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_booted_at": { + "name": "last_booted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "release_history_version_chk": { + "name": "release_history_version_chk", + "value": "version ~ '^\\d+\\.\\d+\\.\\d+(-[0-9A-Za-z.-]+)?$'" + }, + "release_history_revision_chk": { + "name": "release_history_revision_chk", + "value": "revision ~ '^[0-9a-f]{7,40}$'" + }, + "release_history_last_migration_chk": { + "name": "release_history_last_migration_chk", + "value": "char_length(last_migration) BETWEEN 1 AND 100" + } + }, + "isRLSEnabled": false + }, + "public.paperless_connections": { + "name": "paperless_connections", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "base_url": { + "name": "base_url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "config_ciphertext": { + "name": "config_ciphertext", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "key_version": { + "name": "key_version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "server_version": { + "name": "server_version", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "paperless_connections_location_id_locations_id_fk": { + "name": "paperless_connections_location_id_locations_id_fk", + "tableFrom": "paperless_connections", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "paperless_connections_location_uq": { + "name": "paperless_connections_location_uq", + "columns": [ + "location_id" + ], + "nullsNotDistinct": false + }, + "paperless_connections_location_id_uq": { + "name": "paperless_connections_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "paperless_connections_base_url_chk": { + "name": "paperless_connections_base_url_chk", + "value": "char_length(base_url) BETWEEN 1 AND 500" + }, + "paperless_connections_key_version_chk": { + "name": "paperless_connections_key_version_chk", + "value": "key_version >= 1" + }, + "paperless_connections_version_chk": { + "name": "paperless_connections_version_chk", + "value": "server_version IS NULL OR char_length(server_version) <= 40" + } + }, + "isRLSEnabled": false + }, + "public.paperless_links": { + "name": "paperless_links", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "document_id": { + "name": "document_id", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type_name": { + "name": "type_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "correspondent": { + "name": "correspondent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_on": { + "name": "created_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "copied_attachment_id": { + "name": "copied_attachment_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "refreshed_at": { + "name": "refreshed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "paperless_links_location_idx": { + "name": "paperless_links_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "paperless_links_copied_idx": { + "name": "paperless_links_copied_idx", + "columns": [ + { + "expression": "copied_attachment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "paperless_links_thing_id_things_id_fk": { + "name": "paperless_links_thing_id_things_id_fk", + "tableFrom": "paperless_links", + "columnsFrom": [ + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "paperless_links_place_id_places_id_fk": { + "name": "paperless_links_place_id_places_id_fk", + "tableFrom": "paperless_links", + "columnsFrom": [ + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "paperless_links_copied_attachment_id_attachments_id_fk": { + "name": "paperless_links_copied_attachment_id_attachments_id_fk", + "tableFrom": "paperless_links", + "columnsFrom": [ + "copied_attachment_id" + ], + "tableTo": "attachments", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "paperless_links_connection_fk": { + "name": "paperless_links_connection_fk", + "tableFrom": "paperless_links", + "columnsFrom": [ + "location_id", + "connection_id" + ], + "tableTo": "paperless_connections", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "paperless_links_thing_uq": { + "name": "paperless_links_thing_uq", + "columns": [ + "thing_id", + "document_id" + ], + "nullsNotDistinct": false + }, + "paperless_links_place_uq": { + "name": "paperless_links_place_uq", + "columns": [ + "place_id", + "document_id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "paperless_links_kind_chk": { + "name": "paperless_links_kind_chk", + "value": "\"kind\" IN ('receipt', 'invoice', 'manual', 'warranty_doc', 'document')" + }, + "paperless_links_subject_chk": { + "name": "paperless_links_subject_chk", + "value": "num_nonnulls(thing_id, place_id) = 1" + }, + "paperless_links_document_chk": { + "name": "paperless_links_document_chk", + "value": "document_id > 0" + }, + "paperless_links_title_chk": { + "name": "paperless_links_title_chk", + "value": "char_length(title) BETWEEN 1 AND 300" + }, + "paperless_links_type_chk": { + "name": "paperless_links_type_chk", + "value": "type_name IS NULL OR char_length(type_name) <= 128" + }, + "paperless_links_correspondent_chk": { + "name": "paperless_links_correspondent_chk", + "value": "correspondent IS NULL OR char_length(correspondent) <= 128" + } + }, + "isRLSEnabled": false + }, + "public.places": { + "name": "places", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "parent_id": { + "name": "parent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind_key": { + "name": "kind_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'room'" + }, + "is_unplaced": { + "name": "is_unplaced", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sort": { + "name": "sort", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "child_order": { + "name": "child_order", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'name'" + }, + "custom": { + "name": "custom", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "layout": { + "name": "layout", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "cell": { + "name": "cell", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "trash_batch_id": { + "name": "trash_batch_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "change_xid": { + "name": "change_xid", + "type": "xid8", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "places_one_unplaced_uq": { + "name": "places_one_unplaced_uq", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "is_unplaced", + "concurrently": false + }, + "places_parent_idx": { + "name": "places_parent_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "places_trash_purge_idx": { + "name": "places_trash_purge_idx", + "columns": [ + { + "expression": "deleted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "deleted_at IS NOT NULL", + "concurrently": false + }, + "places_sync_idx": { + "name": "places_sync_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "change_xid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "places_location_id_locations_id_fk": { + "name": "places_location_id_locations_id_fk", + "tableFrom": "places", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "places_parent_fk": { + "name": "places_parent_fk", + "tableFrom": "places", + "columnsFrom": [ + "location_id", + "parent_id" + ], + "tableTo": "places", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "places_location_id_uq": { + "name": "places_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "places_unplaced_top_level_chk": { + "name": "places_unplaced_top_level_chk", + "value": "NOT is_unplaced OR parent_id IS NULL" + }, + "places_not_own_parent_chk": { + "name": "places_not_own_parent_chk", + "value": "parent_id IS NULL OR parent_id <> id" + }, + "places_custom_chk": { + "name": "places_custom_chk", + "value": "jsonb_typeof(custom) = 'object'" + }, + "places_child_order_chk": { + "name": "places_child_order_chk", + "value": "child_order IN ('name', 'custom')" + }, + "places_layout_chk": { + "name": "places_layout_chk", + "value": "layout IS NULL OR jsonb_typeof(layout) = 'object'" + }, + "places_cell_chk": { + "name": "places_cell_chk", + "value": "cell IS NULL OR jsonb_typeof(cell) = 'object'" + }, + "places_icon_chk": { + "name": "places_icon_chk", + "value": "icon IS NULL OR icon ~ '^(lucide|tabler|kept):[a-z0-9-]+$'" + } + }, + "isRLSEnabled": false + }, + "public.purchase_lines": { + "name": "purchase_lines", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "purchase_id": { + "name": "purchase_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(12, 3)", + "primaryKey": false, + "notNull": true, + "default": "'1'" + }, + "unit_price": { + "name": "unit_price", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": false + }, + "sort": { + "name": "sort", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "purchase_lines_purchase_idx": { + "name": "purchase_lines_purchase_idx", + "columns": [ + { + "expression": "purchase_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "purchase_lines_purchase_fk": { + "name": "purchase_lines_purchase_fk", + "tableFrom": "purchase_lines", + "columnsFrom": [ + "location_id", + "purchase_id" + ], + "tableTo": "purchases", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "purchase_lines_location_id_uq": { + "name": "purchase_lines_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "purchase_lines_description_chk": { + "name": "purchase_lines_description_chk", + "value": "char_length(description) BETWEEN 1 AND 300" + }, + "purchase_lines_quantity_chk": { + "name": "purchase_lines_quantity_chk", + "value": "quantity > 0" + }, + "purchase_lines_unit_price_chk": { + "name": "purchase_lines_unit_price_chk", + "value": "unit_price >= 0" + } + }, + "isRLSEnabled": false + }, + "public.purchases": { + "name": "purchases", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "vendor_id": { + "name": "vendor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "purchased_on": { + "name": "purchased_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "currency": { + "name": "currency", + "type": "char(3)", + "primaryKey": false, + "notNull": false + }, + "total": { + "name": "total", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": false + }, + "tax": { + "name": "tax", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "review_state": { + "name": "review_state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'confirmed'" + }, + "created_via": { + "name": "created_via", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'app'" + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "purchases_location_date_idx": { + "name": "purchases_location_date_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "purchased_on", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "purchases_vendor_idx": { + "name": "purchases_vendor_idx", + "columns": [ + { + "expression": "vendor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "purchases_location_id_locations_id_fk": { + "name": "purchases_location_id_locations_id_fk", + "tableFrom": "purchases", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "purchases_vendor_id_vendors_id_fk": { + "name": "purchases_vendor_id_vendors_id_fk", + "tableFrom": "purchases", + "columnsFrom": [ + "vendor_id" + ], + "tableTo": "vendors", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "purchases_currency_currencies_code_fk": { + "name": "purchases_currency_currencies_code_fk", + "tableFrom": "purchases", + "columnsFrom": [ + "currency" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "purchases_location_id_uq": { + "name": "purchases_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "purchases_review_state_chk": { + "name": "purchases_review_state_chk", + "value": "\"review_state\" IN ('draft', 'confirmed')" + }, + "purchases_created_via_chk": { + "name": "purchases_created_via_chk", + "value": "\"created_via\" IN ('app', 'mcp', 'assistant', 'import', 'email')" + }, + "purchases_dated_chk": { + "name": "purchases_dated_chk", + "value": "purchased_on IS NOT NULL OR review_state = 'draft'" + }, + "purchases_total_chk": { + "name": "purchases_total_chk", + "value": "total >= 0" + }, + "purchases_tax_chk": { + "name": "purchases_tax_chk", + "value": "tax >= 0" + }, + "purchases_money_chk": { + "name": "purchases_money_chk", + "value": "(total IS NULL AND tax IS NULL) OR currency IS NOT NULL" + }, + "purchases_notes_chk": { + "name": "purchases_notes_chk", + "value": "char_length(notes) <= 5000" + } + }, + "isRLSEnabled": false + }, + "public.brand_logos": { + "name": "brand_logos", + "schema": "", + "columns": { + "brand_id": { + "name": "brand_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "png": { + "name": "png", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "brand_logos_owner_idx": { + "name": "brand_logos_owner_idx", + "columns": [ + { + "expression": "owner_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "brand_logos_owner_account_id_owner_accounts_id_fk": { + "name": "brand_logos_owner_account_id_owner_accounts_id_fk", + "tableFrom": "brand_logos", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "brand_logos_brand_fk": { + "name": "brand_logos_brand_fk", + "tableFrom": "brand_logos", + "columnsFrom": [ + "owner_account_id", + "brand_id" + ], + "tableTo": "brands", + "columnsTo": [ + "owner_account_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "brand_logos_png_chk": { + "name": "brand_logos_png_chk", + "value": "octet_length(png) BETWEEN 8 AND 262144" + }, + "brand_logos_size_chk": { + "name": "brand_logos_size_chk", + "value": "width BETWEEN 1 AND 256 AND height BETWEEN 1 AND 256" + }, + "brand_logos_sha256_chk": { + "name": "brand_logos_sha256_chk", + "value": "sha256 ~ '^[0-9a-f]{64}$'" + } + }, + "isRLSEnabled": false + }, + "public.brands": { + "name": "brands", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "website": { + "name": "website", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "support_phone": { + "name": "support_phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "claim_url": { + "name": "claim_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_warranty_months": { + "name": "default_warranty_months", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "brands_owner_account_id_owner_accounts_id_fk": { + "name": "brands_owner_account_id_owner_accounts_id_fk", + "tableFrom": "brands", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "brands_owner_id_uq": { + "name": "brands_owner_id_uq", + "columns": [ + "owner_account_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "brands_name_chk": { + "name": "brands_name_chk", + "value": "char_length(name) BETWEEN 1 AND 120" + }, + "brands_website_chk": { + "name": "brands_website_chk", + "value": "website IS NULL OR char_length(website) <= 2000" + }, + "brands_claim_url_chk": { + "name": "brands_claim_url_chk", + "value": "claim_url IS NULL OR char_length(claim_url) <= 2000" + }, + "brands_support_phone_chk": { + "name": "brands_support_phone_chk", + "value": "support_phone IS NULL OR char_length(support_phone) <= 40" + }, + "brands_default_warranty_chk": { + "name": "brands_default_warranty_chk", + "value": "default_warranty_months IS NULL OR default_warranty_months >= 0" + } + }, + "isRLSEnabled": false + }, + "public.people": { + "name": "people", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "member_user_id": { + "name": "member_user_id", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "people_owner_account_id_owner_accounts_id_fk": { + "name": "people_owner_account_id_owner_accounts_id_fk", + "tableFrom": "people", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "people_member_user_id_user_id_fk": { + "name": "people_member_user_id_user_id_fk", + "tableFrom": "people", + "columnsFrom": [ + "member_user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "people_owner_id_uq": { + "name": "people_owner_id_uq", + "columns": [ + "owner_account_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "people_display_name_chk": { + "name": "people_display_name_chk", + "value": "char_length(display_name) BETWEEN 1 AND 120" + } + }, + "isRLSEnabled": false + }, + "public.person_contacts": { + "name": "person_contacts", + "schema": "", + "columns": { + "person_id": { + "name": "person_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "phone": { + "name": "phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "person_contacts_owner_account_id_owner_accounts_id_fk": { + "name": "person_contacts_owner_account_id_owner_accounts_id_fk", + "tableFrom": "person_contacts", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "person_contacts_person_fk": { + "name": "person_contacts_person_fk", + "tableFrom": "person_contacts", + "columnsFrom": [ + "owner_account_id", + "person_id" + ], + "tableTo": "people", + "columnsTo": [ + "owner_account_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "person_contacts_phone_chk": { + "name": "person_contacts_phone_chk", + "value": "phone IS NULL OR char_length(phone) <= 40" + }, + "person_contacts_email_chk": { + "name": "person_contacts_email_chk", + "value": "email IS NULL OR char_length(email) <= 320" + }, + "person_contacts_notes_chk": { + "name": "person_contacts_notes_chk", + "value": "notes IS NULL OR char_length(notes) <= 5000" + } + }, + "isRLSEnabled": false + }, + "public.place_kinds": { + "name": "place_kinds", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "archived_at": { + "name": "archived_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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "place_kinds_owner_account_id_owner_accounts_id_fk": { + "name": "place_kinds_owner_account_id_owner_accounts_id_fk", + "tableFrom": "place_kinds", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "place_kinds_owner_key_uq": { + "name": "place_kinds_owner_key_uq", + "columns": [ + "owner_account_id", + "key" + ], + "nullsNotDistinct": true + }, + "place_kinds_owner_id_uq": { + "name": "place_kinds_owner_id_uq", + "columns": [ + "owner_account_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "place_kinds_key_chk": { + "name": "place_kinds_key_chk", + "value": "key ~ '^[a-z][a-z0-9_]{0,39}$'" + }, + "place_kinds_icon_chk": { + "name": "place_kinds_icon_chk", + "value": "icon ~ '^(lucide|tabler|kept):[a-z0-9-]+$'" + }, + "place_kinds_name_chk": { + "name": "place_kinds_name_chk", + "value": "name IS NULL OR char_length(name) BETWEEN 1 AND 80" + }, + "place_kinds_named_chk": { + "name": "place_kinds_named_chk", + "value": "owner_account_id IS NULL OR name IS NOT NULL OR key IN ('floor', 'room', 'zone', 'closet', 'furniture', 'cube', 'shelf', 'drawer')" + } + }, + "isRLSEnabled": false + }, + "public.tags": { + "name": "tags", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "colour": { + "name": "colour", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "tags_owner_account_id_owner_accounts_id_fk": { + "name": "tags_owner_account_id_owner_accounts_id_fk", + "tableFrom": "tags", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "tags_owner_id_uq": { + "name": "tags_owner_id_uq", + "columns": [ + "owner_account_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "tags_name_chk": { + "name": "tags_name_chk", + "value": "char_length(name) BETWEEN 1 AND 60" + }, + "tags_colour_chk": { + "name": "tags_colour_chk", + "value": "colour IS NULL OR colour ~ '^#[0-9A-Fa-f]{6}$'" + } + }, + "isRLSEnabled": false + }, + "public.type_fields": { + "name": "type_fields", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "type_id": { + "name": "type_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_kind_id": { + "name": "place_kind_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "unit": { + "name": "unit", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "options": { + "name": "options", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "repeatable": { + "name": "repeatable", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "required": { + "name": "required", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "sort": { + "name": "sort", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "secret": { + "name": "secret", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "archived_at": { + "name": "archived_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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "type_fields_type_key_uq": { + "name": "type_fields_type_key_uq", + "columns": [ + { + "expression": "type_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "type_id IS NOT NULL", + "concurrently": false + }, + "type_fields_place_kind_key_uq": { + "name": "type_fields_place_kind_key_uq", + "columns": [ + { + "expression": "place_kind_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "place_kind_id IS NOT NULL", + "concurrently": false + }, + "type_fields_owner_idx": { + "name": "type_fields_owner_idx", + "columns": [ + { + "expression": "owner_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "type_fields_owner_account_id_owner_accounts_id_fk": { + "name": "type_fields_owner_account_id_owner_accounts_id_fk", + "tableFrom": "type_fields", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "type_fields_type_id_types_id_fk": { + "name": "type_fields_type_id_types_id_fk", + "tableFrom": "type_fields", + "columnsFrom": [ + "type_id" + ], + "tableTo": "types", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "type_fields_place_kind_id_place_kinds_id_fk": { + "name": "type_fields_place_kind_id_place_kinds_id_fk", + "tableFrom": "type_fields", + "columnsFrom": [ + "place_kind_id" + ], + "tableTo": "place_kinds", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "type_fields_type_account_fk": { + "name": "type_fields_type_account_fk", + "tableFrom": "type_fields", + "columnsFrom": [ + "owner_account_id", + "type_id" + ], + "tableTo": "types", + "columnsTo": [ + "owner_account_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "type_fields_place_kind_account_fk": { + "name": "type_fields_place_kind_account_fk", + "tableFrom": "type_fields", + "columnsFrom": [ + "owner_account_id", + "place_kind_id" + ], + "tableTo": "place_kinds", + "columnsTo": [ + "owner_account_id", + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "type_fields_kind_chk": { + "name": "type_fields_kind_chk", + "value": "\"kind\" IN ('text', 'number', 'date', 'select', 'multi_select', 'boolean', 'url', 'money', 'person', 'vendor', 'file')" + }, + "type_fields_one_owner_chk": { + "name": "type_fields_one_owner_chk", + "value": "num_nonnulls(type_id, place_kind_id) = 1" + }, + "type_fields_key_chk": { + "name": "type_fields_key_chk", + "value": "key ~ '^[a-z][a-z0-9_]{0,39}$'" + }, + "type_fields_secret_text_chk": { + "name": "type_fields_secret_text_chk", + "value": "NOT secret OR kind = 'text'" + }, + "type_fields_label_chk": { + "name": "type_fields_label_chk", + "value": "label IS NULL OR char_length(label) BETWEEN 1 AND 80" + }, + "type_fields_unit_chk": { + "name": "type_fields_unit_chk", + "value": "unit IS NULL OR char_length(unit) BETWEEN 1 AND 12" + }, + "type_fields_options_chk": { + "name": "type_fields_options_chk", + "value": "options IS NULL OR jsonb_typeof(options) = 'array'" + } + }, + "isRLSEnabled": false + }, + "public.types": { + "name": "types", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "builtin_key": { + "name": "builtin_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "copied_from_id": { + "name": "copied_from_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "parent_id": { + "name": "parent_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "search_names": { + "name": "search_names", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "colour": { + "name": "colour", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "capabilities": { + "name": "capabilities", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "default_meter": { + "name": "default_meter", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "is_field_group": { + "name": "is_field_group", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "field_groups": { + "name": "field_groups", + "type": "uuid[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::uuid[]" + }, + "default_warranty_months": { + "name": "default_warranty_months", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "archived_at": { + "name": "archived_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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "types_builtin_key_uq": { + "name": "types_builtin_key_uq", + "columns": [ + { + "expression": "builtin_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "owner_account_id IS NULL", + "concurrently": false + }, + "types_parent_idx": { + "name": "types_parent_idx", + "columns": [ + { + "expression": "parent_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "types_copied_from_idx": { + "name": "types_copied_from_idx", + "columns": [ + { + "expression": "copied_from_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "types_owner_account_id_owner_accounts_id_fk": { + "name": "types_owner_account_id_owner_accounts_id_fk", + "tableFrom": "types", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "types_parent_fk": { + "name": "types_parent_fk", + "tableFrom": "types", + "columnsFrom": [ + "parent_id" + ], + "tableTo": "types", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "types_copied_from_fk": { + "name": "types_copied_from_fk", + "tableFrom": "types", + "columnsFrom": [ + "copied_from_id" + ], + "tableTo": "types", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "types_owner_id_uq": { + "name": "types_owner_id_uq", + "columns": [ + "owner_account_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "types_builtin_chk": { + "name": "types_builtin_chk", + "value": "(owner_account_id IS NULL) = (builtin_key IS NOT NULL)" + }, + "types_builtin_key_chk": { + "name": "types_builtin_key_chk", + "value": "builtin_key IS NULL OR builtin_key ~ '^[a-z][a-z0-9_]{0,39}$'" + }, + "types_named_chk": { + "name": "types_named_chk", + "value": "name IS NOT NULL OR builtin_key IS NOT NULL OR copied_from_id IS NOT NULL" + }, + "types_name_chk": { + "name": "types_name_chk", + "value": "name IS NULL OR char_length(name) BETWEEN 1 AND 80" + }, + "types_icon_chk": { + "name": "types_icon_chk", + "value": "icon ~ '^(lucide|tabler|kept):[a-z0-9-]+$'" + }, + "types_colour_chk": { + "name": "types_colour_chk", + "value": "colour IS NULL OR colour ~ '^#[0-9A-Fa-f]{6}$'" + }, + "types_capabilities_chk": { + "name": "types_capabilities_chk", + "value": "capabilities <@ ARRAY['container', 'metered', 'warranty', 'serialized', 'consumable', 'expires']::text[]" + }, + "types_default_meter_chk": { + "name": "types_default_meter_chk", + "value": "default_meter IS NULL OR jsonb_typeof(default_meter) IN ('object', 'null')" + }, + "types_field_group_chk": { + "name": "types_field_group_chk", + "value": "NOT is_field_group OR (parent_id IS NULL AND cardinality(field_groups) = 0)" + }, + "types_not_own_parent_chk": { + "name": "types_not_own_parent_chk", + "value": "parent_id IS NULL OR parent_id <> id" + }, + "types_default_warranty_chk": { + "name": "types_default_warranty_chk", + "value": "default_warranty_months IS NULL OR default_warranty_months >= 0" + } + }, + "isRLSEnabled": false + }, + "public.vendors": { + "name": "vendors", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'other'" + }, + "address": { + "name": "address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "phone": { + "name": "phone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "website": { + "name": "website", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "vendors_owner_account_id_owner_accounts_id_fk": { + "name": "vendors_owner_account_id_owner_accounts_id_fk", + "tableFrom": "vendors", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "vendors_owner_id_uq": { + "name": "vendors_owner_id_uq", + "columns": [ + "owner_account_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "vendors_kind_chk": { + "name": "vendors_kind_chk", + "value": "\"kind\" IN ('store', 'online', 'service_centre', 'station', 'other')" + }, + "vendors_name_chk": { + "name": "vendors_name_chk", + "value": "char_length(name) BETWEEN 1 AND 120" + }, + "vendors_address_chk": { + "name": "vendors_address_chk", + "value": "address IS NULL OR char_length(address) <= 500" + }, + "vendors_phone_chk": { + "name": "vendors_phone_chk", + "value": "phone IS NULL OR char_length(phone) <= 40" + }, + "vendors_website_chk": { + "name": "vendors_website_chk", + "value": "website IS NULL OR char_length(website) <= 2000" + } + }, + "isRLSEnabled": false + }, + "public.notification_digests": { + "name": "notification_digests", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "digest_on": { + "name": "digest_on", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "channel_id": { + "name": "channel_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "notification_digests_channel_idx": { + "name": "notification_digests_channel_idx", + "columns": [ + { + "expression": "channel_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "notification_digests_user_id_user_id_fk": { + "name": "notification_digests_user_id_user_id_fk", + "tableFrom": "notification_digests", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "notification_digests_channel_id_notification_channels_id_fk": { + "name": "notification_digests_channel_id_notification_channels_id_fk", + "tableFrom": "notification_digests", + "columnsFrom": [ + "channel_id" + ], + "tableTo": "notification_channels", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "notification_digests_pk": { + "name": "notification_digests_pk", + "columns": [ + "user_id", + "digest_on", + "channel_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notifications": { + "name": "notifications", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "occurrence_id": { + "name": "occurrence_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "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": { + "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" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "notifications_unread_idx": { + "name": "notifications_unread_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "read_at IS NULL", + "concurrently": false + }, + "notifications_occurrence_idx": { + "name": "notifications_occurrence_idx", + "columns": [ + { + "expression": "occurrence_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "notifications_user_id_user_id_fk": { + "name": "notifications_user_id_user_id_fk", + "tableFrom": "notifications", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "notifications_location_id_locations_id_fk": { + "name": "notifications_location_id_locations_id_fk", + "tableFrom": "notifications", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "notifications_occurrence_id_reminder_occurrences_id_fk": { + "name": "notifications_occurrence_id_reminder_occurrences_id_fk", + "tableFrom": "notifications", + "columnsFrom": [ + "occurrence_id" + ], + "tableTo": "reminder_occurrences", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "notifications_user_occurrence_uq": { + "name": "notifications_user_occurrence_uq", + "columns": [ + "user_id", + "occurrence_id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "notifications_kind_chk": { + "name": "notifications_kind_chk", + "value": "\"kind\" IN ('reminder', 'membership_added', 'membership_ended', 'ai_cap', 'ai_summary', 'export_ready')" + }, + "notifications_payload_chk": { + "name": "notifications_payload_chk", + "value": "jsonb_typeof(payload) = 'object'" + }, + "notifications_reminder_chk": { + "name": "notifications_reminder_chk", + "value": "(kind = 'reminder') = (occurrence_id IS NOT NULL)" + } + }, + "isRLSEnabled": false + }, + "public.reminder_deliveries": { + "name": "reminder_deliveries", + "schema": "", + "columns": { + "occurrence_id": { + "name": "occurrence_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "channel_id": { + "name": "channel_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "not_before": { + "name": "not_before", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "reminder_deliveries_digest_idx": { + "name": "reminder_deliveries_digest_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "status = 'digest'", + "concurrently": false + }, + "reminder_deliveries_queued_idx": { + "name": "reminder_deliveries_queued_idx", + "columns": [ + { + "expression": "not_before", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "status = 'queued'", + "concurrently": false + }, + "reminder_deliveries_channel_idx": { + "name": "reminder_deliveries_channel_idx", + "columns": [ + { + "expression": "channel_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "reminder_deliveries_occurrence_id_reminder_occurrences_id_fk": { + "name": "reminder_deliveries_occurrence_id_reminder_occurrences_id_fk", + "tableFrom": "reminder_deliveries", + "columnsFrom": [ + "occurrence_id" + ], + "tableTo": "reminder_occurrences", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "reminder_deliveries_user_id_user_id_fk": { + "name": "reminder_deliveries_user_id_user_id_fk", + "tableFrom": "reminder_deliveries", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "reminder_deliveries_channel_id_notification_channels_id_fk": { + "name": "reminder_deliveries_channel_id_notification_channels_id_fk", + "tableFrom": "reminder_deliveries", + "columnsFrom": [ + "channel_id" + ], + "tableTo": "notification_channels", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "reminder_deliveries_pk": { + "name": "reminder_deliveries_pk", + "columns": [ + "occurrence_id", + "user_id", + "channel_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "reminder_deliveries_status_chk": { + "name": "reminder_deliveries_status_chk", + "value": "\"status\" IN ('digest', 'queued', 'sending', 'sent', 'failed', 'skipped')" + }, + "reminder_deliveries_error_chk": { + "name": "reminder_deliveries_error_chk", + "value": "error ~ '^[a-z_0-9]{1,40}$'" + } + }, + "isRLSEnabled": false + }, + "public.reminder_occurrences": { + "name": "reminder_occurrences", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_id": { + "name": "source_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "due_period": { + "name": "due_period", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "due_on": { + "name": "due_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'open'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "closed_at": { + "name": "closed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "reminder_occurrences_open_idx": { + "name": "reminder_occurrences_open_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "state = 'open'", + "concurrently": false + }, + "reminder_occurrences_source_idx": { + "name": "reminder_occurrences_source_idx", + "columns": [ + { + "expression": "source_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "reminder_occurrences_location_id_locations_id_fk": { + "name": "reminder_occurrences_location_id_locations_id_fk", + "tableFrom": "reminder_occurrences", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "reminder_occurrences_thing_fk": { + "name": "reminder_occurrences_thing_fk", + "tableFrom": "reminder_occurrences", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "reminder_occurrences_place_fk": { + "name": "reminder_occurrences_place_fk", + "tableFrom": "reminder_occurrences", + "columnsFrom": [ + "location_id", + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "reminder_occurrences_location_id_uq": { + "name": "reminder_occurrences_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + }, + "reminder_occurrences_key_uq": { + "name": "reminder_occurrences_key_uq", + "columns": [ + "thing_id", + "place_id", + "location_id", + "source_type", + "source_id", + "kind", + "due_period" + ], + "nullsNotDistinct": true + } + }, + "policies": {}, + "checkConstraints": { + "reminder_occurrences_source_type_chk": { + "name": "reminder_occurrences_source_type_chk", + "value": "\"source_type\" IN ('schedule', 'warranty', 'registration', 'document', 'loan', 'thing_expiry', 'stock', 'reading_stale')" + }, + "reminder_occurrences_kind_chk": { + "name": "reminder_occurrences_kind_chk", + "value": "\"kind\" IN ('due', 'overdue', 'expiring')" + }, + "reminder_occurrences_state_chk": { + "name": "reminder_occurrences_state_chk", + "value": "\"state\" IN ('open', 'done', 'superseded', 'cancelled')" + }, + "reminder_occurrences_due_period_chk": { + "name": "reminder_occurrences_due_period_chk", + "value": "due_period ~ '^(date:\\d{4}-\\d{2}-\\d{2}|meter:\\d+(\\.\\d{1,3})?)$'" + }, + "reminder_occurrences_subject_chk": { + "name": "reminder_occurrences_subject_chk", + "value": "num_nonnulls(thing_id, place_id) <= 1" + }, + "reminder_occurrences_closed_chk": { + "name": "reminder_occurrences_closed_chk", + "value": "(state = 'open') = (closed_at IS NULL)" + } + }, + "isRLSEnabled": false + }, + "public.report_runs": { + "name": "report_runs", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "location_ids": { + "name": "location_ids", + "type": "uuid[]", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'inventory'" + }, + "options": { + "name": "options", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "progress_done": { + "name": "progress_done", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "progress_total": { + "name": "progress_total", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "bytes": { + "name": "bytes", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now() + interval '24 hours'" + }, + "email_when_done": { + "name": "email_when_done", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "report_runs_user_idx": { + "name": "report_runs_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "report_runs_expires_idx": { + "name": "report_runs_expires_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "report_runs_user_id_user_id_fk": { + "name": "report_runs_user_id_user_id_fk", + "tableFrom": "report_runs", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "report_runs_location_id_locations_id_fk": { + "name": "report_runs_location_id_locations_id_fk", + "tableFrom": "report_runs", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "report_runs_owner_account_id_owner_accounts_id_fk": { + "name": "report_runs_owner_account_id_owner_accounts_id_fk", + "tableFrom": "report_runs", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "report_runs_status_chk": { + "name": "report_runs_status_chk", + "value": "\"status\" IN ('queued', 'running', 'done', 'failed')" + }, + "report_runs_kind_chk": { + "name": "report_runs_kind_chk", + "value": "\"kind\" IN ('inventory', 'insurance', 'vehicle_history', 'condition', 'move')" + }, + "report_runs_scope_chk": { + "name": "report_runs_scope_chk", + "value": "num_nonnulls(location_id, owner_account_id) = 1" + }, + "report_runs_locations_chk": { + "name": "report_runs_locations_chk", + "value": "cardinality(location_ids) BETWEEN 1 AND 1000\n AND (location_id IS NULL OR location_ids = ARRAY[location_id])" + }, + "report_runs_thing_chk": { + "name": "report_runs_thing_chk", + "value": "(kind = 'vehicle_history') = (thing_id IS NOT NULL)\n AND (thing_id IS NULL OR location_id IS NOT NULL)" + }, + "report_runs_options_chk": { + "name": "report_runs_options_chk", + "value": "jsonb_typeof(options) = 'object'" + }, + "report_runs_progress_chk": { + "name": "report_runs_progress_chk", + "value": "progress_done >= 0 AND progress_total >= 0 AND progress_done <= progress_total" + }, + "report_runs_error_chk": { + "name": "report_runs_error_chk", + "value": "error ~ '^[a-z_]{1,32}$'" + }, + "report_runs_expires_chk": { + "name": "report_runs_expires_chk", + "value": "expires_at > created_at" + } + }, + "isRLSEnabled": false + }, + "public.report_schedules": { + "name": "report_schedules", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "cadence": { + "name": "cadence", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_run_on": { + "name": "last_run_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "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": { + "report_schedules_uq": { + "name": "report_schedules_uq", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "kind", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "concurrently": false + }, + "report_schedules_location_idx": { + "name": "report_schedules_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "report_schedules_user_id_user_id_fk": { + "name": "report_schedules_user_id_user_id_fk", + "tableFrom": "report_schedules", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "report_schedules_location_id_locations_id_fk": { + "name": "report_schedules_location_id_locations_id_fk", + "tableFrom": "report_schedules", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "report_schedules_kind_chk": { + "name": "report_schedules_kind_chk", + "value": "\"kind\" IN ('inventory', 'insurance')" + }, + "report_schedules_cadence_chk": { + "name": "report_schedules_cadence_chk", + "value": "\"cadence\" IN ('weekly', 'monthly')" + }, + "report_schedules_error_chk": { + "name": "report_schedules_error_chk", + "value": "last_error ~ '^[a-z_]{1,32}$'" + } + }, + "isRLSEnabled": false + }, + "public.room_captures": { + "name": "room_captures", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "container_id": { + "name": "container_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "batch_id": { + "name": "batch_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'reading'" + }, + "codes": { + "name": "codes", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "attachment_ids": { + "name": "attachment_ids", + "type": "uuid[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::uuid[]" + }, + "result": { + "name": "result", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "room_captures_location_idx": { + "name": "room_captures_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "room_captures_batch_idx": { + "name": "room_captures_batch_idx", + "columns": [ + { + "expression": "batch_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "room_captures_location_id_locations_id_fk": { + "name": "room_captures_location_id_locations_id_fk", + "tableFrom": "room_captures", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "room_captures_place_fk": { + "name": "room_captures_place_fk", + "tableFrom": "room_captures", + "columnsFrom": [ + "location_id", + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "room_captures_container_fk": { + "name": "room_captures_container_fk", + "tableFrom": "room_captures", + "columnsFrom": [ + "location_id", + "container_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "room_captures_location_id_uq": { + "name": "room_captures_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "room_captures_status_chk": { + "name": "room_captures_status_chk", + "value": "\"status\" IN ('reading', 'merging', 'ready', 'failed', 'off')" + }, + "room_captures_target_chk": { + "name": "room_captures_target_chk", + "value": "num_nonnulls(place_id, container_id) = 1" + }, + "room_captures_codes_chk": { + "name": "room_captures_codes_chk", + "value": "cardinality(codes) <= 60" + }, + "room_captures_photos_chk": { + "name": "room_captures_photos_chk", + "value": "cardinality(attachment_ids) BETWEEN 1 AND 5" + }, + "room_captures_result_chk": { + "name": "room_captures_result_chk", + "value": "result IS NULL OR jsonb_typeof(result) = 'object'" + } + }, + "isRLSEnabled": false + }, + "public.scan_session_lines": { + "name": "scan_session_lines", + "schema": "", + "columns": { + "session_id": { + "name": "session_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to_place_id": { + "name": "to_place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "to_container_id": { + "name": "to_container_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "was_place_id": { + "name": "was_place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "was_container_id": { + "name": "was_container_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "read_by": { + "name": "read_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "area_place_id": { + "name": "area_place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "found_qty": { + "name": "found_qty", + "type": "numeric(12, 3)", + "primaryKey": false, + "notNull": false + }, + "expected_qty": { + "name": "expected_qty", + "type": "numeric(12, 3)", + "primaryKey": false, + "notNull": false + }, + "short_not_here": { + "name": "short_not_here", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": { + "scan_session_lines_thing_idx": { + "name": "scan_session_lines_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "scan_session_lines_thing_id_things_id_fk": { + "name": "scan_session_lines_thing_id_things_id_fk", + "tableFrom": "scan_session_lines", + "columnsFrom": [ + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "scan_session_lines_to_place_id_places_id_fk": { + "name": "scan_session_lines_to_place_id_places_id_fk", + "tableFrom": "scan_session_lines", + "columnsFrom": [ + "to_place_id" + ], + "tableTo": "places", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "scan_session_lines_to_container_id_things_id_fk": { + "name": "scan_session_lines_to_container_id_things_id_fk", + "tableFrom": "scan_session_lines", + "columnsFrom": [ + "to_container_id" + ], + "tableTo": "things", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "scan_session_lines_was_place_id_places_id_fk": { + "name": "scan_session_lines_was_place_id_places_id_fk", + "tableFrom": "scan_session_lines", + "columnsFrom": [ + "was_place_id" + ], + "tableTo": "places", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "scan_session_lines_was_container_id_things_id_fk": { + "name": "scan_session_lines_was_container_id_things_id_fk", + "tableFrom": "scan_session_lines", + "columnsFrom": [ + "was_container_id" + ], + "tableTo": "things", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "scan_session_lines_area_place_id_places_id_fk": { + "name": "scan_session_lines_area_place_id_places_id_fk", + "tableFrom": "scan_session_lines", + "columnsFrom": [ + "area_place_id" + ], + "tableTo": "places", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "scan_session_lines_session_fk": { + "name": "scan_session_lines_session_fk", + "tableFrom": "scan_session_lines", + "columnsFrom": [ + "location_id", + "session_id" + ], + "tableTo": "scan_sessions", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "scan_session_lines_pk": { + "name": "scan_session_lines_pk", + "columns": [ + "session_id", + "thing_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "scan_session_lines_action_chk": { + "name": "scan_session_lines_action_chk", + "value": "\"action\" IN ('seen', 'not_here', 'move', 'missing', 'elsewhere', 'on_loan', 'in_repair', 'trashed', 'not_counted')" + }, + "scan_session_lines_to_chk": { + "name": "scan_session_lines_to_chk", + "value": "num_nonnulls(to_place_id, to_container_id) <= 1" + }, + "scan_session_lines_qty_chk": { + "name": "scan_session_lines_qty_chk", + "value": "(found_qty IS NULL OR found_qty > 0) AND (expected_qty IS NULL OR expected_qty >= 0)\n AND (NOT short_not_here OR found_qty IS NOT NULL)" + } + }, + "isRLSEnabled": false + }, + "public.scan_sessions": { + "name": "scan_sessions", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "mode": { + "name": "mode", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_place_id": { + "name": "target_place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "target_container_id": { + "name": "target_container_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "target_inside": { + "name": "target_inside", + "type": "boolean", + "primaryKey": false, + "notNull": false + }, + "started_by": { + "name": "started_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "expected": { + "name": "expected", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "seen": { + "name": "seen", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "not_here": { + "name": "not_here", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "moved": { + "name": "moved", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "skipped": { + "name": "skipped", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "missing": { + "name": "missing", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "elsewhere": { + "name": "elsewhere", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "on_loan": { + "name": "on_loan", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "in_repair": { + "name": "in_repair", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "not_counted": { + "name": "not_counted", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "counted_place_ids": { + "name": "counted_place_ids", + "type": "uuid[]", + "primaryKey": false, + "notNull": false + }, + "schedule_id": { + "name": "schedule_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "finished_by": { + "name": "finished_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "audit_event_id": { + "name": "audit_event_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scan_sessions_location_idx": { + "name": "scan_sessions_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "started_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "scan_sessions_schedule_idx": { + "name": "scan_sessions_schedule_idx", + "columns": [ + { + "expression": "schedule_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "scan_sessions_open_idx": { + "name": "scan_sessions_open_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "finished_at IS NULL", + "concurrently": false + } + }, + "foreignKeys": { + "scan_sessions_location_id_locations_id_fk": { + "name": "scan_sessions_location_id_locations_id_fk", + "tableFrom": "scan_sessions", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "scan_sessions_target_place_id_places_id_fk": { + "name": "scan_sessions_target_place_id_places_id_fk", + "tableFrom": "scan_sessions", + "columnsFrom": [ + "target_place_id" + ], + "tableTo": "places", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "scan_sessions_target_container_id_things_id_fk": { + "name": "scan_sessions_target_container_id_things_id_fk", + "tableFrom": "scan_sessions", + "columnsFrom": [ + "target_container_id" + ], + "tableTo": "things", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "scan_sessions_schedule_id_schedules_id_fk": { + "name": "scan_sessions_schedule_id_schedules_id_fk", + "tableFrom": "scan_sessions", + "columnsFrom": [ + "schedule_id" + ], + "tableTo": "schedules", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scan_sessions_location_id_uq": { + "name": "scan_sessions_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "scan_sessions_mode_chk": { + "name": "scan_sessions_mode_chk", + "value": "\"mode\" IN ('count', 'pack', 'move')" + }, + "scan_sessions_target_chk": { + "name": "scan_sessions_target_chk", + "value": "num_nonnulls(target_place_id, target_container_id) <= 1" + }, + "scan_sessions_totals_chk": { + "name": "scan_sessions_totals_chk", + "value": "seen >= 0 AND not_here >= 0 AND moved >= 0 AND skipped >= 0\n AND (expected IS NULL OR expected >= 0)\n AND (missing IS NULL OR missing >= 0) AND (elsewhere IS NULL OR elsewhere >= 0)\n AND (on_loan IS NULL OR on_loan >= 0) AND (in_repair IS NULL OR in_repair >= 0)\n AND (not_counted IS NULL OR not_counted >= 0)" + } + }, + "isRLSEnabled": false + }, + "public.expiring_documents": { + "name": "expiring_documents", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_on": { + "name": "expires_on", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "lead_days": { + "name": "lead_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 30 + }, + "superseded_by_id": { + "name": "superseded_by_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "issued_on": { + "name": "issued_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "currency": { + "name": "currency", + "type": "char(3)", + "primaryKey": false, + "notNull": false + }, + "cost": { + "name": "cost", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "expiring_documents_expires_idx": { + "name": "expiring_documents_expires_idx", + "columns": [ + { + "expression": "expires_on", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "superseded_by_id IS NULL", + "concurrently": false + }, + "expiring_documents_location_idx": { + "name": "expiring_documents_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "expiring_documents_thing_idx": { + "name": "expiring_documents_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "expiring_documents_place_idx": { + "name": "expiring_documents_place_idx", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "expiring_documents_location_id_locations_id_fk": { + "name": "expiring_documents_location_id_locations_id_fk", + "tableFrom": "expiring_documents", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "expiring_documents_currency_currencies_code_fk": { + "name": "expiring_documents_currency_currencies_code_fk", + "tableFrom": "expiring_documents", + "columnsFrom": [ + "currency" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "expiring_documents_thing_fk": { + "name": "expiring_documents_thing_fk", + "tableFrom": "expiring_documents", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "expiring_documents_place_fk": { + "name": "expiring_documents_place_fk", + "tableFrom": "expiring_documents", + "columnsFrom": [ + "location_id", + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "expiring_documents_location_id_uq": { + "name": "expiring_documents_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "expiring_documents_kind_chk": { + "name": "expiring_documents_kind_chk", + "value": "\"kind\" IN ('registration', 'insurance', 'licence', 'inspection', 'lease', 'contract', 'other')" + }, + "expiring_documents_cost_chk": { + "name": "expiring_documents_cost_chk", + "value": "(cost IS NULL) = (currency IS NULL) AND (cost IS NULL OR cost >= 0)" + }, + "expiring_documents_issued_chk": { + "name": "expiring_documents_issued_chk", + "value": "issued_on IS NULL OR issued_on <= expires_on" + }, + "expiring_documents_title_chk": { + "name": "expiring_documents_title_chk", + "value": "char_length(title) BETWEEN 1 AND 120" + }, + "expiring_documents_lead_days_chk": { + "name": "expiring_documents_lead_days_chk", + "value": "lead_days BETWEEN 0 AND 365" + }, + "expiring_documents_subject_chk": { + "name": "expiring_documents_subject_chk", + "value": "num_nonnulls(thing_id, place_id) <= 1" + }, + "expiring_documents_other_chk": { + "name": "expiring_documents_other_chk", + "value": "kind <> 'other' OR title IS NOT NULL" + }, + "expiring_documents_superseded_chk": { + "name": "expiring_documents_superseded_chk", + "value": "superseded_by_id IS DISTINCT FROM id" + } + }, + "isRLSEnabled": false + }, + "public.schedules": { + "name": "schedules", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'task'" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "every_months": { + "name": "every_months", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "every_units": { + "name": "every_units", + "type": "numeric(14, 3)", + "primaryKey": false, + "notNull": false + }, + "meter_id": { + "name": "meter_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "due_on": { + "name": "due_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "lead_days": { + "name": "lead_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 14 + }, + "lead_units": { + "name": "lead_units", + "type": "numeric(14, 3)", + "primaryKey": false, + "notNull": false + }, + "base_on": { + "name": "base_on", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "base_value": { + "name": "base_value", + "type": "numeric(14, 3)", + "primaryKey": false, + "notNull": false + }, + "anchor_on": { + "name": "anchor_on", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "anchor_value": { + "name": "anchor_value", + "type": "numeric(14, 3)", + "primaryKey": false, + "notNull": false + }, + "snoozed_until": { + "name": "snoozed_until", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "snoozed_until_value": { + "name": "snoozed_until_value", + "type": "numeric(14, 3)", + "primaryKey": false, + "notNull": false + }, + "skip_next": { + "name": "skip_next", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "schedules_one_count_uq": { + "name": "schedules_one_count_uq", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "kind = 'count' AND active", + "concurrently": false + }, + "schedules_thing_idx": { + "name": "schedules_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "schedules_place_idx": { + "name": "schedules_place_idx", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "schedules_location_idx": { + "name": "schedules_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "active", + "concurrently": false + } + }, + "foreignKeys": { + "schedules_location_id_locations_id_fk": { + "name": "schedules_location_id_locations_id_fk", + "tableFrom": "schedules", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "schedules_thing_fk": { + "name": "schedules_thing_fk", + "tableFrom": "schedules", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "schedules_place_fk": { + "name": "schedules_place_fk", + "tableFrom": "schedules", + "columnsFrom": [ + "location_id", + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "schedules_meter_fk": { + "name": "schedules_meter_fk", + "tableFrom": "schedules", + "columnsFrom": [ + "location_id", + "meter_id" + ], + "tableTo": "meters", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "schedules_location_id_uq": { + "name": "schedules_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "schedules_kind_chk": { + "name": "schedules_kind_chk", + "value": "\"kind\" IN ('task', 'count')" + }, + "schedules_count_chk": { + "name": "schedules_count_chk", + "value": "kind <> 'count' OR (place_id IS NOT NULL AND every_months BETWEEN 1 AND 24\n AND every_units IS NULL AND due_on IS NULL)" + }, + "schedules_name_chk": { + "name": "schedules_name_chk", + "value": "char_length(name) BETWEEN 1 AND 120" + }, + "schedules_every_months_chk": { + "name": "schedules_every_months_chk", + "value": "every_months BETWEEN 1 AND 600" + }, + "schedules_every_units_chk": { + "name": "schedules_every_units_chk", + "value": "every_units > 0" + }, + "schedules_lead_days_chk": { + "name": "schedules_lead_days_chk", + "value": "lead_days BETWEEN 0 AND 365" + }, + "schedules_lead_units_chk": { + "name": "schedules_lead_units_chk", + "value": "lead_units >= 0" + }, + "schedules_subject_chk": { + "name": "schedules_subject_chk", + "value": "num_nonnulls(thing_id, place_id) = 1" + }, + "schedules_rule_chk": { + "name": "schedules_rule_chk", + "value": "num_nonnulls(every_months, every_units, due_on) >= 1" + }, + "schedules_meter_chk": { + "name": "schedules_meter_chk", + "value": "(every_units IS NULL) = (meter_id IS NULL)" + }, + "schedules_meter_thing_chk": { + "name": "schedules_meter_thing_chk", + "value": "meter_id IS NULL OR thing_id IS NOT NULL" + }, + "schedules_one_off_chk": { + "name": "schedules_one_off_chk", + "value": "due_on IS NULL OR (every_months IS NULL AND every_units IS NULL)" + } + }, + "isRLSEnabled": false + }, + "public.service_completions": { + "name": "service_completions", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "service_record_id": { + "name": "service_record_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "schedule_id": { + "name": "schedule_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "service_completions_schedule_idx": { + "name": "service_completions_schedule_idx", + "columns": [ + { + "expression": "schedule_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "service_completions_record_fk": { + "name": "service_completions_record_fk", + "tableFrom": "service_completions", + "columnsFrom": [ + "location_id", + "service_record_id" + ], + "tableTo": "service_records", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "service_completions_schedule_fk": { + "name": "service_completions_schedule_fk", + "tableFrom": "service_completions", + "columnsFrom": [ + "location_id", + "schedule_id" + ], + "tableTo": "schedules", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "service_completions_pk": { + "name": "service_completions_pk", + "columns": [ + "service_record_id", + "schedule_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.secret_field_policies": { + "name": "secret_field_policies", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "type_field_id": { + "name": "type_field_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "reveal_roles": { + "name": "reveal_roles", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "ARRAY['owner', 'admin']::text[]" + }, + "reveal_user_ids": { + "name": "reveal_user_ids", + "type": "uuid[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::uuid[]" + }, + "ai_allowed": { + "name": "ai_allowed", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "secret_field_policies_location_id_locations_id_fk": { + "name": "secret_field_policies_location_id_locations_id_fk", + "tableFrom": "secret_field_policies", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "secret_field_policies_type_field_id_type_fields_id_fk": { + "name": "secret_field_policies_type_field_id_type_fields_id_fk", + "tableFrom": "secret_field_policies", + "columnsFrom": [ + "type_field_id" + ], + "tableTo": "type_fields", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "secret_field_policies_pk": { + "name": "secret_field_policies_pk", + "columns": [ + "location_id", + "type_field_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "secret_field_policies_roles_chk": { + "name": "secret_field_policies_roles_chk", + "value": "reveal_roles <@ ARRAY['owner', 'admin', 'member', 'viewer']::text[]" + } + }, + "isRLSEnabled": false + }, + "public.secret_values": { + "name": "secret_values", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "type_field_id": { + "name": "type_field_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "field_key": { + "name": "field_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "ciphertext": { + "name": "ciphertext", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "key_version": { + "name": "key_version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "updated_by": { + "name": "updated_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "superseded_at": { + "name": "superseded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "secret_values_thing_current_uq": { + "name": "secret_values_thing_current_uq", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "field_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "superseded_at IS NULL AND thing_id IS NOT NULL", + "concurrently": false + }, + "secret_values_place_current_uq": { + "name": "secret_values_place_current_uq", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "field_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "superseded_at IS NULL AND place_id IS NOT NULL", + "concurrently": false + }, + "secret_values_type_field_idx": { + "name": "secret_values_type_field_idx", + "columns": [ + { + "expression": "type_field_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "secret_values_key_version_idx": { + "name": "secret_values_key_version_idx", + "columns": [ + { + "expression": "key_version", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "secret_values_type_field_id_type_fields_id_fk": { + "name": "secret_values_type_field_id_type_fields_id_fk", + "tableFrom": "secret_values", + "columnsFrom": [ + "type_field_id" + ], + "tableTo": "type_fields", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "secret_values_thing_fk": { + "name": "secret_values_thing_fk", + "tableFrom": "secret_values", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "secret_values_place_fk": { + "name": "secret_values_place_fk", + "tableFrom": "secret_values", + "columnsFrom": [ + "location_id", + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "secret_values_one_subject_chk": { + "name": "secret_values_one_subject_chk", + "value": "num_nonnulls(thing_id, place_id) = 1" + }, + "secret_values_key_version_chk": { + "name": "secret_values_key_version_chk", + "value": "key_version > 0" + }, + "secret_values_ciphertext_chk": { + "name": "secret_values_ciphertext_chk", + "value": "ciphertext IS NULL OR jsonb_typeof(ciphertext) = 'object'" + } + }, + "isRLSEnabled": false + }, + "public.service_lines": { + "name": "service_lines", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "service_record_id": { + "name": "service_record_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "quantity": { + "name": "quantity", + "type": "numeric(12, 3)", + "primaryKey": false, + "notNull": false + }, + "unit_cost": { + "name": "unit_cost", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": false + }, + "sort": { + "name": "sort", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "consumable_thing_id": { + "name": "consumable_thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "consumed_quantity": { + "name": "consumed_quantity", + "type": "numeric(12, 3)", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "service_lines_record_idx": { + "name": "service_lines_record_idx", + "columns": [ + { + "expression": "service_record_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sort", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "service_lines_consumable_idx": { + "name": "service_lines_consumable_idx", + "columns": [ + { + "expression": "consumable_thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "consumable_thing_id IS NOT NULL", + "concurrently": false + } + }, + "foreignKeys": { + "service_lines_record_fk": { + "name": "service_lines_record_fk", + "tableFrom": "service_lines", + "columnsFrom": [ + "location_id", + "service_record_id" + ], + "tableTo": "service_records", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "service_lines_kind_chk": { + "name": "service_lines_kind_chk", + "value": "\"kind\" IN ('part', 'labour', 'fluid', 'other')" + }, + "service_lines_description_chk": { + "name": "service_lines_description_chk", + "value": "char_length(description) BETWEEN 1 AND 300" + }, + "service_lines_quantity_chk": { + "name": "service_lines_quantity_chk", + "value": "quantity > 0" + }, + "service_lines_unit_cost_chk": { + "name": "service_lines_unit_cost_chk", + "value": "unit_cost >= 0" + }, + "service_lines_consumed_chk": { + "name": "service_lines_consumed_chk", + "value": "consumed_quantity > 0" + } + }, + "isRLSEnabled": false + }, + "public.service_records": { + "name": "service_records", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "serviced_on": { + "name": "serviced_on", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "meter_reading_id": { + "name": "meter_reading_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "vendor_id": { + "name": "vendor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "total": { + "name": "total", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": false + }, + "currency": { + "name": "currency", + "type": "char(3)", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "logged_by": { + "name": "logged_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "review_state": { + "name": "review_state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'confirmed'" + }, + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "service_records_thing_idx": { + "name": "service_records_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "serviced_on", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "service_records_place_idx": { + "name": "service_records_place_idx", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "serviced_on", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "service_records_reading_idx": { + "name": "service_records_reading_idx", + "columns": [ + { + "expression": "meter_reading_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "service_records_vendor_idx": { + "name": "service_records_vendor_idx", + "columns": [ + { + "expression": "vendor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "service_records_reading_uq": { + "name": "service_records_reading_uq", + "columns": [ + { + "expression": "meter_reading_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "meter_reading_id IS NOT NULL", + "concurrently": false + }, + "service_records_drafts_idx": { + "name": "service_records_drafts_idx", + "columns": [ + { + "expression": "logged_by", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "review_state = 'draft'", + "concurrently": false + } + }, + "foreignKeys": { + "service_records_location_id_locations_id_fk": { + "name": "service_records_location_id_locations_id_fk", + "tableFrom": "service_records", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "service_records_currency_currencies_code_fk": { + "name": "service_records_currency_currencies_code_fk", + "tableFrom": "service_records", + "columnsFrom": [ + "currency" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "service_records_thing_fk": { + "name": "service_records_thing_fk", + "tableFrom": "service_records", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "service_records_place_fk": { + "name": "service_records_place_fk", + "tableFrom": "service_records", + "columnsFrom": [ + "location_id", + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "service_records_location_id_uq": { + "name": "service_records_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "service_records_review_state_chk": { + "name": "service_records_review_state_chk", + "value": "\"review_state\" IN ('draft', 'confirmed')" + }, + "service_records_subject_chk": { + "name": "service_records_subject_chk", + "value": "num_nonnulls(thing_id, place_id) = 1" + }, + "service_records_money_chk": { + "name": "service_records_money_chk", + "value": "(total IS NULL) = (currency IS NULL)" + }, + "service_records_total_chk": { + "name": "service_records_total_chk", + "value": "total >= 0" + }, + "service_records_notes_chk": { + "name": "service_records_notes_chk", + "value": "char_length(notes) <= 5000" + } + }, + "isRLSEnabled": false + }, + "public.share_links": { + "name": "share_links", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "scope_type": { + "name": "scope_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "filter": { + "name": "filter", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "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_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "views": { + "name": "views", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_viewed_at": { + "name": "last_viewed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "share_links_location_idx": { + "name": "share_links_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "share_links_thing_idx": { + "name": "share_links_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "share_links_place_idx": { + "name": "share_links_place_idx", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "share_links_location_id_locations_id_fk": { + "name": "share_links_location_id_locations_id_fk", + "tableFrom": "share_links", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "share_links_thing_id_things_id_fk": { + "name": "share_links_thing_id_things_id_fk", + "tableFrom": "share_links", + "columnsFrom": [ + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "share_links_place_id_places_id_fk": { + "name": "share_links_place_id_places_id_fk", + "tableFrom": "share_links", + "columnsFrom": [ + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "share_links_token_hash_uq": { + "name": "share_links_token_hash_uq", + "columns": [ + "token_hash" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "share_links_scope_type_chk": { + "name": "share_links_scope_type_chk", + "value": "\"scope_type\" IN ('thing', 'place', 'view')" + }, + "share_links_token_hash_chk": { + "name": "share_links_token_hash_chk", + "value": "token_hash ~ '^[0-9a-f]{64}$'" + }, + "share_links_subject_chk": { + "name": "share_links_subject_chk", + "value": "CASE scope_type\n WHEN 'thing' THEN thing_id IS NOT NULL AND place_id IS NULL AND filter IS NULL\n WHEN 'place' THEN place_id IS NOT NULL AND thing_id IS NULL AND filter IS NULL\n ELSE filter IS NOT NULL AND thing_id IS NULL AND place_id IS NULL\n AND title IS NOT NULL END" + }, + "share_links_filter_chk": { + "name": "share_links_filter_chk", + "value": "filter IS NULL OR jsonb_typeof(filter) = 'object'" + }, + "share_links_title_chk": { + "name": "share_links_title_chk", + "value": "title IS NULL OR char_length(title) BETWEEN 1 AND 120" + }, + "share_links_expiry_chk": { + "name": "share_links_expiry_chk", + "value": "expires_at > created_at AND expires_at <= created_at + interval '1 year'" + }, + "share_links_views_chk": { + "name": "share_links_views_chk", + "value": "views >= 0" + } + }, + "isRLSEnabled": false + }, + "public.box_check_lines": { + "name": "box_check_lines", + "schema": "", + "columns": { + "box_check_id": { + "name": "box_check_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "expected_qty": { + "name": "expected_qty", + "type": "numeric(12, 3)", + "primaryKey": false, + "notNull": true + }, + "found_qty": { + "name": "found_qty", + "type": "numeric(12, 3)", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "box_check_lines_thing_idx": { + "name": "box_check_lines_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "box_check_lines_check_fk": { + "name": "box_check_lines_check_fk", + "tableFrom": "box_check_lines", + "columnsFrom": [ + "location_id", + "box_check_id" + ], + "tableTo": "box_checks", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "box_check_lines_thing_fk": { + "name": "box_check_lines_thing_fk", + "tableFrom": "box_check_lines", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "box_check_lines_pk": { + "name": "box_check_lines_pk", + "columns": [ + "box_check_id", + "thing_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "box_check_lines_expected_chk": { + "name": "box_check_lines_expected_chk", + "value": "expected_qty >= 0" + }, + "box_check_lines_found_chk": { + "name": "box_check_lines_found_chk", + "value": "found_qty >= 0" + } + }, + "isRLSEnabled": false + }, + "public.box_checks": { + "name": "box_checks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "container_id": { + "name": "container_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "checked_by": { + "name": "checked_by", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "checked_at": { + "name": "checked_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": { + "box_checks_container_idx": { + "name": "box_checks_container_idx", + "columns": [ + { + "expression": "container_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "checked_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "box_checks_location_id_locations_id_fk": { + "name": "box_checks_location_id_locations_id_fk", + "tableFrom": "box_checks", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "box_checks_container_fk": { + "name": "box_checks_container_fk", + "tableFrom": "box_checks", + "columnsFrom": [ + "location_id", + "container_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "box_checks_location_id_uq": { + "name": "box_checks_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.legacy_codes": { + "name": "legacy_codes", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_collection": { + "name": "source_collection", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "code": { + "name": "code", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "change_xid": { + "name": "change_xid", + "type": "xid8", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "legacy_codes_code_idx": { + "name": "legacy_codes_code_idx", + "columns": [ + { + "expression": "source", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "legacy_codes_any_code_idx": { + "name": "legacy_codes_any_code_idx", + "columns": [ + { + "expression": "code", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "legacy_codes_thing_idx": { + "name": "legacy_codes_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "legacy_codes_place_idx": { + "name": "legacy_codes_place_idx", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "legacy_codes_sync_idx": { + "name": "legacy_codes_sync_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "change_xid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "legacy_codes_location_id_locations_id_fk": { + "name": "legacy_codes_location_id_locations_id_fk", + "tableFrom": "legacy_codes", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "legacy_codes_thing_fk": { + "name": "legacy_codes_thing_fk", + "tableFrom": "legacy_codes", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "legacy_codes_place_fk": { + "name": "legacy_codes_place_fk", + "tableFrom": "legacy_codes", + "columnsFrom": [ + "location_id", + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "legacy_codes_pk": { + "name": "legacy_codes_pk", + "columns": [ + "location_id", + "source", + "source_collection", + "code" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "legacy_codes_source_chk": { + "name": "legacy_codes_source_chk", + "value": "\"source\" IN ('homebox', 'csv', 'own', 'kept')" + }, + "legacy_codes_collection_chk": { + "name": "legacy_codes_collection_chk", + "value": "char_length(source_collection) <= 100" + }, + "legacy_codes_code_chk": { + "name": "legacy_codes_code_chk", + "value": "char_length(code) BETWEEN 1 AND 100 AND code = upper(btrim(code))" + }, + "legacy_codes_target_chk": { + "name": "legacy_codes_target_chk", + "value": "num_nonnulls(thing_id, place_id) = 1" + } + }, + "isRLSEnabled": false + }, + "public.own_code_counters": { + "name": "own_code_counters", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_number": { + "name": "last_number", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "own_code_counters_location_id_locations_id_fk": { + "name": "own_code_counters_location_id_locations_id_fk", + "tableFrom": "own_code_counters", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "own_code_counters_pk": { + "name": "own_code_counters_pk", + "columns": [ + "location_id", + "prefix" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "own_code_counters_number_chk": { + "name": "own_code_counters_number_chk", + "value": "last_number >= 0" + } + }, + "isRLSEnabled": false + }, + "public.own_code_settings": { + "name": "own_code_settings", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "numbering": { + "name": "numbering", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "pad": { + "name": "pad", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 4 + }, + "rule_pattern": { + "name": "rule_pattern", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rule_message": { + "name": "rule_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rule_example": { + "name": "rule_example", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "own_code_settings_location_id_locations_id_fk": { + "name": "own_code_settings_location_id_locations_id_fk", + "tableFrom": "own_code_settings", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "own_code_settings_prefix_chk": { + "name": "own_code_settings_prefix_chk", + "value": "char_length(prefix) <= 20 AND prefix = upper(btrim(prefix))" + }, + "own_code_settings_pad_chk": { + "name": "own_code_settings_pad_chk", + "value": "pad BETWEEN 1 AND 8" + }, + "own_code_settings_rule_chk": { + "name": "own_code_settings_rule_chk", + "value": "num_nonnulls(rule_pattern, rule_message, rule_example) IN (0, 3)\n AND char_length(rule_pattern) BETWEEN 1 AND 200\n AND char_length(rule_message) BETWEEN 1 AND 200\n AND char_length(rule_example) BETWEEN 1 AND 100" + } + }, + "isRLSEnabled": false + }, + "public.sync_ops": { + "name": "sync_ops", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "client_id": { + "name": "client_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "op": { + "name": "op", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload_version": { + "name": "payload_version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "client_version": { + "name": "client_version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "taken_at": { + "name": "taken_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "received_at": { + "name": "received_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "outcome": { + "name": "outcome", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "result": { + "name": "result", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + } + }, + "indexes": { + "sync_ops_received_idx": { + "name": "sync_ops_received_idx", + "columns": [ + { + "expression": "received_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "sync_ops_user_id_user_id_fk": { + "name": "sync_ops_user_id_user_id_fk", + "tableFrom": "sync_ops", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "sync_ops_location_id_locations_id_fk": { + "name": "sync_ops_location_id_locations_id_fk", + "tableFrom": "sync_ops", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "sync_ops_pk": { + "name": "sync_ops_pk", + "columns": [ + "user_id", + "idempotency_key" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "sync_ops_op_chk": { + "name": "sync_ops_op_chk", + "value": "\"op\" IN ('create_thing', 'move', 'log_reading', 'claim_label', 'mark_seen', 'not_here', 'create_area', 'box_check', 'move_box', 'move_box_room', 'scan_session_lines', 'scan_session_finish', 'tag_things')" + }, + "sync_ops_outcome_chk": { + "name": "sync_ops_outcome_chk", + "value": "\"outcome\" IN ('applied', 'needs_review', 'dropped')" + }, + "sync_ops_key_chk": { + "name": "sync_ops_key_chk", + "value": "idempotency_key ~ '^[A-Za-z0-9_.:-]{8,200}$'" + }, + "sync_ops_payload_version_chk": { + "name": "sync_ops_payload_version_chk", + "value": "payload_version > 0" + }, + "sync_ops_client_version_chk": { + "name": "sync_ops_client_version_chk", + "value": "char_length(client_version) BETWEEN 1 AND 40" + }, + "sync_ops_request_hash_chk": { + "name": "sync_ops_request_hash_chk", + "value": "request_hash ~ '^[0-9a-f]{64}$'" + }, + "sync_ops_reason_chk": { + "name": "sync_ops_reason_chk", + "value": "char_length(reason) <= 60" + }, + "sync_ops_result_chk": { + "name": "sync_ops_result_chk", + "value": "jsonb_typeof(result) = 'object'" + } + }, + "isRLSEnabled": false + }, + "public.idempotency_keys": { + "name": "idempotency_keys", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "response": { + "name": "response", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "idempotency_keys_user_id_user_id_fk": { + "name": "idempotency_keys_user_id_user_id_fk", + "tableFrom": "idempotency_keys", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "idempotency_keys_user_id_key_pk": { + "name": "idempotency_keys_user_id_key_pk", + "columns": [ + "user_id", + "key" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.instance_admins": { + "name": "instance_admins", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "granted_by": { + "name": "granted_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "granted_at": { + "name": "granted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "instance_admins_user_id_user_id_fk": { + "name": "instance_admins_user_id_user_id_fk", + "tableFrom": "instance_admins", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "instance_admins_granted_by_user_id_fk": { + "name": "instance_admins_granted_by_user_id_fk", + "tableFrom": "instance_admins", + "columnsFrom": [ + "granted_by" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.instance_settings": { + "name": "instance_settings", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "jsonb", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "instance_settings_values_chk": { + "name": "instance_settings_values_chk", + "value": "CASE key\n WHEN 'embeddings_source' THEN jsonb_typeof(value) = 'string'\n AND value #>> '{}' IN ('provider', 'local', 'off')\n WHEN 'assistant_thread_days' THEN jsonb_typeof(value) = 'number'\n AND (value #>> '{}')::numeric BETWEEN 7 AND 365\n WHEN 'oidc_config_hash' THEN jsonb_typeof(value) = 'string'\n AND value #>> '{}' ~ '^[0-9a-f]{64}$'\n WHEN 'smtp_config_hash' THEN jsonb_typeof(value) = 'string'\n AND value #>> '{}' ~ '^[0-9a-f]{64}$'\n ELSE true END" + } + }, + "isRLSEnabled": false + }, + "public.invites": { + "name": "invites", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "membership_expires_at": { + "name": "membership_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "accepted_by": { + "name": "accepted_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "claimed_at": { + "name": "claimed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "claimed_email": { + "name": "claimed_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "invites_location_idx": { + "name": "invites_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "invites_location_id_locations_id_fk": { + "name": "invites_location_id_locations_id_fk", + "tableFrom": "invites", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "invites_created_by_user_id_fk": { + "name": "invites_created_by_user_id_fk", + "tableFrom": "invites", + "columnsFrom": [ + "created_by" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "invites_accepted_by_user_id_fk": { + "name": "invites_accepted_by_user_id_fk", + "tableFrom": "invites", + "columnsFrom": [ + "accepted_by" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "invites_token_hash_unique": { + "name": "invites_token_hash_unique", + "columns": [ + "token_hash" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "invites_role_chk": { + "name": "invites_role_chk", + "value": "\"role\" IN ('admin', 'member', 'viewer')" + } + }, + "isRLSEnabled": false + }, + "public.location_modules": { + "name": "location_modules", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "module": { + "name": "module", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "enabled_at": { + "name": "enabled_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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "location_modules_location_id_locations_id_fk": { + "name": "location_modules_location_id_locations_id_fk", + "tableFrom": "location_modules", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "location_modules_location_id_module_pk": { + "name": "location_modules_location_id_module_pk", + "columns": [ + "location_id", + "module" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "location_modules_module_chk": { + "name": "location_modules_module_chk", + "value": "module ~ '^[a-z][a-z0-9_]*$'" + } + }, + "isRLSEnabled": false + }, + "public.locations": { + "name": "locations", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "owner_account_id": { + "name": "owner_account_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timezone": { + "name": "timezone", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "currency": { + "name": "currency", + "type": "char(3)", + "primaryKey": false, + "notNull": true + }, + "languages": { + "name": "languages", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "address": { + "name": "address", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "latitude": { + "name": "latitude", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "longitude": { + "name": "longitude", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "suggest_radius_m": { + "name": "suggest_radius_m", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 150 + }, + "preset": { + "name": "preset", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'household'" + }, + "money_visible_to_viewers": { + "name": "money_visible_to_viewers", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "require_2fa": { + "name": "require_2fa", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "long_unseen_months": { + "name": "long_unseen_months", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 12 + }, + "keep_room_photos": { + "name": "keep_room_photos", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "successor_user_id": { + "name": "successor_user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "purge_after": { + "name": "purge_after", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "locations_one_personal_uq": { + "name": "locations_one_personal_uq", + "columns": [ + { + "expression": "owner_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "kind = 'personal'", + "concurrently": false + }, + "locations_owner_account_idx": { + "name": "locations_owner_account_idx", + "columns": [ + { + "expression": "owner_account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "locations_owner_account_id_owner_accounts_id_fk": { + "name": "locations_owner_account_id_owner_accounts_id_fk", + "tableFrom": "locations", + "columnsFrom": [ + "owner_account_id" + ], + "tableTo": "owner_accounts", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "restrict" + }, + "locations_currency_currencies_code_fk": { + "name": "locations_currency_currencies_code_fk", + "tableFrom": "locations", + "columnsFrom": [ + "currency" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "locations_successor_user_id_user_id_fk": { + "name": "locations_successor_user_id_user_id_fk", + "tableFrom": "locations", + "columnsFrom": [ + "successor_user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "locations_id_owner_account_uq": { + "name": "locations_id_owner_account_uq", + "columns": [ + "id", + "owner_account_id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "locations_kind_chk": { + "name": "locations_kind_chk", + "value": "\"kind\" IN ('personal', 'home', 'apartment', 'garage', 'storage_unit', 'office', 'vacation_home', 'custom')" + }, + "locations_preset_chk": { + "name": "locations_preset_chk", + "value": "\"preset\" IN ('essentials', 'household', 'complete')" + }, + "locations_latitude_chk": { + "name": "locations_latitude_chk", + "value": "latitude BETWEEN -90 AND 90" + }, + "locations_longitude_chk": { + "name": "locations_longitude_chk", + "value": "longitude BETWEEN -180 AND 180" + }, + "locations_suggest_radius_chk": { + "name": "locations_suggest_radius_chk", + "value": "suggest_radius_m > 0" + }, + "locations_long_unseen_chk": { + "name": "locations_long_unseen_chk", + "value": "long_unseen_months > 0" + }, + "locations_purge_needs_delete_chk": { + "name": "locations_purge_needs_delete_chk", + "value": "purge_after IS NULL OR deleted_at IS NOT NULL" + } + }, + "isRLSEnabled": false + }, + "public.memberships": { + "name": "memberships", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "invited_by": { + "name": "invited_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "memberships_one_owner_uq": { + "name": "memberships_one_owner_uq", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "role = 'owner'", + "concurrently": false + }, + "memberships_user_idx": { + "name": "memberships_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "memberships_location_id_locations_id_fk": { + "name": "memberships_location_id_locations_id_fk", + "tableFrom": "memberships", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "memberships_user_id_user_id_fk": { + "name": "memberships_user_id_user_id_fk", + "tableFrom": "memberships", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "memberships_invited_by_user_id_fk": { + "name": "memberships_invited_by_user_id_fk", + "tableFrom": "memberships", + "columnsFrom": [ + "invited_by" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "memberships_location_user_uq": { + "name": "memberships_location_user_uq", + "columns": [ + "location_id", + "user_id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "memberships_role_chk": { + "name": "memberships_role_chk", + "value": "\"role\" IN ('owner', 'admin', 'member', 'viewer')" + }, + "memberships_owner_no_expiry_chk": { + "name": "memberships_owner_no_expiry_chk", + "value": "role <> 'owner' OR expires_at IS NULL" + } + }, + "isRLSEnabled": false + }, + "public.owner_accounts": { + "name": "owner_accounts", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "owner_accounts_user_id_user_id_fk": { + "name": "owner_accounts_user_id_user_id_fk", + "tableFrom": "owner_accounts", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "owner_accounts_user_id_unique": { + "name": "owner_accounts_user_id_unique", + "columns": [ + "user_id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sync_tombstones": { + "name": "sync_tombstones", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "entity_type": { + "name": "entity_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entity_id": { + "name": "entity_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "entity_key": { + "name": "entity_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "change_xid": { + "name": "change_xid", + "type": "xid8", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "sync_tombstones_change_seq_idx": { + "name": "sync_tombstones_change_seq_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "change_seq", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "sync_tombstones_sync_idx": { + "name": "sync_tombstones_sync_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "change_xid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "sync_tombstones_location_id_locations_id_fk": { + "name": "sync_tombstones_location_id_locations_id_fk", + "tableFrom": "sync_tombstones", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "sync_tombstones_location_id_entity_type_entity_id_pk": { + "name": "sync_tombstones_location_id_entity_type_entity_id_pk", + "columns": [ + "location_id", + "entity_type", + "entity_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "sync_tombstones_key_chk": { + "name": "sync_tombstones_key_chk", + "value": "(entity_type IN ('code', 'legacy_code')) = (entity_key IS NOT NULL)\n AND (entity_key IS NULL\n OR (char_length(entity_key) <= 400 AND entity_id = md5(entity_key)::uuid))" + } + }, + "isRLSEnabled": false + }, + "public.user_hidden_modules": { + "name": "user_hidden_modules", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "module": { + "name": "module", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "user_hidden_modules_user_id_user_id_fk": { + "name": "user_hidden_modules_user_id_user_id_fk", + "tableFrom": "user_hidden_modules", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "user_hidden_modules_location_id_locations_id_fk": { + "name": "user_hidden_modules_location_id_locations_id_fk", + "tableFrom": "user_hidden_modules", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "user_hidden_modules_user_id_location_id_module_pk": { + "name": "user_hidden_modules_user_id_location_id_module_pk", + "columns": [ + "user_id", + "location_id", + "module" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "user_hidden_modules_module_chk": { + "name": "user_hidden_modules_module_chk", + "value": "module ~ '^[a-z][a-z0-9_]*$'" + } + }, + "isRLSEnabled": false + }, + "public.user_profiles": { + "name": "user_profiles", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": true, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "timezone": { + "name": "timezone", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'UTC'" + }, + "locale": { + "name": "locale", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'en'" + }, + "units": { + "name": "units", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'metric'" + }, + "theme": { + "name": "theme", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'system'" + }, + "digits": { + "name": "digits", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'western'" + }, + "suggest_location": { + "name": "suggest_location", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hide_personal": { + "name": "hide_personal", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "digest_time": { + "name": "digest_time", + "type": "time", + "primaryKey": false, + "notNull": false + }, + "quiet_from": { + "name": "quiet_from", + "type": "time", + "primaryKey": false, + "notNull": false + }, + "quiet_to": { + "name": "quiet_to", + "type": "time", + "primaryKey": false, + "notNull": false + }, + "managed": { + "name": "managed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "created_in_location_id": { + "name": "created_in_location_id", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_profiles_user_id_user_id_fk": { + "name": "user_profiles_user_id_user_id_fk", + "tableFrom": "user_profiles", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "user_profiles_created_by_user_id_user_id_fk": { + "name": "user_profiles_created_by_user_id_user_id_fk", + "tableFrom": "user_profiles", + "columnsFrom": [ + "created_by_user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "user_profiles_created_in_location_id_locations_id_fk": { + "name": "user_profiles_created_in_location_id_locations_id_fk", + "tableFrom": "user_profiles", + "columnsFrom": [ + "created_in_location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "user_profiles_units_chk": { + "name": "user_profiles_units_chk", + "value": "\"units\" IN ('metric', 'imperial')" + }, + "user_profiles_theme_chk": { + "name": "user_profiles_theme_chk", + "value": "\"theme\" IN ('system', 'light', 'dark')" + }, + "user_profiles_digits_chk": { + "name": "user_profiles_digits_chk", + "value": "\"digits\" IN ('western', 'eastern')" + } + }, + "isRLSEnabled": false + }, + "public.short_ids": { + "name": "short_ids", + "schema": "", + "columns": { + "code": { + "name": "code", + "type": "char(6)", + "primaryKey": true, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'assigned'" + }, + "is_primary": { + "name": "is_primary", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "printed_at": { + "name": "printed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "claimed_at": { + "name": "claimed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "claimed_by": { + "name": "claimed_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "change_xid": { + "name": "change_xid", + "type": "xid8", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "short_ids_primary_thing_uq": { + "name": "short_ids_primary_thing_uq", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "is_primary AND state = 'assigned'", + "concurrently": false + }, + "short_ids_primary_place_uq": { + "name": "short_ids_primary_place_uq", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "is_primary AND state = 'assigned'", + "concurrently": false + }, + "short_ids_thing_idx": { + "name": "short_ids_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "short_ids_place_idx": { + "name": "short_ids_place_idx", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "short_ids_location_idx": { + "name": "short_ids_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "short_ids_sync_idx": { + "name": "short_ids_sync_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "change_xid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "short_ids_state_chk": { + "name": "short_ids_state_chk", + "value": "\"state\" IN ('blank', 'assigned', 'retired')" + }, + "short_ids_code_chk": { + "name": "short_ids_code_chk", + "value": "code ~ '^[0-9A-HJKMNP-TV-Z]{6}$'" + }, + "short_ids_target_chk": { + "name": "short_ids_target_chk", + "value": "CASE state WHEN 'blank' THEN num_nonnulls(thing_id, place_id) = 0\n WHEN 'assigned' THEN num_nonnulls(thing_id, place_id) = 1\n ELSE num_nonnulls(thing_id, place_id) <= 1 END" + } + }, + "isRLSEnabled": false + }, + "public.thing_links": { + "name": "thing_links", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "from_thing_id": { + "name": "from_thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "to_thing_id": { + "name": "to_thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "thing_links_to_idx": { + "name": "thing_links_to_idx", + "columns": [ + { + "expression": "to_thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "thing_links_from_fk": { + "name": "thing_links_from_fk", + "tableFrom": "thing_links", + "columnsFrom": [ + "location_id", + "from_thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + }, + "thing_links_to_fk": { + "name": "thing_links_to_fk", + "tableFrom": "thing_links", + "columnsFrom": [ + "location_id", + "to_thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "thing_links_uq": { + "name": "thing_links_uq", + "columns": [ + "from_thing_id", + "to_thing_id", + "kind" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "thing_links_kind_chk": { + "name": "thing_links_kind_chk", + "value": "\"kind\" IN ('accessory_of', 'spare_part_for', 'consumable_for', 'bundled_with', 'replaces', 'related')" + }, + "thing_links_not_self_chk": { + "name": "thing_links_not_self_chk", + "value": "from_thing_id <> to_thing_id" + } + }, + "isRLSEnabled": false + }, + "public.thing_tags": { + "name": "thing_tags", + "schema": "", + "columns": { + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "tag_id": { + "name": "tag_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "thing_tags_tag_idx": { + "name": "thing_tags_tag_idx", + "columns": [ + { + "expression": "tag_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "thing_tags_tag_id_tags_id_fk": { + "name": "thing_tags_tag_id_tags_id_fk", + "tableFrom": "thing_tags", + "columnsFrom": [ + "tag_id" + ], + "tableTo": "tags", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "thing_tags_thing_fk": { + "name": "thing_tags_thing_fk", + "tableFrom": "thing_tags", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "thing_tags_pk": { + "name": "thing_tags_pk", + "columns": [ + "thing_id", + "tag_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.things": { + "name": "things", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "container_id": { + "name": "container_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "type_id": { + "name": "type_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "brand_id": { + "name": "brand_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serial": { + "name": "serial", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "barcode": { + "name": "barcode", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "colour": { + "name": "colour", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "quantity": { + "name": "quantity", + "type": "numeric(12, 3)", + "primaryKey": false, + "notNull": true, + "default": "'1'" + }, + "condition": { + "name": "condition", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "aliases": { + "name": "aliases", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "belongs_to_person_id": { + "name": "belongs_to_person_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "purchase_line_id": { + "name": "purchase_line_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "manual_url": { + "name": "manual_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_on": { + "name": "expires_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "expiry_lead_days": { + "name": "expiry_lead_days", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "lifecycle": { + "name": "lifecycle", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'in_use'" + }, + "ended_on": { + "name": "ended_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "ended_price": { + "name": "ended_price", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": false + }, + "ended_currency": { + "name": "ended_currency", + "type": "char(3)", + "primaryKey": false, + "notNull": false + }, + "ended_to": { + "name": "ended_to", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ended_notes": { + "name": "ended_notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "acquired_from": { + "name": "acquired_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provenance_notes": { + "name": "provenance_notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rack_units": { + "name": "rack_units", + "type": "numeric(3, 1)", + "primaryKey": false, + "notNull": false + }, + "rack_at": { + "name": "rack_at", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "location_uncertain": { + "name": "location_uncertain", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "custom": { + "name": "custom", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "archived_custom": { + "name": "archived_custom", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "field_status": { + "name": "field_status", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "review_state": { + "name": "review_state", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'confirmed'" + }, + "created_via": { + "name": "created_via", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'app'" + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "split_from_id": { + "name": "split_from_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "place_path": { + "name": "place_path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "search_tsv": { + "name": "search_tsv", + "type": "tsvector", + "primaryKey": false, + "notNull": false + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "trash_batch_id": { + "name": "trash_batch_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "capture_batch_id": { + "name": "capture_batch_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "merged_into_id": { + "name": "merged_into_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "cover_file_id": { + "name": "cover_file_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "meter_version": { + "name": "meter_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "state_version": { + "name": "state_version", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "change_xid": { + "name": "change_xid", + "type": "xid8", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "things_purchase_line_idx": { + "name": "things_purchase_line_idx", + "columns": [ + { + "expression": "purchase_line_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "things_place_idx": { + "name": "things_place_idx", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "things_container_idx": { + "name": "things_container_idx", + "columns": [ + { + "expression": "container_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "things_type_idx": { + "name": "things_type_idx", + "columns": [ + { + "expression": "type_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "things_brand_idx": { + "name": "things_brand_idx", + "columns": [ + { + "expression": "brand_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "things_person_idx": { + "name": "things_person_idx", + "columns": [ + { + "expression": "belongs_to_person_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "things_barcode_idx": { + "name": "things_barcode_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "barcode", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "things_serial_exact_idx": { + "name": "things_serial_exact_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "serial", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "things_last_seen_idx": { + "name": "things_last_seen_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "last_seen_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "lifecycle = 'in_use' AND deleted_at IS NULL", + "concurrently": false + }, + "things_uncertain_idx": { + "name": "things_uncertain_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "location_uncertain", + "concurrently": false + }, + "things_draft_idx": { + "name": "things_draft_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "review_state = 'draft'", + "concurrently": false + }, + "things_expires_idx": { + "name": "things_expires_idx", + "columns": [ + { + "expression": "expires_on", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "expires_on IS NOT NULL", + "concurrently": false + }, + "things_trash_idx": { + "name": "things_trash_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "deleted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "deleted_at IS NOT NULL", + "concurrently": false + }, + "things_trash_purge_idx": { + "name": "things_trash_purge_idx", + "columns": [ + { + "expression": "deleted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "deleted_at IS NOT NULL", + "concurrently": false + }, + "things_created_by_idx": { + "name": "things_created_by_idx", + "columns": [ + { + "expression": "created_by", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "deleted_at IS NULL", + "concurrently": false + }, + "things_capture_batch_idx": { + "name": "things_capture_batch_idx", + "columns": [ + { + "expression": "created_by", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "capture_batch_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "deleted_at IS NULL", + "concurrently": false + }, + "things_merged_into_idx": { + "name": "things_merged_into_idx", + "columns": [ + { + "expression": "merged_into_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "merged_into_id IS NOT NULL", + "concurrently": false + }, + "things_sync_idx": { + "name": "things_sync_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "change_xid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "things_location_id_locations_id_fk": { + "name": "things_location_id_locations_id_fk", + "tableFrom": "things", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "things_type_id_types_id_fk": { + "name": "things_type_id_types_id_fk", + "tableFrom": "things", + "columnsFrom": [ + "type_id" + ], + "tableTo": "types", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "things_brand_id_brands_id_fk": { + "name": "things_brand_id_brands_id_fk", + "tableFrom": "things", + "columnsFrom": [ + "brand_id" + ], + "tableTo": "brands", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "things_belongs_to_person_id_people_id_fk": { + "name": "things_belongs_to_person_id_people_id_fk", + "tableFrom": "things", + "columnsFrom": [ + "belongs_to_person_id" + ], + "tableTo": "people", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "things_ended_currency_currencies_code_fk": { + "name": "things_ended_currency_currencies_code_fk", + "tableFrom": "things", + "columnsFrom": [ + "ended_currency" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "things_split_from_id_things_id_fk": { + "name": "things_split_from_id_things_id_fk", + "tableFrom": "things", + "columnsFrom": [ + "split_from_id" + ], + "tableTo": "things", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "things_merged_into_id_things_id_fk": { + "name": "things_merged_into_id_things_id_fk", + "tableFrom": "things", + "columnsFrom": [ + "merged_into_id" + ], + "tableTo": "things", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + }, + "things_place_fk": { + "name": "things_place_fk", + "tableFrom": "things", + "columnsFrom": [ + "location_id", + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "no action" + }, + "things_container_fk": { + "name": "things_container_fk", + "tableFrom": "things", + "columnsFrom": [ + "location_id", + "container_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "no action" + }, + "things_purchase_line_fk": { + "name": "things_purchase_line_fk", + "tableFrom": "things", + "columnsFrom": [ + "purchase_line_id" + ], + "tableTo": "purchase_lines", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "things_location_id_uq": { + "name": "things_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "things_lifecycle_chk": { + "name": "things_lifecycle_chk", + "value": "\"lifecycle\" IN ('in_use', 'archived', 'sold', 'given_away', 'lost', 'disposed', 'stolen', 'destroyed', 'returned_to_owner')" + }, + "things_condition_chk": { + "name": "things_condition_chk", + "value": "\"condition\" IN ('new', 'good', 'fair', 'poor', 'broken')" + }, + "things_review_state_chk": { + "name": "things_review_state_chk", + "value": "\"review_state\" IN ('draft', 'confirmed')" + }, + "things_created_via_chk": { + "name": "things_created_via_chk", + "value": "\"created_via\" IN ('app', 'mcp', 'assistant', 'import', 'email')" + }, + "things_one_parent_chk": { + "name": "things_one_parent_chk", + "value": "num_nonnulls(place_id, container_id) = 1" + }, + "things_not_own_container_chk": { + "name": "things_not_own_container_chk", + "value": "container_id IS NULL OR container_id <> id" + }, + "things_named_chk": { + "name": "things_named_chk", + "value": "name IS NOT NULL OR review_state = 'draft'" + }, + "things_name_chk": { + "name": "things_name_chk", + "value": "name IS NULL OR char_length(name) BETWEEN 1 AND 200" + }, + "things_model_chk": { + "name": "things_model_chk", + "value": "char_length(model) <= 120" + }, + "things_serial_chk": { + "name": "things_serial_chk", + "value": "char_length(serial) <= 100" + }, + "things_barcode_chk": { + "name": "things_barcode_chk", + "value": "char_length(barcode) <= 64" + }, + "things_colour_chk": { + "name": "things_colour_chk", + "value": "char_length(colour) <= 60" + }, + "things_notes_chk": { + "name": "things_notes_chk", + "value": "char_length(notes) <= 5000" + }, + "things_manual_url_chk": { + "name": "things_manual_url_chk", + "value": "char_length(manual_url) <= 2000" + }, + "things_ended_to_chk": { + "name": "things_ended_to_chk", + "value": "char_length(ended_to) <= 200" + }, + "things_ended_notes_chk": { + "name": "things_ended_notes_chk", + "value": "char_length(ended_notes) <= 5000" + }, + "things_acquired_from_chk": { + "name": "things_acquired_from_chk", + "value": "char_length(acquired_from) <= 200" + }, + "things_provenance_notes_chk": { + "name": "things_provenance_notes_chk", + "value": "char_length(provenance_notes) <= 5000" + }, + "things_quantity_chk": { + "name": "things_quantity_chk", + "value": "quantity >= 0" + }, + "things_expiry_lead_chk": { + "name": "things_expiry_lead_chk", + "value": "expiry_lead_days BETWEEN 0 AND 3650" + }, + "things_ended_price_chk": { + "name": "things_ended_price_chk", + "value": "ended_price >= 0" + }, + "things_ended_money_chk": { + "name": "things_ended_money_chk", + "value": "(ended_price IS NULL) = (ended_currency IS NULL)" + }, + "things_in_use_chk": { + "name": "things_in_use_chk", + "value": "lifecycle <> 'in_use' OR (ended_on IS NULL AND ended_price IS NULL AND ended_to IS NULL)" + }, + "things_aliases_chk": { + "name": "things_aliases_chk", + "value": "jsonb_typeof(aliases) = 'object'" + }, + "things_custom_chk": { + "name": "things_custom_chk", + "value": "jsonb_typeof(custom) = 'object'" + }, + "things_archived_custom_chk": { + "name": "things_archived_custom_chk", + "value": "jsonb_typeof(archived_custom) = 'object'" + }, + "things_field_status_chk": { + "name": "things_field_status_chk", + "value": "jsonb_typeof(field_status) = 'object'" + }, + "things_rack_units_chk": { + "name": "things_rack_units_chk", + "value": "rack_units BETWEEN 0 AND 60 AND rack_units * 2 = trunc(rack_units * 2)" + }, + "things_rack_at_chk": { + "name": "things_rack_at_chk", + "value": "rack_at IS NULL OR jsonb_typeof(rack_at) = 'object'" + } + }, + "isRLSEnabled": false + }, + "public.api_tokens": { + "name": "api_tokens", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "lookup": { + "name": "lookup", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hash": { + "name": "hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "oauth_client_id": { + "name": "oauth_client_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_with_mfa": { + "name": "created_with_mfa", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_used_at": { + "name": "last_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 + }, + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "api_tokens_lookup_uq": { + "name": "api_tokens_lookup_uq", + "columns": [ + { + "expression": "lookup", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "concurrently": false + }, + "api_tokens_oauth_uq": { + "name": "api_tokens_oauth_uq", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "oauth_client_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "kind = 'oauth' AND revoked_at IS NULL", + "concurrently": false + }, + "api_tokens_user_idx": { + "name": "api_tokens_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "api_tokens_user_id_user_id_fk": { + "name": "api_tokens_user_id_user_id_fk", + "tableFrom": "api_tokens", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "api_tokens_kind_chk": { + "name": "api_tokens_kind_chk", + "value": "\"kind\" IN ('personal', 'oauth')" + }, + "api_tokens_scope_chk": { + "name": "api_tokens_scope_chk", + "value": "\"scope\" IN ('read', 'write')" + }, + "api_tokens_revoked_reason_chk": { + "name": "api_tokens_revoked_reason_chk", + "value": "\"revoked_reason\" IN ('user', 'membership_ended', 'role_lost', 'expired', 'admin', 'client_revoked', 'account_claimed')" + }, + "api_tokens_name_chk": { + "name": "api_tokens_name_chk", + "value": "char_length(name) BETWEEN 1 AND 80" + }, + "api_tokens_lookup_chk": { + "name": "api_tokens_lookup_chk", + "value": "lookup ~ '^[A-Za-z0-9]{8}$'" + }, + "api_tokens_hash_chk": { + "name": "api_tokens_hash_chk", + "value": "hash ~ '^[0-9a-f]{64}$'" + }, + "api_tokens_oauth_client_chk": { + "name": "api_tokens_oauth_client_chk", + "value": "char_length(oauth_client_id) <= 400" + }, + "api_tokens_kind_fields_chk": { + "name": "api_tokens_kind_fields_chk", + "value": "CASE kind WHEN 'personal'\n THEN lookup IS NOT NULL AND hash IS NOT NULL AND oauth_client_id IS NULL\n ELSE lookup IS NULL AND hash IS NULL AND oauth_client_id IS NOT NULL END" + }, + "api_tokens_revoked_chk": { + "name": "api_tokens_revoked_chk", + "value": "(revoked_at IS NULL) = (revoked_reason IS NULL)" + } + }, + "isRLSEnabled": false + }, + "public.token_locations": { + "name": "token_locations", + "schema": "", + "columns": { + "token_id": { + "name": "token_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "token_locations_location_idx": { + "name": "token_locations_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "token_locations_token_id_api_tokens_id_fk": { + "name": "token_locations_token_id_api_tokens_id_fk", + "tableFrom": "token_locations", + "columnsFrom": [ + "token_id" + ], + "tableTo": "api_tokens", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "token_locations_location_id_locations_id_fk": { + "name": "token_locations_location_id_locations_id_fk", + "tableFrom": "token_locations", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "token_locations_pk": { + "name": "token_locations_pk", + "columns": [ + "token_id", + "location_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.token_rate_windows": { + "name": "token_rate_windows", + "schema": "", + "columns": { + "token_id": { + "name": "token_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "minute": { + "name": "minute", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "token_rate_windows_token_id_api_tokens_id_fk": { + "name": "token_rate_windows_token_id_api_tokens_id_fk", + "tableFrom": "token_rate_windows", + "columnsFrom": [ + "token_id" + ], + "tableTo": "api_tokens", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "token_rate_windows_pk": { + "name": "token_rate_windows_pk", + "columns": [ + "token_id", + "minute", + "kind" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "token_rate_windows_kind_chk": { + "name": "token_rate_windows_kind_chk", + "value": "\"kind\" IN ('read', 'write')" + }, + "token_rate_windows_count_chk": { + "name": "token_rate_windows_count_chk", + "value": "count >= 0" + } + }, + "isRLSEnabled": false + }, + "public.place_folds": { + "name": "place_folds", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "place_id": { + "name": "place_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "place_folds_place_idx": { + "name": "place_folds_place_idx", + "columns": [ + { + "expression": "place_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "place_folds_user_id_user_id_fk": { + "name": "place_folds_user_id_user_id_fk", + "tableFrom": "place_folds", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "place_folds_place_id_places_id_fk": { + "name": "place_folds_place_id_places_id_fk", + "tableFrom": "place_folds", + "columnsFrom": [ + "place_id" + ], + "tableTo": "places", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "place_folds_pk": { + "name": "place_folds_pk", + "columns": [ + "user_id", + "place_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.saved_view_prefs": { + "name": "saved_view_prefs", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "surface": { + "name": "surface", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "default_view_id": { + "name": "default_view_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "pinned": { + "name": "pinned", + "type": "uuid[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::uuid[]" + } + }, + "indexes": {}, + "foreignKeys": { + "saved_view_prefs_user_id_user_id_fk": { + "name": "saved_view_prefs_user_id_user_id_fk", + "tableFrom": "saved_view_prefs", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "saved_view_prefs_default_view_id_saved_views_id_fk": { + "name": "saved_view_prefs_default_view_id_saved_views_id_fk", + "tableFrom": "saved_view_prefs", + "columnsFrom": [ + "default_view_id" + ], + "tableTo": "saved_views", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "set null" + } + }, + "compositePrimaryKeys": { + "saved_view_prefs_pk": { + "name": "saved_view_prefs_pk", + "columns": [ + "user_id", + "surface" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "saved_view_prefs_surface_chk": { + "name": "saved_view_prefs_surface_chk", + "value": "surface ~ '^[a-z][a-z-]{0,31}$'" + }, + "saved_view_prefs_pinned_chk": { + "name": "saved_view_prefs_pinned_chk", + "value": "cardinality(pinned) <= 20" + } + }, + "isRLSEnabled": false + }, + "public.saved_views": { + "name": "saved_views", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "query": { + "name": "query", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "shared": { + "name": "shared", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "surface": { + "name": "surface", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'search'" + }, + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "saved_views_user_idx": { + "name": "saved_views_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "saved_views_location_idx": { + "name": "saved_views_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "shared", + "concurrently": false + }, + "saved_views_user_surface_idx": { + "name": "saved_views_user_surface_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "surface", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "saved_views_user_id_user_id_fk": { + "name": "saved_views_user_id_user_id_fk", + "tableFrom": "saved_views", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "saved_views_location_id_locations_id_fk": { + "name": "saved_views_location_id_locations_id_fk", + "tableFrom": "saved_views", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "saved_views_name_chk": { + "name": "saved_views_name_chk", + "value": "char_length(name) BETWEEN 1 AND 80" + }, + "saved_views_surface_chk": { + "name": "saved_views_surface_chk", + "value": "surface ~ '^[a-z][a-z-]{0,31}$'" + }, + "saved_views_query_chk": { + "name": "saved_views_query_chk", + "value": "jsonb_typeof(query) = 'object'" + }, + "saved_views_shared_chk": { + "name": "saved_views_shared_chk", + "value": "NOT shared OR location_id IS NOT NULL" + } + }, + "isRLSEnabled": false + }, + "public.user_hints": { + "name": "user_hints", + "schema": "", + "columns": { + "user_id": { + "name": "user_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "hint_key": { + "name": "hint_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "seen_at": { + "name": "seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "dismissed": { + "name": "dismissed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "user_hints_user_id_user_id_fk": { + "name": "user_hints_user_id_user_id_fk", + "tableFrom": "user_hints", + "columnsFrom": [ + "user_id" + ], + "tableTo": "user", + "schemaTo": "auth", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": { + "user_hints_pk": { + "name": "user_hints_pk", + "columns": [ + "user_id", + "hint_key" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "user_hints_key_chk": { + "name": "user_hints_key_chk", + "value": "hint_key ~ '^[a-z0-9_.:-]{1,64}$'" + } + }, + "isRLSEnabled": false + }, + "public.claims": { + "name": "claims", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "warranty_id": { + "name": "warranty_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "incident_id": { + "name": "incident_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "opened_on": { + "name": "opened_on", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "reference": { + "name": "reference", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "vendor_id": { + "name": "vendor_id", + "type": "uuid", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'open'" + }, + "cost": { + "name": "cost", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": false + }, + "currency": { + "name": "currency", + "type": "char(3)", + "primaryKey": false, + "notNull": false + }, + "covered_amount": { + "name": "covered_amount", + "type": "numeric(16, 4)", + "primaryKey": false, + "notNull": false + }, + "notes": { + "name": "notes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "closed_on": { + "name": "closed_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "claims_one_repair_uq": { + "name": "claims_one_repair_uq", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "with": {}, + "method": "btree", + "where": "status = 'in_repair'", + "concurrently": false + }, + "claims_thing_idx": { + "name": "claims_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "claims_warranty_idx": { + "name": "claims_warranty_idx", + "columns": [ + { + "expression": "warranty_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "claims_incident_idx": { + "name": "claims_incident_idx", + "columns": [ + { + "expression": "incident_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "claims_vendor_idx": { + "name": "claims_vendor_idx", + "columns": [ + { + "expression": "vendor_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "claims_location_id_locations_id_fk": { + "name": "claims_location_id_locations_id_fk", + "tableFrom": "claims", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "claims_currency_currencies_code_fk": { + "name": "claims_currency_currencies_code_fk", + "tableFrom": "claims", + "columnsFrom": [ + "currency" + ], + "tableTo": "currencies", + "columnsTo": [ + "code" + ], + "onUpdate": "no action", + "onDelete": "no action" + }, + "claims_thing_fk": { + "name": "claims_thing_fk", + "tableFrom": "claims", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "claims_location_id_uq": { + "name": "claims_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "claims_status_chk": { + "name": "claims_status_chk", + "value": "\"status\" IN ('open', 'in_repair', 'resolved', 'rejected')" + }, + "claims_reference_chk": { + "name": "claims_reference_chk", + "value": "char_length(reference) <= 100" + }, + "claims_cost_chk": { + "name": "claims_cost_chk", + "value": "cost >= 0" + }, + "claims_covered_amount_chk": { + "name": "claims_covered_amount_chk", + "value": "covered_amount >= 0" + }, + "claims_notes_chk": { + "name": "claims_notes_chk", + "value": "char_length(notes) <= 5000" + }, + "claims_money_chk": { + "name": "claims_money_chk", + "value": "(cost IS NULL AND covered_amount IS NULL) OR currency IS NOT NULL" + }, + "claims_closed_chk": { + "name": "claims_closed_chk", + "value": "(status IN ('resolved', 'rejected')) = (closed_on IS NOT NULL)" + }, + "claims_closed_on_chk": { + "name": "claims_closed_on_chk", + "value": "closed_on IS NULL OR closed_on >= opened_on" + } + }, + "isRLSEnabled": false + }, + "public.warranties": { + "name": "warranties", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "thing_id": { + "name": "thing_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "starts_on": { + "name": "starts_on", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "ends_on": { + "name": "ends_on", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "term_months": { + "name": "term_months", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "lifetime": { + "name": "lifetime", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "effective_ends_on": { + "name": "effective_ends_on", + "type": "date", + "primaryKey": false, + "notNull": false, + "generated": { + "type": "stored", + "as": "CASE WHEN lifetime THEN NULL\n WHEN ends_on IS NOT NULL THEN ends_on\n ELSE (starts_on + make_interval(months => term_months))::date - 1 END" + } + }, + "lead_days": { + "name": "lead_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 30 + }, + "claim_contact": { + "name": "claim_contact", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "registered": { + "name": "registered", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "registration_deadline": { + "name": "registration_deadline", + "type": "date", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "warranties_thing_idx": { + "name": "warranties_thing_idx", + "columns": [ + { + "expression": "thing_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "warranties_ends_idx": { + "name": "warranties_ends_idx", + "columns": [ + { + "expression": "effective_ends_on", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "warranties_location_id_locations_id_fk": { + "name": "warranties_location_id_locations_id_fk", + "tableFrom": "warranties", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + }, + "warranties_thing_fk": { + "name": "warranties_thing_fk", + "tableFrom": "warranties", + "columnsFrom": [ + "location_id", + "thing_id" + ], + "tableTo": "things", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "warranties_location_id_uq": { + "name": "warranties_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "warranties_kind_chk": { + "name": "warranties_kind_chk", + "value": "\"kind\" IN ('manufacturer', 'extended', 'store', 'credit_card', 'insurance')" + }, + "warranties_provider_chk": { + "name": "warranties_provider_chk", + "value": "char_length(provider) <= 120" + }, + "warranties_term_months_chk": { + "name": "warranties_term_months_chk", + "value": "term_months BETWEEN 1 AND 600" + }, + "warranties_lead_days_chk": { + "name": "warranties_lead_days_chk", + "value": "lead_days BETWEEN 0 AND 365" + }, + "warranties_claim_contact_chk": { + "name": "warranties_claim_contact_chk", + "value": "char_length(claim_contact) <= 300" + }, + "warranties_term_chk": { + "name": "warranties_term_chk", + "value": "num_nonnulls(ends_on, term_months) + lifetime::int = 1" + }, + "warranties_ends_chk": { + "name": "warranties_ends_chk", + "value": "ends_on IS NULL OR ends_on >= starts_on" + } + }, + "isRLSEnabled": false + }, + "public.webhook_deliveries": { + "name": "webhook_deliveries", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "webhook_id": { + "name": "webhook_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "event_id": { + "name": "event_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event": { + "name": "event", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempts": { + "name": "attempts", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "http_status": { + "name": "http_status", + "type": "smallint", + "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": { + "webhook_deliveries_webhook_idx": { + "name": "webhook_deliveries_webhook_idx", + "columns": [ + { + "expression": "webhook_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + }, + "webhook_deliveries_due_idx": { + "name": "webhook_deliveries_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "where": "status IN ('pending', 'failed')", + "concurrently": false + }, + "webhook_deliveries_location_idx": { + "name": "webhook_deliveries_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "webhook_deliveries_webhook_fk": { + "name": "webhook_deliveries_webhook_fk", + "tableFrom": "webhook_deliveries", + "columnsFrom": [ + "location_id", + "webhook_id" + ], + "tableTo": "webhooks", + "columnsTo": [ + "location_id", + "id" + ], + "onUpdate": "cascade", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhook_deliveries_event_uq": { + "name": "webhook_deliveries_event_uq", + "columns": [ + "webhook_id", + "event_id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "webhook_deliveries_status_chk": { + "name": "webhook_deliveries_status_chk", + "value": "\"status\" IN ('pending', 'delivered', 'failed', 'gave_up')" + }, + "webhook_deliveries_event_id_chk": { + "name": "webhook_deliveries_event_id_chk", + "value": "event_id ~ '^evt_[A-Za-z0-9]{10,40}$'" + }, + "webhook_deliveries_event_chk": { + "name": "webhook_deliveries_event_chk", + "value": "event IN ('thing.created', 'thing.updated', 'thing.moved', 'thing.trashed', 'thing.restored', 'thing.lifecycle_changed', 'reading.logged', 'reminder.due', 'ping')" + }, + "webhook_deliveries_attempts_chk": { + "name": "webhook_deliveries_attempts_chk", + "value": "attempts BETWEEN 0 AND 50" + }, + "webhook_deliveries_http_status_chk": { + "name": "webhook_deliveries_http_status_chk", + "value": "http_status BETWEEN 100 AND 599" + } + }, + "isRLSEnabled": false + }, + "public.webhooks": { + "name": "webhooks", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "uuid", + "primaryKey": true, + "notNull": true, + "default": "uuidv7()" + }, + "location_id": { + "name": "location_id", + "type": "uuid", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "secret_ciphertext": { + "name": "secret_ciphertext", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "key_version": { + "name": "key_version", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "events": { + "name": "events", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "failing_since": { + "name": "failing_since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_reason": { + "name": "disabled_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by": { + "name": "created_by", + "type": "uuid", + "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()" + }, + "row_version": { + "name": "row_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "change_seq": { + "name": "change_seq", + "type": "bigint", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "webhooks_location_idx": { + "name": "webhooks_location_idx", + "columns": [ + { + "expression": "location_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "with": {}, + "method": "btree", + "concurrently": false + } + }, + "foreignKeys": { + "webhooks_location_id_locations_id_fk": { + "name": "webhooks_location_id_locations_id_fk", + "tableFrom": "webhooks", + "columnsFrom": [ + "location_id" + ], + "tableTo": "locations", + "columnsTo": [ + "id" + ], + "onUpdate": "no action", + "onDelete": "cascade" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhooks_location_id_uq": { + "name": "webhooks_location_id_uq", + "columns": [ + "location_id", + "id" + ], + "nullsNotDistinct": false + } + }, + "policies": {}, + "checkConstraints": { + "webhooks_disabled_reason_chk": { + "name": "webhooks_disabled_reason_chk", + "value": "\"disabled_reason\" IN ('creator_lost_role', 'failing', 'admin')" + }, + "webhooks_url_chk": { + "name": "webhooks_url_chk", + "value": "url ~ '^https?://' AND char_length(url) <= 500" + }, + "webhooks_events_chk": { + "name": "webhooks_events_chk", + "value": "cardinality(events) BETWEEN 1 AND 8 AND events <@ ARRAY['thing.created', 'thing.updated', 'thing.moved', 'thing.trashed', 'thing.restored', 'thing.lifecycle_changed', 'reading.logged', 'reminder.due']::text[]" + }, + "webhooks_key_version_chk": { + "name": "webhooks_key_version_chk", + "value": "key_version >= 1" + }, + "webhooks_disabled_chk": { + "name": "webhooks_disabled_chk", + "value": "active OR disabled_reason IS NOT NULL" + } + }, + "isRLSEnabled": false + } + }, + "enums": {}, + "schemas": { + "auth": "auth" + }, + "views": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/apps/server/migrations/meta/_journal.json b/apps/server/migrations/meta/_journal.json index 8f81afd1..239b67cd 100644 --- a/apps/server/migrations/meta/_journal.json +++ b/apps/server/migrations/meta/_journal.json @@ -1247,6 +1247,13 @@ "when": 1794489790206, "tag": "0177_counts_module", "breakpoints": true + }, + { + "idx": 178, + "version": "7", + "when": 1794613972746, + "tag": "0178_customised_type_names", + "breakpoints": true } ] } \ No newline at end of file diff --git a/apps/server/src/graph/view.ts b/apps/server/src/graph/view.ts index 2aeaf515..5d3665ae 100644 --- a/apps/server/src/graph/view.ts +++ b/apps/server/src/graph/view.ts @@ -6,6 +6,7 @@ import { shownCodeSql } from '../labels/printed-sql.js'; import { requireMembership } from '../locations/access.js'; import { attentionOf, placeRows } from '../map/view.js'; import { thingNameSql } from '../places/order.js'; +import { typeKeySql } from '../types/graph.js'; // GET /api/v1/locations/:id/graph (#207): a location as a graph, in one read under the caller's // row-level security. The web lays it out (2D focus rings and the 3D floors) from this. @@ -97,8 +98,8 @@ export async function graphView( const { rows: things } = await client.query( `SELECT t.id, t.name, t.place_id, t.container_id, ${shownCodeSql('thing_id', 't.id')} AS short_code, - coalesce(ty.builtin_key, - (SELECT pt.builtin_key FROM public.types pt WHERE pt.id = ty.parent_id)) + coalesce(${typeKeySql('ty')}, + (SELECT ${typeKeySql('pt')} FROM public.types pt WHERE pt.id = ty.parent_id)) AS type_key, CASE WHEN ty.builtin_key IS NULL THEN ty.name END AS type_name, (coalesce('container' = ANY (kept.type_capabilities(t.type_id)), false) diff --git a/apps/server/src/lists/things-csv.ts b/apps/server/src/lists/things-csv.ts index b81f93a8..013f7ea3 100644 --- a/apps/server/src/lists/things-csv.ts +++ b/apps/server/src/lists/things-csv.ts @@ -6,6 +6,7 @@ import { type ReportLocale, reportLocaleOf, wordsFor } from '../reports/labels.j import { gateFor } from '../serialize/gates.js'; import { type ThingListFilter, thingListOrder, thingListWhere } from '../things/service.js'; import type { ListQuery } from '../things/validate.js'; +import { typeKeySql } from '../types/graph.js'; // The things list you're looking at, as a CSV (D169): // GET /api/v1/things.csv takes every GET /things parameter and writes the same rows in the same @@ -89,7 +90,7 @@ async function readRows( moneyLocations: string[], ): Promise { const { rows } = await client.query( - `SELECT t.id, t.location_id, t.name, ty.name AS type_name, ty.builtin_key AS type_builtin_key, + `SELECT t.id, t.location_id, t.name, ty.name AS type_name, ${typeKeySql('ty')} AS type_builtin_key, b.name AS brand, t.model, t.serial, t.quantity::text AS quantity, t.condition, t.lifecycle, t.last_seen_at, (SELECT s.code FROM public.short_ids s diff --git a/apps/server/src/map/view.ts b/apps/server/src/map/view.ts index fb8fd156..9d929a5e 100644 --- a/apps/server/src/map/view.ts +++ b/apps/server/src/map/view.ts @@ -22,6 +22,7 @@ import { labelPrintedSql, shownCodeSql } from '../labels/printed-sql.js'; import { requireMembership } from '../locations/access.js'; import { placeOrderSql, thingNameSql } from '../places/order.js'; import { layoutOf as furnitureLayout } from '../templates/furniture-view.js'; +import { typeKeySql } from '../types/graph.js'; // GET /api/v1/locations/:id/map (1.x, D237): everything the location map draws and its card and // list show, in one read under the caller's row-level security. @@ -307,8 +308,8 @@ export async function placeRows(client: pg.ClientBase, locationId: string): Prom export async function thingRows(client: pg.ClientBase, locationId: string): Promise { const { rows } = await client.query( `SELECT t.id, t.name, t.place_id, t.container_id, t.quantity::text AS quantity, - coalesce(ty.builtin_key, - (SELECT pt.builtin_key FROM public.types pt WHERE pt.id = ty.parent_id)) + coalesce(${typeKeySql('ty')}, + (SELECT ${typeKeySql('pt')} FROM public.types pt WHERE pt.id = ty.parent_id)) AS type_key, CASE WHEN ty.builtin_key IS NULL THEN ty.name END AS type_name, (coalesce('container' = ANY (kept.type_capabilities(t.type_id)), false) diff --git a/apps/server/src/places/view.ts b/apps/server/src/places/view.ts index 6a2e3a68..b497cdda 100644 --- a/apps/server/src/places/view.ts +++ b/apps/server/src/places/view.ts @@ -37,6 +37,7 @@ import { tagsOfRow, tagsSql, } from '../things/tag-sql.js'; +import { typeKeySql } from '../types/graph.js'; import { placeOrderSql, thingNameSql } from './order.js'; // What the API shows of places (D45, D118, D160): the shapes of the web contract @@ -727,11 +728,13 @@ export async function placeContents( } const sort = query.sort ?? 'name'; - // Grouped by type: typed things first, by built-in key or name, untyped ones last. By tag: under - // the first tag A to Z, untagged ones last (things/tag-sql.ts). + // Grouped by type: typed things first, by name or built-in key, then the type's id, so a + // customised copy and its built-in, same key, stay apart (#546); untyped ones last. By tag: + // under the first tag A to Z, untagged ones last (things/tag-sql.ts). const g = query.group === 'type' - ? `CASE WHEN ty.id IS NULL THEN '1' ELSE '0' || coalesce(ty.builtin_key, lower(ty.name)) END` + ? `CASE WHEN ty.id IS NULL THEN '1' + ELSE '0' || coalesce(lower(ty.name), ${typeKeySql('ty')}) || ' ' || ty.id::text END` : query.group === 'tag' ? tagGroupSql('t.id') : `''`; @@ -762,7 +765,7 @@ export async function placeContents( ${shownCodeSql('thing_id', 't.id')} AS short_code, ${labelPrintedSql('thing_id', 't.id')} AS label_printed, ty.id AS type_id, ty.icon AS type_icon, ty.name AS type_name, - ty.builtin_key AS type_builtin_key, + ${typeKeySql('ty')} AS type_builtin_key, (SELECT a.file_id FROM public.attachments a JOIN public.file_derivatives d ON d.file_id = a.file_id AND d.variant = 'thumb' WHERE a.thing_id = t.id AND a.role = 'photo' diff --git a/apps/server/src/reports/gather.ts b/apps/server/src/reports/gather.ts index b2dcd49f..32e746c0 100644 --- a/apps/server/src/reports/gather.ts +++ b/apps/server/src/reports/gather.ts @@ -2,6 +2,7 @@ import { builtinTypeName, type Digits } from '@kept/shared'; import type pg from 'pg'; import type { Scope, Tx } from '../db/scope.js'; import { gateFor } from '../serialize/gates.js'; +import { typeKeySql } from '../types/graph.js'; import type { ReportLocale } from './labels.js'; // What goes into a report (D201), read in the requester's scope: the `report` job runs as a @@ -198,7 +199,7 @@ async function readThings( : 'NULL::text'; const moneyLocs = p.add(moneyLocationIds); const text = `${ctes.length > 0 ? `WITH RECURSIVE ${ctes.join(',\n')}` : ''} - SELECT t.id, t.location_id, t.name, ty.name AS type_name, ty.builtin_key AS type_builtin_key, + SELECT t.id, t.location_id, t.name, ty.name AS type_name, ${typeKeySql('ty')} AS type_builtin_key, b.name AS brand, t.model, t.serial, t.condition, t.lifecycle, t.quantity::text AS quantity, t.deleted_at IS NOT NULL AS trashed, (SELECT s.code FROM public.short_ids s @@ -237,7 +238,8 @@ async function namesOf(client: pg.ClientBase, options: ReportOptions) { f.placeIds, ); const types = await read( - 'SELECT name, builtin_key FROM public.types WHERE id = ANY ($1::uuid[])', + `SELECT t.name, ${typeKeySql('t')} AS builtin_key FROM public.types t + WHERE t.id = ANY ($1::uuid[])`, f.typeIds, ); const tags = await read('SELECT name FROM public.tags WHERE id = ANY ($1::uuid[])', f.tagIds); diff --git a/apps/server/src/reports/vehicle/gather.ts b/apps/server/src/reports/vehicle/gather.ts index 0b1e3bd2..db810c9a 100644 --- a/apps/server/src/reports/vehicle/gather.ts +++ b/apps/server/src/reports/vehicle/gather.ts @@ -4,6 +4,7 @@ import type { Scope, Tx } from '../../db/scope.js'; import { type FuelSummary, fillsOf, fuelSummary } from '../../fuel/summary.js'; import { notFound } from '../../http/errors.js'; import { gateFor } from '../../serialize/gates.js'; +import { typeKeySql } from '../../types/graph.js'; import { correctedValueSql, odometerOf, type VehicleMeter } from '../../vehicles/meters.js'; import { typeNameOf } from '../gather.js'; import type { ReportLocale } from '../labels.js'; @@ -143,7 +144,7 @@ const inRange = (column: string, tz: string, from: string, to: string) => async function readThing(client: pg.ClientBase, id: string): Promise { const { rows } = await client.query( - `SELECT t.id, t.location_id, t.name, ty.name AS type_name, ty.builtin_key AS type_builtin_key, + `SELECT t.id, t.location_id, t.name, ty.name AS type_name, ${typeKeySql('ty')} AS type_builtin_key, (SELECT s.code FROM public.short_ids s WHERE s.thing_id = t.id AND s.is_primary AND s.state = 'assigned' LIMIT 1) AS short_code, diff --git a/apps/server/src/room/match.ts b/apps/server/src/room/match.ts index 317b2e08..3ee97912 100644 --- a/apps/server/src/room/match.ts +++ b/apps/server/src/room/match.ts @@ -13,6 +13,7 @@ */ import { normalize } from '@kept/shared'; import type pg from 'pg'; +import { typeKeySql } from '../types/graph.js'; import type { Merged } from './merge.js'; export type MatchReason = 'code' | 'brand_model' | 'name_type'; @@ -59,7 +60,7 @@ export async function candidatesOf( WHERE s.code = ANY ($4::text[]) AND s.state = 'assigned' AND s.thing_id IS NOT NULL AND s.location_id = $1) SELECT t.id, coalesce(t.name, '') AS name, b.name AS brand, t.model, - ty.name AS type, coalesce(ty.builtin_key, pt.builtin_key) AS builtin, + ty.name AS type, coalesce(${typeKeySql('ty')}, ${typeKeySql('pt')}) AS builtin, t.id IN (SELECT id FROM coded) AS by_code FROM public.things t LEFT JOIN public.brands b ON b.id = t.brand_id diff --git a/apps/server/src/search/query.ts b/apps/server/src/search/query.ts index cc925956..519fa2ba 100644 --- a/apps/server/src/search/query.ts +++ b/apps/server/src/search/query.ts @@ -14,6 +14,7 @@ import { type Many, manyOf, matchOf, notOf } from '../http/list-filters.js'; import { legacyCodeOf } from '../imports/csv.js'; import { labelPrintedSql, shownCodeSql } from '../labels/printed-sql.js'; import { tagMatchSql, tagsSql } from '../things/tag-sql.js'; +import { typeKeySql } from '../types/graph.js'; // The search SQL (D42). Everything here runs on the // request's kept_app transaction, so row-level security decides what exists: a thing, place, @@ -440,7 +441,7 @@ export async function searchThings( ${shownCodeSql('thing_id', 't.id')} AS short_code, ${labelPrintedSql('thing_id', 't.id')} AS label_printed, ty.id AS type_id, ty.icon AS type_icon, ty.name AS type_name, - ty.builtin_key AS type_builtin_key, + ${typeKeySql('ty')} AS type_builtin_key, ${firstThumb('t.id')} AS thumb_file_id, CASE WHEN t.container_id IS NULL THEN NULL ELSE ${firstThumb('t.container_id')} END AS container_thumb_file_id, diff --git a/apps/server/src/sync/snapshot.ts b/apps/server/src/sync/snapshot.ts index 1c66efdf..19823ac6 100644 --- a/apps/server/src/sync/snapshot.ts +++ b/apps/server/src/sync/snapshot.ts @@ -23,6 +23,7 @@ import { import type pg from 'pg'; import { switchedOn } from '../locations/views.js'; import { decimalOut } from '../meters/check.js'; +import { typeKeySql } from '../types/graph.js'; import { type After, type CursorState, @@ -151,7 +152,7 @@ async function visibleTypes(client: pg.ClientBase): Promise<{ hash: string; item icon: string; is_container: boolean; }>( - `SELECT t.id, t.builtin_key, t.name, t.icon, + `SELECT t.id, ${typeKeySql('t')} AS builtin_key, t.name, t.icon, coalesce('container' = ANY (kept.type_capabilities(t.id)), false) AS is_container FROM public.types t WHERE NOT t.is_field_group diff --git a/apps/server/src/things/service.ts b/apps/server/src/things/service.ts index c52586bd..b2fb1ab7 100644 --- a/apps/server/src/things/service.ts +++ b/apps/server/src/things/service.ts @@ -30,6 +30,7 @@ import { STATE_SQL } from '../search/query.js'; import { gateFor } from '../serialize/gates.js'; import type { FileStorage } from '../storage/blob-store.js'; import { rackWrite } from '../templates/racks.js'; +import { typeKeySql } from '../types/graph.js'; import { customClasses, moneyShaped, @@ -1430,7 +1431,7 @@ export function thingListOrder(q: Pick): { } { const group = q.group === 'type' - ? `(lower(coalesce(ty.name, ty.builtin_key, '~')) || ' ' || coalesce(ty.id::text, '')) ${ICU}` + ? `(lower(coalesce(ty.name, ${typeKeySql('ty')}, '~')) || ' ' || coalesce(ty.id::text, '')) ${ICU}` : q.group === 'place' ? `coalesce(t.container_id, t.place_id)::text ${ICU}` : q.group === 'tag' diff --git a/apps/server/src/things/view.ts b/apps/server/src/things/view.ts index fb417082..2c8fbb2d 100644 --- a/apps/server/src/things/view.ts +++ b/apps/server/src/things/view.ts @@ -36,6 +36,7 @@ import { } from '../serialize/gates.js'; import type { FileStorage } from '../storage/blob-store.js'; import { type ThingRack, ThingRackSchema, thingRackOf } from '../templates/rack-view.js'; +import { typeKeySql } from '../types/graph.js'; import { moneyShaped } from './audit-image.js'; import { type ResolvedFieldView, resolvedFields } from './fields.js'; import { type ThingTag, ThingTagSchema, tagsOfRow, tagsSql } from './tag-sql.js'; @@ -98,7 +99,7 @@ export const ROW_COLUMNS = `t.id, t.location_id, t.name, t.quantity::text AS qua ${shownCodeSql('thing_id', 't.id')} AS short_code, ${labelPrintedSql('thing_id', 't.id')} AS label_printed, ty.id AS type_id, ty.icon AS type_icon, ty.name AS type_name, - ty.builtin_key AS type_builtin_key, + ${typeKeySql('ty')} AS type_builtin_key, ${firstThumb('t.id')} AS thumb_file_id, CASE WHEN t.container_id IS NULL THEN NULL ELSE ${firstThumb('t.container_id')} END AS container_thumb_file_id, diff --git a/apps/server/src/types/customised-name.test.ts b/apps/server/src/types/customised-name.test.ts new file mode 100644 index 00000000..449f4d62 --- /dev/null +++ b/apps/server/src/types/customised-name.test.ts @@ -0,0 +1,260 @@ +import { type Envelope, envelopeSchema, isToolError, TOOL_DEFS, type ToolName } from '@kept/mcp'; +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; +import type { TestApp } from '../../test/app.js'; +import { type TestDb, testDb } from '../../test/db.js'; +import { call, type Person, peopleApp, person } from '../../test/people.js'; +import { builtinType, createLocation, createThing, type Loc, ok, own } from '../../test/things.js'; +import { withScope } from '../db/scope.js'; +import { thingRows } from '../map/view.js'; +import { gather } from '../reports/gather.js'; +import { runTool } from '../tools/context.js'; +import type { ToolContext } from '../tools/types.js'; + +// #546: a customised built-in keeps its name. "Customise" copies the built-in into the account +// (kept.customise_type) with no name of its own, pointing at the built-in through +// `copied_from_id`, so it still reads in each person's language. Every reader names the copy +// through that pointer: the thing page, the tools, search, lists, the CSV, reports, the map, the +// phone's snapshot and share links. A copy renamed by hand shows its own name. +// +// Ibrahim owns Home (complete). Its router is a Network device; he customises Network device. + +let db: TestDb; +let t: TestApp; +let ibrahim: Person; +let home: Loc; +let builtin: string; +let copy: string; +let router: string; + +type TypeRef = { id: string; name: string | null; builtinKey: string | null } | null; + +// biome-ignore lint/suspicious/noExplicitAny: the envelope was validated against its zod schema +type Answer = Record; + +let seq = 0; +async function tool(name: ToolName, args: Record): Promise { + seq += 1; + const ctx: ToolContext = { + deps: { + pools: db.pools, + jobs: null, + files: null, + providerResolved: async () => true, + baseUrl: 'https://kept.example', + }, + principal: { userId: ibrahim.userId, mfa: false, scope: 'write' }, + locale: 'de', + requestId: `customised-name-${seq}`, + via: 'mcp', + }; + const env = (await runTool(ctx, name, args)) as Envelope; + expect(envelopeSchema(TOOL_DEFS[name].output).safeParse(env).success).toBe(true); + if (isToolError(env)) throw new Error(`${name}: ${env.error} (${env.hint})`); + return env.data; +} + +const typeOfThing = async (id: string) => + (ok(await call(t, `/api/v1/things/${id}`, { as: ibrahim })) as unknown as { type: TypeRef }).type; + +beforeAll(async () => { + db = await testDb(); + await db.reset(); + t = await peopleApp(db); + ibrahim = await person(t, db, 'ibrahim'); + home = await createLocation(t, db, ibrahim, 'complete', 'Home'); + builtin = await builtinType(db, 'network_device'); + router = (await createThing(t, ibrahim, home, { name: 'Hall router', typeId: builtin })).id; + const res = await call(t, `/api/v1/types/${builtin}/customise`, { + as: ibrahim, + body: { accountId: home.accountId }, + }); + expect(res.statusCode, res.body).toBe(200); + copy = (res.json() as { typeId: string }).typeId; +}); + +afterAll(async () => { + await t?.app.close(); +}); + +describe('a customised built-in type keeps its name (#546)', () => { + it('customising moves the thing onto a copy that still answers to the built-in', async () => { + expect(copy).not.toBe(builtin); + const [row] = await own<{ type_id: string }>( + db, + 'SELECT type_id FROM public.things WHERE id = $1', + [router], + ); + expect(row?.type_id).toBe(copy); + const detail = ok(await call(t, `/api/v1/types/${copy}`, { as: ibrahim })); + expect(detail).toMatchObject({ + builtinKey: 'network_device', + name: null, + copiedFromId: builtin, + }); + }); + + it('the thing page names the copy by the built-in, so it translates', async () => { + expect(await typeOfThing(router)).toEqual({ + id: copy, + icon: 'lucide:router', + name: null, + builtinKey: 'network_device', + }); + }); + + it('get_thing says the type in English, as for the built-in', async () => { + const d = await tool('get_thing', { thing_id: router }); + expect(d.thing.untrusted.type).toBe('Network device'); + expect(d.thing.type_id).toBe(copy); + }); + + it('search finds the thing by its type name and names the type', async () => { + for (const q of ['network', 'جهاز شبكة']) { + const res = ok( + await call( + t, + `/api/v1/search?q=${encodeURIComponent(q)}&kind=things&locationId=${home.id}`, + { + as: ibrahim, + }, + ), + ) as unknown as { things: { items: { id: string; type: TypeRef }[] } }; + const hit = res.things.items.find((i) => i.id === router); + expect(hit, q).toBeDefined(); + expect(hit?.type).toMatchObject({ id: copy, builtinKey: 'network_device' }); + } + }); + + it('the place’s contents, the things list and the CSV name the type', async () => { + const contents = ok( + await call(t, `/api/v1/places/${home.unplacedId}/contents?group=type`, { as: ibrahim }), + ) as unknown as { things: { items: { id: string; type: TypeRef }[] } }; + expect(contents.things.items.find((i) => i.id === router)?.type).toMatchObject({ + builtinKey: 'network_device', + }); + const list = ok( + await call(t, `/api/v1/things?locationId=${home.id}&group=type`, { as: ibrahim }), + ) as unknown as { items: { id: string; type: TypeRef }[] }; + expect(list.items.find((i) => i.id === router)?.type).toMatchObject({ + builtinKey: 'network_device', + }); + const csv = await call(t, `/api/v1/things.csv?locationId=${home.id}`, { as: ibrahim }); + expect(csv.statusCode, csv.body).toBe(200); + const line = csv.body.split('\r\n').find((l) => l.includes('Hall router')); + expect(line).toContain('Network device'); + }); + + it('a report names the type in the report’s language, in its rows and its filter', async () => { + const scope = { userId: ibrahim.userId, mfa: false }; + const got = await withScope(db.pools.app, scope, (tx, client) => + gather(tx, client, scope, { + locationIds: [home.id], + scope: { locationId: home.id }, + options: { + filters: { + placeIds: [], + typeIds: [copy], + tagIds: [], + thingIds: [], + includeEnded: false, + includeTrashed: false, + }, + include: { photos: false, qr: false, money: false }, + locale: 'de', + digits: 'western', + }, + }), + ); + expect(got.things.find((x) => x.id === router)?.typeName).toBe('Netzwerkgerät'); + expect(got.filterNames.types).toEqual(['Netzwerkgerät']); + }); + + it('the map’s rows carry the built-in key, not the parent’s', async () => { + // The map draws only things in rooms; its rows are read as the map reads them. + const scope = { userId: ibrahim.userId, mfa: false }; + const mapRows = await withScope(db.pools.app, scope, (_tx, client) => + thingRows(client, home.id), + ); + expect(mapRows.find((x) => x.id === router)?.type_key).toBe('network_device'); + }); + + it('the graph carries the built-in key, not the parent’s', async () => { + const graph = ok( + await call(t, `/api/v1/locations/${home.id}/graph`, { as: ibrahim }), + ) as unknown as { things: { id: string; typeKey: string | null }[] }; + expect(graph.things.find((x) => x.id === router)?.typeKey).toBe('network_device'); + }); + + it('the phone’s snapshot names the copy by the built-in key', async () => { + const snap = ok(await call(t, '/api/v1/sync/snapshot', { as: ibrahim })) as unknown as { + types: { items?: { id: string; builtinKey: string | null; name: string }[] }; + }; + expect(snap.types.items?.find((x) => x.id === copy)).toMatchObject({ + builtinKey: 'network_device', + name: 'network_device', + }); + }); + + it('a share link’s page names the type', async () => { + const made = await call(t, `/api/v1/locations/${home.id}/share-links`, { + as: ibrahim, + body: { thingId: router }, + }); + expect(made.statusCode, made.body).toBe(201); + const token = new URL((made.json() as { url: string }).url).pathname.slice('/s/'.length); + const res = await t.app.inject({ method: 'GET', url: `/api/v1/shared/${token}` }); + expect(res.statusCode, res.body).toBe(200); + expect((res.json() as { thing: { type: TypeRef } }).thing.type).toEqual({ + icon: 'lucide:router', + name: null, + builtinKey: 'network_device', + }); + }); + + it('a place grouped by type keeps the copy and the built-in apart, page after page', async () => { + // A thing can still be on the built-in itself (typed through the API); by name it falls + // between two things on the copy. + const attic = (await createThing(t, ibrahim, home, { name: 'Attic switch', typeId: copy })).id; + const garage = (await createThing(t, ibrahim, home, { name: 'Garage modem', typeId: builtin })) + .id; + const seen: { id: string; typeId: string | null }[] = []; + let cursor: string | null = null; + for (let i = 0; i < 20; i++) { + const page = ok( + await call( + t, + `/api/v1/places/${home.unplacedId}/contents?group=type&limit=1${ + cursor ? `&cursor=${encodeURIComponent(cursor)}` : '' + }`, + { as: ibrahim }, + ), + ) as unknown as { + things: { items: { id: string; type: TypeRef }[]; next_cursor: string | null }; + }; + seen.push(...page.things.items.map((x) => ({ id: x.id, typeId: x.type?.id ?? null }))); + cursor = page.things.next_cursor; + if (!cursor) break; + } + expect(cursor).toBeNull(); + const ids = seen.map((x) => x.id); + expect(new Set(ids).size).toBe(ids.length); + expect(ids).toEqual(expect.arrayContaining([router, attic, garage])); + // Each type's things come together: a type seen once never comes back after another. + const runs = seen.map((x) => x.typeId).filter((x, i, all) => i === 0 || all[i - 1] !== x); + expect(new Set(runs).size).toBe(runs.length); + }); + + it('a copy renamed by hand shows its own name everywhere', async () => { + const before = ok(await call(t, `/api/v1/types/${copy}`, { as: ibrahim })); + const res = await call(t, `/api/v1/types/${copy}`, { + as: ibrahim, + method: 'PATCH', + headers: { 'if-match': String(before.rowVersion) }, + body: { name: 'Mesh node' }, + }); + expect(res.statusCode, res.body).toBe(200); + expect(await typeOfThing(router)).toMatchObject({ name: 'Mesh node' }); + const d = await tool('get_thing', { thing_id: router }); + expect(d.thing.untrusted.type).toBe('Mesh node'); + }); +}); diff --git a/apps/server/src/types/graph.ts b/apps/server/src/types/graph.ts index dfd22e1a..0d63b66a 100644 --- a/apps/server/src/types/graph.ts +++ b/apps/server/src/types/graph.ts @@ -53,6 +53,16 @@ export const FIELD_COLUMNS = `f.id, f.owner_account_id, f.type_id, f.place_kind_ f.kind, f.unit, f.options, f.repeatable, f.required, f.sort, f.secret, f.archived_at, f.row_version`; +/** + * The built-in key a type is named and translated by, as SQL over the `public.types` row + * `alias`: a built-in's own, or, for an account's customised copy of one, its source's (#546). + * The copy keeps no name of its own until renamed (kept.customise_type), so it reads in each + * person's language; every reader that names a type goes through this, as builtinKeyOf() does. + */ +export const typeKeySql = (alias: string): string => + `coalesce(${alias}.builtin_key, + (SELECT k.builtin_key FROM public.types k WHERE k.id = ${alias}.copied_from_id))`; + /** A key a change would define twice along a chain (D92). */ export class Redefined extends Error { constructor(readonly key: string) { diff --git a/apps/web/src/components/vehicles/is-vehicle.ts b/apps/web/src/components/vehicles/is-vehicle.ts index f71c36a9..0cf38603 100644 --- a/apps/web/src/components/vehicles/is-vehicle.ts +++ b/apps/web/src/components/vehicles/is-vehicle.ts @@ -32,10 +32,15 @@ export function mainMeterOf(meters: readonly M[]): M return meters.find((m) => m.kind === 'distance') ?? meters[0] ?? null; } -/** Whether this thing is a vehicle; false while an account type's ancestry is still loading. */ +/** + * Whether this thing is a vehicle; false while an account type's ancestry is still loading. A + * vehicle built-in's key answers at once. Any other type is walked over the account's types: an + * account's customised copy carries its built-in's key (#546) but may sit under Vehicle, and the + * thing's type ref doesn't say whether it is the built-in itself or a copy. + */ export function useIsVehicle(thing: Pick, accountId: string): boolean { const builtin = thing.type?.builtinKey ? builtinIsVehicle(thing.type.builtinKey) : false; - const needTypes = !builtin && !!thing.type && !thing.type.builtinKey; + const needTypes = !builtin && !!thing.type; const types = useTypes(needTypes ? accountId : ''); if (builtin) return true; if (!needTypes) return false; diff --git a/apps/web/src/test/screens/customised-type.test.tsx b/apps/web/src/test/screens/customised-type.test.tsx new file mode 100644 index 00000000..88b7b6e3 --- /dev/null +++ b/apps/web/src/test/screens/customised-type.test.tsx @@ -0,0 +1,128 @@ +/** + * A customised built-in type keeps its name (#546). "Customise" makes the account's copy of a + * built-in with no name of its own; the server names it by the built-in's key (`builtinKey`) on + * the thing page and in the type list, so it reads in each person's language. The copy stands + * in for the built-in in every picker (#357). + */ +import { screen, waitFor, within } from '@testing-library/react'; +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { INV_IDS } from '@/api/inventory/mock/fixtures'; +import { inventoryPaths as p } from '@/api/inventory/paths'; +import { type MockState, ownerScenario } from '@/api/mock/fixtures'; +import { ensureVehiclesSeeded } from '@/api/vehicles/mock'; +import { findHeading, renderApp } from '@/test/app'; + +vi.setConfig({ testTimeout: 15_000 }); + +const T = INV_IDS.thing; +const copyId = '0190a000-0000-7000-8000-00000000c546'; + +/** Ibrahim's account has customised TV / display: its TV is on the copy, as the server leaves it. */ +function customised(): MockState { + const s = ownerScenario(); + const original = s.inventory.types.find((x) => x.id === INV_IDS.type.tvDisplay); + if (!original) throw new Error('fixture'); + s.inventory.types.push({ + ...structuredClone(original), + id: copyId, + name: null, + builtinKey: 'tv_display', + copiedFromId: original.id, + }); + const tv = s.inventory.things.find((x) => x.id === T.tv); + if (!tv?.type) throw new Error('fixture'); + tv.type = { ...tv.type, id: copyId, name: null, builtinKey: 'tv_display' }; + return s; +} + +describe('a customised built-in type (#546)', () => { + for (const { locale, name, actions, retype, title, confirm, newType, typed } of [ + { + locale: 'en', + name: 'TV / display', + actions: 'Actions', + retype: 'Re-type', + title: 'Change the type', + confirm: 'Change type', + newType: 'New type', + typed: 'disp', + }, + { + locale: 'de', + name: 'TV / Bildschirm', + actions: 'Aktionen', + retype: 'Typ ändern', + title: 'Typ ändern', + confirm: 'Typ ändern', + newType: 'Neuer Typ', + typed: 'Bildsch', + }, + ] as const) { + it(`the thing page names it, never "No type" (${locale})`, async () => { + await renderApp(`/t/${T.tv}`, { state: customised(), locale }); + await findHeading('Samsung TV, 55″'); + expect(screen.getAllByText(name).length).toBeGreaterThan(0); + }); + + it(`Change type offers it once, by its name, and picks the copy (${locale})`, async () => { + const { user, mock } = await renderApp(`/t/${T.drill}`, { state: customised(), locale }); + await findHeading('Bosch drill, 18 V'); + await user.click(screen.getByRole('button', { name: actions })); + await user.click(await screen.findByRole('menuitem', { name: retype })); + const dialog = await screen.findByRole('dialog', { name: title }); + await user.type(within(dialog).getByRole('combobox', { name: newType }), typed); + const options = await screen.findAllByRole('option', { name: new RegExp(`^${name}`) }); + expect(options).toHaveLength(1); + await user.click(options[0] as HTMLElement); + await user.click(within(dialog).getByRole('button', { name: confirm })); + await waitFor(() => + expect(mock.lastCall('POST', p.thingRetype(T.drill))?.body).toEqual({ typeId: copyId }), + ); + }); + } +}); + +/** From `md` up the thing page uses tabs; jsdom has no matchMedia, so a test opts in. */ +function desktop() { + vi.stubGlobal('matchMedia', (q: string) => ({ + matches: q.includes('min-width: 768px'), + media: q, + onchange: null, + addEventListener() {}, + removeEventListener() {}, + addListener() {}, + removeListener() {}, + dispatchEvent: () => false, + })); +} + +afterEach(() => { + vi.unstubAllGlobals(); +}); + +describe('a customised built-in moved under Vehicle', () => { + it('shows as a vehicle, as the server says (kept.is_vehicle_type follows the parent)', async () => { + desktop(); + // The account customised Power tool and put its copy under Vehicle; the drill is on the copy. + // Its row names the built-in it came from (`power_tool`), which is no vehicle by itself. + const s = ownerScenario(); + ensureVehiclesSeeded(s); + const original = s.inventory.types.find((x) => x.id === INV_IDS.type.powerTool); + if (!original) throw new Error('fixture'); + s.inventory.types.push({ + ...structuredClone(original), + id: copyId, + parentId: INV_IDS.type.vehicle, + name: null, + builtinKey: 'power_tool', + copiedFromId: original.id, + }); + const drill = s.inventory.things.find((x) => x.id === T.drill); + if (!drill?.type) throw new Error('fixture'); + drill.type = { ...drill.type, id: copyId, name: null, builtinKey: 'power_tool' }; + await renderApp(`/t/${T.drill}`, { state: s }); + await findHeading('Bosch drill, 18 V'); + const tabs = await screen.findByRole('tablist', { name: 'Sections' }); + await waitFor(() => expect(within(tabs).getAllByRole('tab')[0]?.textContent).toBe('Overview')); + }); +});