From 3ad368d233de42627952e6ac21ff645845e7a806 Mon Sep 17 00:00:00 2001 From: Bailey Pumfleet Date: Wed, 4 Nov 2026 11:41:40 -0600 Subject: [PATCH 01/30] Scheduling: keep meetings and calendars right when a booking's hosts change Replacing a host reset the meeting link even when the meeting was someone else's: Zoom never gives a link back on update, so a collective booking lost it for good, and a new host who sorted first started a second meeting. Meetings now stay with whoever runs them, and only reset when that host leaves. A booking going to another host and back reused a deleted event's key, and Graph's answer to a repeated transactionId is undocumented, so events now get a new key each time they're deleted. Removing an event goes by the ledger, so an event on a calendar that's stopped being the write target still goes. Co-hosts' events now get a Meet link made by someone else's event. Slots for moving a booking come from the hosts it has, not who the event type would pick today. --- apps/api/src/routes/scheduling-client.ts | 70 +- .../db/migrations/0126_tidy_marauders.sql | 1 + .../db/migrations/meta/0126_snapshot.json | 31083 ++++++++++++++++ packages/db/migrations/meta/_journal.json | 7 + packages/db/src/schema/scheduling.ts | 2 + packages/scheduling/AGENTS.md | 15 +- packages/scheduling/src/availability.ts | 70 + packages/scheduling/src/bookings.ts | 83 +- packages/scheduling/src/calendar/writes.ts | 57 +- packages/scheduling/src/testing.ts | 42 +- packages/scheduling/test/host-changes.test.ts | 507 + 11 files changed, 31855 insertions(+), 82 deletions(-) create mode 100644 packages/db/migrations/0126_tidy_marauders.sql create mode 100644 packages/db/migrations/meta/0126_snapshot.json create mode 100644 packages/scheduling/test/host-changes.test.ts diff --git a/apps/api/src/routes/scheduling-client.ts b/apps/api/src/routes/scheduling-client.ts index 6683af482..651da3f39 100644 --- a/apps/api/src/routes/scheduling-client.ts +++ b/apps/api/src/routes/scheduling-client.ts @@ -23,6 +23,7 @@ import { getHost, getLogoRow, getSettingsRow, + listBookingSlots, listConnections, listEventTypeSlots, listSchedules, @@ -256,45 +257,42 @@ export function createSchedulingClientRoutes(opts: { return c.json(base); }); - const slotsFor = async ( - c: Context, - eventType: string, - hostRefs: readonly string[] | undefined, - durationMinutes?: number, - attributes?: Record, - ) => { + const slotQueryOf = (c: Context) => { const query = SlotQuery.safeParse({ start: c.req.query("start"), end: c.req.query("end"), duration_minutes: c.req.query("duration_minutes"), }); if (!query.success) throw invalidBody("`start` and `end` are required."); - const slots = await listEventTypeSlots(c.var.session.env, { - eventTypeRef: eventType, + return { fromMs: instant(query.data.start, "start"), toMs: instant(query.data.end, "end"), nowMs: (deps.now?.() ?? new Date()).getTime(), - hostRefs, - attributes, - durationMinutes: durationMinutes ?? query.data.duration_minutes, - }); - // An attendee sees times, never who else could take them. - return c.json({ - object: "list" as const, - data: slots.map((slot) => ({ start: iso(slot.startMs), end: iso(slot.endMs) })), - has_more: false, - }); + durationMinutes: query.data.duration_minutes, + }; }; - router.get("/slots", async (c) => - slotsFor( - c, - eventTypeOf(c), - c.var.session.session.hostId ? [c.var.session.session.hostId] : undefined, - undefined, - sessionAttributes(c.var.session.session, deps), - ), - ); + // An attendee sees times, never who else could take them. + const slotList = (slots: readonly { startMs: number; endMs: number }[]) => ({ + object: "list" as const, + data: slots.map((slot) => ({ start: iso(slot.startMs), end: iso(slot.endMs) })), + has_more: false, + }); + + router.get("/slots", async (c) => { + // The session's kind first: the wrong one is a 404, whatever the query says. + const eventTypeRef = eventTypeOf(c); + return c.json( + slotList( + await listEventTypeSlots(c.var.session.env, { + ...slotQueryOf(c), + eventTypeRef, + hostRefs: c.var.session.session.hostId ? [c.var.session.session.hostId] : undefined, + attributes: sessionAttributes(c.var.session.session, deps), + }), + ), + ); + }); router.post("/bookings", async (c) => { const eventType = eventTypeOf(c); @@ -348,10 +346,18 @@ export function createSchedulingClientRoutes(opts: { }); router.get("/booking/slots", async (c) => { - const id = bookingOf(c); - const booking = await getBooking(c.var.session.env, id, deps); - const duration = (Date.parse(booking.end) - Date.parse(booking.start)) / 60_000; - return slotsFor(c, booking.event_type, booking.hosts, duration); + const bookingId = bookingOf(c); + const { fromMs, toMs, nowMs } = slotQueryOf(c); + return c.json( + slotList( + await listBookingSlots(c.var.session.env, { + bookingId, + fromMs, + toMs, + nowMs, + }), + ), + ); }); router.post("/booking/reschedule", async (c) => { diff --git a/packages/db/migrations/0126_tidy_marauders.sql b/packages/db/migrations/0126_tidy_marauders.sql new file mode 100644 index 000000000..8cc38c424 --- /dev/null +++ b/packages/db/migrations/0126_tidy_marauders.sql @@ -0,0 +1 @@ +ALTER TABLE "scheduling_calendar_event" ADD COLUMN "key_generation" integer DEFAULT 0 NOT NULL; \ No newline at end of file diff --git a/packages/db/migrations/meta/0126_snapshot.json b/packages/db/migrations/meta/0126_snapshot.json new file mode 100644 index 000000000..1c10b7bb9 --- /dev/null +++ b/packages/db/migrations/meta/0126_snapshot.json @@ -0,0 +1,31083 @@ +{ + "id": "a4afc925-7783-4789-aab6-062ad775edfb", + "prevId": "05854061-63ad-4a3c-b76c-02b6f4a74d47", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account": { + "name": "account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp", + "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", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "account_userId_idx": { + "name": "account_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.apikey": { + "name": "apikey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "config_id": { + "name": "config_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'default'" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refill_interval": { + "name": "refill_interval", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refill_amount": { + "name": "refill_amount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_refill_at": { + "name": "last_refill_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_enabled": { + "name": "rate_limit_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_time_window": { + "name": "rate_limit_time_window", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 86400000 + }, + "rate_limit_max": { + "name": "rate_limit_max", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 10 + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "remaining": { + "name": "remaining", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_request": { + "name": "last_request", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "apikey_configId_idx": { + "name": "apikey_configId_idx", + "columns": [ + { + "expression": "config_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "apikey_referenceId_idx": { + "name": "apikey_referenceId_idx", + "columns": [ + { + "expression": "reference_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "apikey_key_idx": { + "name": "apikey_key_idx", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.invitation": { + "name": "invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "inviter_id": { + "name": "inviter_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "invitation_organizationId_idx": { + "name": "invitation_organizationId_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "invitation_email_idx": { + "name": "invitation_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "invitation_organization_id_organization_id_fk": { + "name": "invitation_organization_id_organization_id_fk", + "tableFrom": "invitation", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "invitation_inviter_id_user_id_fk": { + "name": "invitation_inviter_id_user_id_fk", + "tableFrom": "invitation", + "tableTo": "user", + "columnsFrom": [ + "inviter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.member": { + "name": "member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "member_organizationId_idx": { + "name": "member_organizationId_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "member_userId_idx": { + "name": "member_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "member_organization_id_organization_id_fk": { + "name": "member_organization_id_organization_id_fk", + "tableFrom": "member", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "member_user_id_user_id_fk": { + "name": "member_user_id_user_id_fk", + "tableFrom": "member", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization": { + "name": "organization", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "require_two_factor": { + "name": "require_two_factor", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "require_sso": { + "name": "require_sso", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "organization_slug_unique": { + "name": "organization_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.passkey": { + "name": "passkey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "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": "text", + "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", + "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, + "concurrently": false, + "method": "btree", + "with": {} + }, + "passkey_credentialID_idx": { + "name": "passkey_credentialID_idx", + "columns": [ + { + "expression": "credential_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "passkey_user_id_user_id_fk": { + "name": "passkey_user_id_user_id_fk", + "tableFrom": "passkey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_connection_binding": { + "name": "scim_connection_binding", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "connection_key": { + "name": "connection_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "decommissioned_at": { + "name": "decommissioned_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "decommission_status": { + "name": "decommission_status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "decommission_cursor_user_id": { + "name": "decommission_cursor_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "decommission_reconciled_user_count": { + "name": "decommission_reconciled_user_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "decommission_batch_count": { + "name": "decommission_batch_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "decommission_revision": { + "name": "decommission_revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "decommission_completed_at": { + "name": "decommission_completed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "decommission_lease_id": { + "name": "decommission_lease_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "decommission_lease_expires_at": { + "name": "decommission_lease_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "scimConnectionBinding_connectionId_idx": { + "name": "scimConnectionBinding_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_connection_binding_connection_key_unique": { + "name": "scim_connection_binding_connection_key_unique", + "nullsNotDistinct": false, + "columns": [ + "connection_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_group": { + "name": "scim_group", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name_key": { + "name": "display_name_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "external_id_key": { + "name": "external_id_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "order_key": { + "name": "order_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimGroup_connectionId_idx": { + "name": "scimGroup_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimGroup_provisioningDomainId_idx": { + "name": "scimGroup_provisioningDomainId_idx", + "columns": [ + { + "expression": "provisioning_domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_group_display_name_key_unique": { + "name": "scim_group_display_name_key_unique", + "nullsNotDistinct": false, + "columns": [ + "display_name_key" + ] + }, + "scim_group_external_id_key_unique": { + "name": "scim_group_external_id_key_unique", + "nullsNotDistinct": false, + "columns": [ + "external_id_key" + ] + }, + "scim_group_order_key_unique": { + "name": "scim_group_order_key_unique", + "nullsNotDistinct": false, + "columns": [ + "order_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_group_member": { + "name": "scim_group_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scim_user_id": { + "name": "scim_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "membership_key": { + "name": "membership_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimGroupMember_connectionId_idx": { + "name": "scimGroupMember_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimGroupMember_groupId_idx": { + "name": "scimGroupMember_groupId_idx", + "columns": [ + { + "expression": "group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimGroupMember_scimUserId_idx": { + "name": "scimGroupMember_scimUserId_idx", + "columns": [ + { + "expression": "scim_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_group_member_group_id_scim_group_id_fk": { + "name": "scim_group_member_group_id_scim_group_id_fk", + "tableFrom": "scim_group_member", + "tableTo": "scim_group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scim_group_member_scim_user_id_scim_user_id_fk": { + "name": "scim_group_member_scim_user_id_scim_user_id_fk", + "tableFrom": "scim_group_member", + "tableTo": "scim_user", + "columnsFrom": [ + "scim_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_group_member_membership_key_unique": { + "name": "scim_group_member_membership_key_unique", + "nullsNotDistinct": false, + "columns": [ + "membership_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_identity_tombstone": { + "name": "scim_identity_tombstone", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "external_id_key": { + "name": "external_id_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "profile": { + "name": "profile", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimIdentityTombstone_connectionId_idx": { + "name": "scimIdentityTombstone_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimIdentityTombstone_provisioningDomainId_idx": { + "name": "scimIdentityTombstone_provisioningDomainId_idx", + "columns": [ + { + "expression": "provisioning_domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimIdentityTombstone_userId_idx": { + "name": "scimIdentityTombstone_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_identity_tombstone_user_id_user_id_fk": { + "name": "scim_identity_tombstone_user_id_user_id_fk", + "tableFrom": "scim_identity_tombstone", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_identity_tombstone_external_id_key_unique": { + "name": "scim_identity_tombstone_external_id_key_unique", + "nullsNotDistinct": false, + "columns": [ + "external_id_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_managed_connection": { + "name": "scim_managed_connection", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "creation_request_id": { + "name": "creation_request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "decommission_started_at": { + "name": "decommission_started_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "decommission_started_by": { + "name": "decommission_started_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "decommissioned_at": { + "name": "decommissioned_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "decommissioned_by": { + "name": "decommissioned_by", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "scimManagedConnection_provisioningDomainId_idx": { + "name": "scimManagedConnection_provisioningDomainId_idx", + "columns": [ + { + "expression": "provisioning_domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_managed_connection_creation_request_id_unique": { + "name": "scim_managed_connection_creation_request_id_unique", + "nullsNotDistinct": false, + "columns": [ + "creation_request_id" + ] + }, + "scim_managed_connection_connection_id_unique": { + "name": "scim_managed_connection_connection_id_unique", + "nullsNotDistinct": false, + "columns": [ + "connection_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_managed_connection_event": { + "name": "scim_managed_connection_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_record_id": { + "name": "connection_record_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_key": { + "name": "event_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credential_id": { + "name": "credential_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimManagedConnectionEvent_connectionRecordId_idx": { + "name": "scimManagedConnectionEvent_connectionRecordId_idx", + "columns": [ + { + "expression": "connection_record_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_managed_connection_event_connection_record_id_scim_managed_connection_id_fk": { + "name": "scim_managed_connection_event_connection_record_id_scim_managed_connection_id_fk", + "tableFrom": "scim_managed_connection_event", + "tableTo": "scim_managed_connection", + "columnsFrom": [ + "connection_record_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_managed_connection_event_event_key_unique": { + "name": "scim_managed_connection_event_event_key_unique", + "nullsNotDistinct": false, + "columns": [ + "event_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_managed_credential": { + "name": "scim_managed_credential", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_record_id": { + "name": "connection_record_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credential_id": { + "name": "credential_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_digest": { + "name": "token_digest", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hash_version": { + "name": "hash_version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "active_slot_key": { + "name": "active_slot_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serialized_scopes": { + "name": "serialized_scopes", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "revoked_by": { + "name": "revoked_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "decommissioned_at": { + "name": "decommissioned_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "scimManagedCredential_connectionRecordId_idx": { + "name": "scimManagedCredential_connectionRecordId_idx", + "columns": [ + { + "expression": "connection_record_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_managed_credential_connection_record_id_scim_managed_connection_id_fk": { + "name": "scim_managed_credential_connection_record_id_scim_managed_connection_id_fk", + "tableFrom": "scim_managed_credential", + "tableTo": "scim_managed_connection", + "columnsFrom": [ + "connection_record_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_managed_credential_credential_id_unique": { + "name": "scim_managed_credential_credential_id_unique", + "nullsNotDistinct": false, + "columns": [ + "credential_id" + ] + }, + "scim_managed_credential_active_slot_key_unique": { + "name": "scim_managed_credential_active_slot_key_unique", + "nullsNotDistinct": false, + "columns": [ + "active_slot_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_projection_grant": { + "name": "scim_projection_grant", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scim_user_id": { + "name": "scim_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_kind": { + "name": "source_kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_id": { + "name": "source_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_value": { + "name": "source_value", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "grant_key": { + "name": "grant_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimProjectionGrant_connectionId_idx": { + "name": "scimProjectionGrant_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimProjectionGrant_provisioningDomainId_idx": { + "name": "scimProjectionGrant_provisioningDomainId_idx", + "columns": [ + { + "expression": "provisioning_domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimProjectionGrant_scimUserId_idx": { + "name": "scimProjectionGrant_scimUserId_idx", + "columns": [ + { + "expression": "scim_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimProjectionGrant_userId_idx": { + "name": "scimProjectionGrant_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_projection_grant_scim_user_id_scim_user_id_fk": { + "name": "scim_projection_grant_scim_user_id_scim_user_id_fk", + "tableFrom": "scim_projection_grant", + "tableTo": "scim_user", + "columnsFrom": [ + "scim_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scim_projection_grant_user_id_user_id_fk": { + "name": "scim_projection_grant_user_id_user_id_fk", + "tableFrom": "scim_projection_grant", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_projection_grant_grant_key_unique": { + "name": "scim_projection_grant_grant_key_unique", + "nullsNotDistinct": false, + "columns": [ + "grant_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_subject": { + "name": "scim_subject", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "profile_source_id": { + "name": "profile_source_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimSubject_profileSourceId_idx": { + "name": "scimSubject_profileSourceId_idx", + "columns": [ + { + "expression": "profile_source_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_subject_user_id_user_id_fk": { + "name": "scim_subject_user_id_user_id_fk", + "tableFrom": "scim_subject", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_subject_user_id_unique": { + "name": "scim_subject_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_user": { + "name": "scim_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "connection_user_key": { + "name": "connection_user_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_name": { + "name": "user_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_name_key": { + "name": "user_name_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "primary_email": { + "name": "primary_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "work_email_value_index": { + "name": "work_email_value_index", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_value_index": { + "name": "email_value_index", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "formatted_name": { + "name": "formatted_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "given_name": { + "name": "given_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "family_name": { + "name": "family_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serialized_emails": { + "name": "serialized_emails", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serialized_attributes": { + "name": "serialized_attributes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "external_id_key": { + "name": "external_id_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "order_key": { + "name": "order_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimUser_connectionId_idx": { + "name": "scimUser_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimUser_provisioningDomainId_idx": { + "name": "scimUser_provisioningDomainId_idx", + "columns": [ + { + "expression": "provisioning_domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimUser_userId_idx": { + "name": "scimUser_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_user_user_id_user_id_fk": { + "name": "scim_user_user_id_user_id_fk", + "tableFrom": "scim_user", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_user_connection_user_key_unique": { + "name": "scim_user_connection_user_key_unique", + "nullsNotDistinct": false, + "columns": [ + "connection_user_key" + ] + }, + "scim_user_user_name_key_unique": { + "name": "scim_user_user_name_key_unique", + "nullsNotDistinct": false, + "columns": [ + "user_name_key" + ] + }, + "scim_user_external_id_key_unique": { + "name": "scim_user_external_id_key_unique", + "nullsNotDistinct": false, + "columns": [ + "external_id_key" + ] + }, + "scim_user_order_key_unique": { + "name": "scim_user_order_key_unique", + "nullsNotDistinct": false, + "columns": [ + "order_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "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": "text", + "primaryKey": false, + "notNull": true + }, + "active_organization_id": { + "name": "active_organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sso_provider_id": { + "name": "sso_provider_id", + "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, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_token_unique": { + "name": "session_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sso_provider": { + "name": "sso_provider", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "issuer": { + "name": "issuer", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "oidc_config": { + "name": "oidc_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "saml_config": { + "name": "saml_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_verified": { + "name": "domain_verified", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "sso_provider_user_id_user_id_fk": { + "name": "sso_provider_user_id_user_id_fk", + "tableFrom": "sso_provider", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sso_provider_provider_id_unique": { + "name": "sso_provider_provider_id_unique", + "nullsNotDistinct": false, + "columns": [ + "provider_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.two_factor": { + "name": "two_factor", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "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": "text", + "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", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "twoFactor_secret_idx": { + "name": "twoFactor_secret_idx", + "columns": [ + { + "expression": "secret", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "twoFactor_userId_idx": { + "name": "twoFactor_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "two_factor_user_id_user_id_fk": { + "name": "two_factor_user_id_user_id_fk", + "tableFrom": "two_factor", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "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", + "primaryKey": false, + "notNull": false + }, + "two_factor_enabled": { + "name": "two_factor_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "canonical_email": { + "name": "canonical_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_organization_limit": { + "name": "owned_organization_limit", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "user_canonicalEmail_idx": { + "name": "user_canonicalEmail_idx", + "columns": [ + { + "expression": "canonical_email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verification": { + "name": "verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "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, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_account": { + "name": "billing_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "billing_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider_customer_id": { + "name": "provider_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "collection_method": { + "name": "collection_method", + "type": "billing_collection_method", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'charge_automatically'" + }, + "net_terms_days": { + "name": "net_terms_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 30 + }, + "allowed_payment_methods": { + "name": "allowed_payment_methods", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{card}'::text[]" + }, + "required_payment_methods": { + "name": "required_payment_methods", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "tax_mode": { + "name": "tax_mode", + "type": "billing_tax_mode", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'none'" + }, + "billing_email": { + "name": "billing_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "billing_cc": { + "name": "billing_cc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "billing_name": { + "name": "billing_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "billing_address": { + "name": "billing_address", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "tax_id": { + "name": "tax_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "spend_limit_cents": { + "name": "spend_limit_cents", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "alert_thresholds": { + "name": "alert_thresholds", + "type": "integer[]", + "primaryKey": false, + "notNull": true, + "default": "'{80,100}'::integer[]" + }, + "grace_days": { + "name": "grace_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 14 + }, + "status": { + "name": "status", + "type": "billing_account_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "past_due_since": { + "name": "past_due_since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "hold_exempt_until": { + "name": "hold_exempt_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "payment_method": { + "name": "payment_method", + "type": "jsonb", + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "billing_account_organization_id_organization_id_fk": { + "name": "billing_account_organization_id_organization_id_fk", + "tableFrom": "billing_account", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_account_organization_unique": { + "name": "billing_account_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_budget": { + "name": "billing_budget", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope": { + "name": "scope", + "type": "billing_budget_scope", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "amount_cents": { + "name": "amount_cents", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "alert_thresholds": { + "name": "alert_thresholds", + "type": "integer[]", + "primaryKey": false, + "notNull": true, + "default": "'{80,100}'::integer[]" + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_budget_member_default_idx": { + "name": "billing_budget_member_default_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_budget\".\"scope\" = 'member_default'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_budget_user_idx": { + "name": "billing_budget_user_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_budget\".\"scope\" = 'user'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_budget_project_idx": { + "name": "billing_budget_project_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_budget\".\"scope\" = 'project'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_budget_api_key_idx": { + "name": "billing_budget_api_key_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "api_key_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_budget\".\"scope\" = 'api_key'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_budget_organization_id_organization_id_fk": { + "name": "billing_budget_organization_id_organization_id_fk", + "tableFrom": "billing_budget", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_budget_user_id_user_id_fk": { + "name": "billing_budget_user_id_user_id_fk", + "tableFrom": "billing_budget", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_budget_api_key_id_apikey_id_fk": { + "name": "billing_budget_api_key_id_apikey_id_fk", + "tableFrom": "billing_budget", + "tableTo": "apikey", + "columnsFrom": [ + "api_key_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_budget_created_by_user_id_user_id_fk": { + "name": "billing_budget_created_by_user_id_user_id_fk", + "tableFrom": "billing_budget", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "billing_budget_project_fk": { + "name": "billing_budget_project_fk", + "tableFrom": "billing_budget", + "tableTo": "project", + "columnsFrom": [ + "project_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "billing_budget_target_check": { + "name": "billing_budget_target_check", + "value": "case \"billing_budget\".\"scope\"\n when 'member_default' then \"billing_budget\".\"user_id\" is null and \"billing_budget\".\"project_id\" is null and \"billing_budget\".\"api_key_id\" is null and \"billing_budget\".\"amount_cents\" is not null\n when 'user' then \"billing_budget\".\"user_id\" is not null and \"billing_budget\".\"project_id\" is null and \"billing_budget\".\"api_key_id\" is null\n when 'project' then \"billing_budget\".\"user_id\" is null and \"billing_budget\".\"project_id\" is not null and \"billing_budget\".\"api_key_id\" is null and \"billing_budget\".\"amount_cents\" is not null\n when 'api_key' then \"billing_budget\".\"user_id\" is null and \"billing_budget\".\"project_id\" is null and \"billing_budget\".\"api_key_id\" is not null and \"billing_budget\".\"amount_cents\" is not null\n end" + }, + "billing_budget_amount_check": { + "name": "billing_budget_amount_check", + "value": "\"billing_budget\".\"amount_cents\" is null or \"billing_budget\".\"amount_cents\" >= 0" + } + }, + "isRLSEnabled": false + }, + "public.billing_budget_hold": { + "name": "billing_budget_hold", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope": { + "name": "scope", + "type": "billing_budget_scope", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "spent_cents": { + "name": "spent_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "limit_cents": { + "name": "limit_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "billing_budget_hold_organization_id_organization_id_fk": { + "name": "billing_budget_hold_organization_id_organization_id_fk", + "tableFrom": "billing_budget_hold", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "billing_budget_hold_organization_id_scope_target_id_pk": { + "name": "billing_budget_hold_organization_id_scope_target_id_pk", + "columns": [ + "organization_id", + "scope", + "target_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_contract": { + "name": "billing_contract", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "billing_contract_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "billing_contract_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "terms": { + "name": "terms", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "effective_from": { + "name": "effective_from", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "effective_until": { + "name": "effective_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "term_end": { + "name": "term_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "auto_renew": { + "name": "auto_renew", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "supersedes_id": { + "name": "supersedes_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pending_invoice_id": { + "name": "pending_invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pending_expires_at": { + "name": "pending_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reference": { + "name": "reference", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "canceled_at": { + "name": "canceled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_contract_organization_idx": { + "name": "billing_contract_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "effective_from", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_contract_pending_idx": { + "name": "billing_contract_pending_idx", + "columns": [ + { + "expression": "pending_expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_contract\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_contract_organization_id_organization_id_fk": { + "name": "billing_contract_organization_id_organization_id_fk", + "tableFrom": "billing_contract", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_contract_account_id_billing_account_id_fk": { + "name": "billing_contract_account_id_billing_account_id_fk", + "tableFrom": "billing_contract", + "tableTo": "billing_account", + "columnsFrom": [ + "account_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_contract_created_by_user_id_user_id_fk": { + "name": "billing_contract_created_by_user_id_user_id_fk", + "tableFrom": "billing_contract", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_counter": { + "name": "billing_counter", + "schema": "", + "columns": { + "name": { + "name": "name", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_credit_entry": { + "name": "billing_credit_entry", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "grant_id": { + "name": "grant_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "billing_credit_entry_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_credit_entry_grant_idx": { + "name": "billing_credit_entry_grant_idx", + "columns": [ + { + "expression": "grant_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_credit_entry_grant_id_billing_credit_grant_id_fk": { + "name": "billing_credit_entry_grant_id_billing_credit_grant_id_fk", + "tableFrom": "billing_credit_entry", + "tableTo": "billing_credit_grant", + "columnsFrom": [ + "grant_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_credit_grant": { + "name": "billing_credit_grant", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "billing_grant_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "meter": { + "name": "meter", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dimension": { + "name": "dimension", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "applies_to": { + "name": "applies_to", + "type": "billing_grant_applies_to", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'usage'" + }, + "source": { + "name": "source", + "type": "billing_grant_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "grant_key": { + "name": "grant_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contract_id": { + "name": "contract_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "effective_at": { + "name": "effective_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "voided_at": { + "name": "voided_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": { + "billing_credit_grant_organization_idx": { + "name": "billing_credit_grant_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "effective_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_credit_grant_invoice_idx": { + "name": "billing_credit_grant_invoice_idx", + "columns": [ + { + "expression": "invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_credit_grant\".\"invoice_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_credit_grant_organization_id_organization_id_fk": { + "name": "billing_credit_grant_organization_id_organization_id_fk", + "tableFrom": "billing_credit_grant", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_credit_grant_created_by_user_id_user_id_fk": { + "name": "billing_credit_grant_created_by_user_id_user_id_fk", + "tableFrom": "billing_credit_grant", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_credit_grant_key_unique": { + "name": "billing_credit_grant_key_unique", + "nullsNotDistinct": false, + "columns": [ + "grant_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_credit_note": { + "name": "billing_credit_note", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "number": { + "name": "number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "amount_cents": { + "name": "amount_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "refund_cents": { + "name": "refund_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "memo": { + "name": "memo", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "billing_credit_note_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "provider_credit_note_id": { + "name": "provider_credit_note_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sync_attempts": { + "name": "sync_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_sync_at": { + "name": "next_sync_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sync_error": { + "name": "sync_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_credit_note_invoice_idx": { + "name": "billing_credit_note_invoice_idx", + "columns": [ + { + "expression": "invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_credit_note_sync_idx": { + "name": "billing_credit_note_sync_idx", + "columns": [ + { + "expression": "next_sync_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_credit_note\".\"next_sync_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_credit_note_invoice_id_billing_invoice_id_fk": { + "name": "billing_credit_note_invoice_id_billing_invoice_id_fk", + "tableFrom": "billing_credit_note", + "tableTo": "billing_invoice", + "columnsFrom": [ + "invoice_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_credit_note_number_unique": { + "name": "billing_credit_note_number_unique", + "nullsNotDistinct": false, + "columns": [ + "number" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_hold": { + "name": "billing_hold", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "billing_hold_reason", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "billing_hold_organization_id_organization_id_fk": { + "name": "billing_hold_organization_id_organization_id_fk", + "tableFrom": "billing_hold", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "billing_hold_organization_id_reason_pk": { + "name": "billing_hold_organization_id_reason_pk", + "columns": [ + "organization_id", + "reason" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_invoice": { + "name": "billing_invoice", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_name": { + "name": "organization_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_slug": { + "name": "organization_slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "number": { + "name": "number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "billing_invoice_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "billing_invoice_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "currency": { + "name": "currency", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'usd'" + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "period_end": { + "name": "period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "subtotal_cents": { + "name": "subtotal_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "discount_cents": { + "name": "discount_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "credit_cents": { + "name": "credit_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "tax_cents": { + "name": "tax_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "total_cents": { + "name": "total_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "amount_paid_cents": { + "name": "amount_paid_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "amount_due_cents": { + "name": "amount_due_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "collection_method": { + "name": "collection_method", + "type": "billing_collection_method", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "billing_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider_customer_id": { + "name": "provider_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_invoice_id": { + "name": "provider_invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hosted_url": { + "name": "hosted_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pdf_url": { + "name": "pdf_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "billing_email": { + "name": "billing_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "due_at": { + "name": "due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "finalized_at": { + "name": "finalized_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "paid_at": { + "name": "paid_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "voided_at": { + "name": "voided_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sync_action": { + "name": "sync_action", + "type": "billing_sync_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "sync_attempts": { + "name": "sync_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_sync_at": { + "name": "next_sync_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sync_error": { + "name": "sync_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "collection_attempts": { + "name": "collection_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_collection_at": { + "name": "next_collection_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "payment_state": { + "name": "payment_state", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "payment_error": { + "name": "payment_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "terms_snapshot": { + "name": "terms_snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "memo": { + "name": "memo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_invoice_organization_idx": { + "name": "billing_invoice_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_period_idx": { + "name": "billing_invoice_period_idx", + "columns": [ + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_invoice\".\"kind\" = 'period' and \"billing_invoice\".\"status\" <> 'void'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_final_idx": { + "name": "billing_invoice_final_idx", + "columns": [ + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_invoice\".\"kind\" = 'final' and \"billing_invoice\".\"status\" <> 'void'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_sync_idx": { + "name": "billing_invoice_sync_idx", + "columns": [ + { + "expression": "next_sync_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_invoice\".\"next_sync_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_collection_idx": { + "name": "billing_invoice_collection_idx", + "columns": [ + { + "expression": "next_collection_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_invoice\".\"next_collection_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_created_at_idx": { + "name": "billing_invoice_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_invoice_number_unique": { + "name": "billing_invoice_number_unique", + "nullsNotDistinct": false, + "columns": [ + "number" + ] + }, + "billing_invoice_provider_unique": { + "name": "billing_invoice_provider_unique", + "nullsNotDistinct": false, + "columns": [ + "provider_invoice_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_invoice_line": { + "name": "billing_invoice_line", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "billing_line_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "meter": { + "name": "meter", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dimension": { + "name": "dimension", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "quantity": { + "name": "quantity", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "covered_units": { + "name": "covered_units", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "unit_nanos": { + "name": "unit_nanos", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "amount_cents": { + "name": "amount_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "period_end": { + "name": "period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "contract_id": { + "name": "contract_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "grant_id": { + "name": "grant_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "charge_key": { + "name": "charge_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "detail": { + "name": "detail", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "billing_invoice_line_invoice_idx": { + "name": "billing_invoice_line_invoice_idx", + "columns": [ + { + "expression": "invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "position", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_line_charge_key_idx": { + "name": "billing_invoice_line_charge_key_idx", + "columns": [ + { + "expression": "charge_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_invoice_line\".\"charge_key\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_line_contract_idx": { + "name": "billing_invoice_line_contract_idx", + "columns": [ + { + "expression": "contract_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_invoice_line\".\"contract_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_invoice_line_invoice_id_billing_invoice_id_fk": { + "name": "billing_invoice_line_invoice_id_billing_invoice_id_fk", + "tableFrom": "billing_invoice_line", + "tableTo": "billing_invoice", + "columnsFrom": [ + "invoice_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_notification": { + "name": "billing_notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "billing_notification_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "recipients": { + "name": "recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_notification_next_attempt_idx": { + "name": "billing_notification_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_notification\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_notification_created_at_idx": { + "name": "billing_notification_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_notification_organization_id_organization_id_fk": { + "name": "billing_notification_organization_id_organization_id_fk", + "tableFrom": "billing_notification", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_notification_user_id_user_id_fk": { + "name": "billing_notification_user_id_user_id_fk", + "tableFrom": "billing_notification", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_notification_dedupe_unique": { + "name": "billing_notification_dedupe_unique", + "nullsNotDistinct": false, + "columns": [ + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_payment": { + "name": "billing_payment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount_cents": { + "name": "amount_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reference": { + "name": "reference", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_payment_id": { + "name": "provider_payment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "received_at": { + "name": "received_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "recorded_by_user_id": { + "name": "recorded_by_user_id", + "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()" + } + }, + "indexes": { + "billing_payment_invoice_idx": { + "name": "billing_payment_invoice_idx", + "columns": [ + { + "expression": "invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_payment_invoice_id_billing_invoice_id_fk": { + "name": "billing_payment_invoice_id_billing_invoice_id_fk", + "tableFrom": "billing_payment", + "tableTo": "billing_invoice", + "columnsFrom": [ + "invoice_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_payment_provider_unique": { + "name": "billing_payment_provider_unique", + "nullsNotDistinct": false, + "columns": [ + "provider_payment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_period": { + "name": "billing_period", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "period_end": { + "name": "period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage": { + "name": "usage", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "warnings": { + "name": "warnings", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_period_account_start_idx": { + "name": "billing_period_account_start_idx", + "columns": [ + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_period_organization_id_organization_id_fk": { + "name": "billing_period_organization_id_organization_id_fk", + "tableFrom": "billing_period", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_period_account_id_billing_account_id_fk": { + "name": "billing_period_account_id_billing_account_id_fk", + "tableFrom": "billing_period", + "tableTo": "billing_account", + "columnsFrom": [ + "account_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_provider_event": { + "name": "billing_provider_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "billing_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider_event_id": { + "name": "provider_event_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "billing_provider_event_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "processed_at": { + "name": "processed_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": { + "billing_provider_event_unique_idx": { + "name": "billing_provider_event_unique_idx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_provider_event_next_attempt_idx": { + "name": "billing_provider_event_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_provider_event\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_provider_event_created_at_idx": { + "name": "billing_provider_event_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_quota": { + "name": "billing_quota", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "meter": { + "name": "meter", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "reserved": { + "name": "reserved", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "billing_quota_organization_id_organization_id_fk": { + "name": "billing_quota_organization_id_organization_id_fk", + "tableFrom": "billing_quota", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "billing_quota_organization_id_meter_period_start_pk": { + "name": "billing_quota_organization_id_meter_period_start_pk", + "columns": [ + "organization_id", + "meter", + "period_start" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_usage": { + "name": "billing_usage", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hour_start": { + "name": "hour_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "meter": { + "name": "meter", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dimension": { + "name": "dimension", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "shard": { + "name": "shard", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "quantity": { + "name": "quantity", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "billing_usage_hour_idx": { + "name": "billing_usage_hour_idx", + "columns": [ + { + "expression": "hour_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_usage_organization_id_organization_id_fk": { + "name": "billing_usage_organization_id_organization_id_fk", + "tableFrom": "billing_usage", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "billing_usage_organization_id_hour_start_meter_dimension_environment_id_shard_pk": { + "name": "billing_usage_organization_id_hour_start_meter_dimension_environment_id_shard_pk", + "columns": [ + "organization_id", + "hour_start", + "meter", + "dimension", + "environment_id", + "shard" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_usage_attribution": { + "name": "billing_usage_attribution", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hour_start": { + "name": "hour_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "meter": { + "name": "meter", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dimension": { + "name": "dimension", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shard": { + "name": "shard", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "quantity": { + "name": "quantity", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "billing_usage_attribution_hour_idx": { + "name": "billing_usage_attribution_hour_idx", + "columns": [ + { + "expression": "hour_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_usage_attribution_organization_id_organization_id_fk": { + "name": "billing_usage_attribution_organization_id_organization_id_fk", + "tableFrom": "billing_usage_attribution", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "billing_usage_attribution_pk": { + "name": "billing_usage_attribution_pk", + "columns": [ + "organization_id", + "hour_start", + "meter", + "dimension", + "environment_id", + "api_key_id", + "user_id", + "shard" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.admin_audit_event": { + "name": "admin_audit_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "admin_audit_event_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "actor_user_id": { + "name": "actor_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_email": { + "name": "actor_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "admin_audit_event_target_idx": { + "name": "admin_audit_event_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "admin_audit_event_organization_idx": { + "name": "admin_audit_event_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"admin_audit_event\".\"organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "admin_audit_event_created_at_idx": { + "name": "admin_audit_event_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audience": { + "name": "audience", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "audience_environment_fk": { + "name": "audience_environment_fk", + "tableFrom": "audience", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "audience_environment_name_unique": { + "name": "audience_environment_name_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "name" + ] + }, + "audience_id_organization_unique": { + "name": "audience_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audience_member": { + "name": "audience_member", + "schema": "", + "columns": { + "audience_id": { + "name": "audience_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "contact_id": { + "name": "contact_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audience_member_contact_idx": { + "name": "audience_member_contact_idx", + "columns": [ + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audience_member_audience_fk": { + "name": "audience_member_audience_fk", + "tableFrom": "audience_member", + "tableTo": "audience", + "columnsFrom": [ + "audience_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audience_member_contact_fk": { + "name": "audience_member_contact_fk", + "tableFrom": "audience_member", + "tableTo": "contact", + "columnsFrom": [ + "contact_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "audience_member_audience_id_contact_id_pk": { + "name": "audience_member_audience_id_contact_id_pk", + "columns": [ + "audience_id", + "contact_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_email": { + "name": "auth_email", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "auth_email_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "to": { + "name": "to", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "auth_email_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_email_next_attempt_idx": { + "name": "auth_email_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"auth_email\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.broadcast": { + "name": "broadcast", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_owner_id": { + "name": "api_key_owner_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "broadcast_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "audience_id": { + "name": "audience_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "segment_id": { + "name": "segment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "topic": { + "name": "topic", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "from": { + "name": "from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reply_to": { + "name": "reply_to", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "preview_text": { + "name": "preview_text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "html": { + "name": "html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "track_opens": { + "name": "track_opens", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "track_clicks": { + "name": "track_clicks", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "rate_per_second": { + "name": "rate_per_second", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "canceled_at": { + "name": "canceled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "contact_upper_bound": { + "name": "contact_upper_bound", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cursor": { + "name": "cursor", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "recipients_estimated": { + "name": "recipients_estimated", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "materialized": { + "name": "materialized", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "screening_status": { + "name": "screening_status", + "type": "broadcast_screening_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "screening_held_at": { + "name": "screening_held_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_run_at": { + "name": "next_run_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "pause_reason": { + "name": "pause_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "broadcast_environment_created_at_idx": { + "name": "broadcast_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "broadcast_due_idx": { + "name": "broadcast_due_idx", + "columns": [ + { + "expression": "next_run_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"broadcast\".\"status\" in ('scheduled', 'sending')", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "broadcast_environment_fk": { + "name": "broadcast_environment_fk", + "tableFrom": "broadcast", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "broadcast_id_organization_unique": { + "name": "broadcast_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "broadcast_environment_idempotency_key_unique": { + "name": "broadcast_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": { + "broadcast_target_check": { + "name": "broadcast_target_check", + "value": "(\"broadcast\".\"audience_id\" is null) <> (\"broadcast\".\"segment_id\" is null)" + } + }, + "isRLSEnabled": false + }, + "public.broadcast_stat": { + "name": "broadcast_stat", + "schema": "", + "columns": { + "broadcast_id": { + "name": "broadcast_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "shard": { + "name": "shard", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "recipients": { + "name": "recipients", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "sent": { + "name": "sent", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "delivered": { + "name": "delivered", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "bounced": { + "name": "bounced", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "complained": { + "name": "complained", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "failed": { + "name": "failed", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "opened": { + "name": "opened", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "clicked": { + "name": "clicked", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "unsubscribed": { + "name": "unsubscribed", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "broadcast_stat_broadcast_fk": { + "name": "broadcast_stat_broadcast_fk", + "tableFrom": "broadcast_stat", + "tableTo": "broadcast", + "columnsFrom": [ + "broadcast_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "broadcast_stat_broadcast_id_shard_pk": { + "name": "broadcast_stat_broadcast_id_shard_pk", + "columns": [ + "broadcast_id", + "shard" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contact": { + "name": "contact", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "contact_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "address": { + "name": "address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "contact_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'subscribed'" + }, + "properties": { + "name": "properties", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "source": { + "name": "source", + "type": "contact_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "subscribed_at": { + "name": "subscribed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "unsubscribed_at": { + "name": "unsubscribed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "pending_since": { + "name": "pending_since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "confirmation_sent_at": { + "name": "confirmation_sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "confirmation_count": { + "name": "confirmation_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "confirmed_at": { + "name": "confirmed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "contact_environment_sequence_idx": { + "name": "contact_environment_sequence_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "contact_environment_id_idx": { + "name": "contact_environment_id_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "contact_properties_idx": { + "name": "contact_properties_idx", + "columns": [ + { + "expression": "properties", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "jsonb_path_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "contact_pending_since_idx": { + "name": "contact_pending_since_idx", + "columns": [ + { + "expression": "pending_since", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"contact\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "contact_environment_fk": { + "name": "contact_environment_fk", + "tableFrom": "contact", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "contact_environment_address_unique": { + "name": "contact_environment_address_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "address" + ] + }, + "contact_id_organization_unique": { + "name": "contact_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contact_counter": { + "name": "contact_counter", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "contact_counter_environment_fk": { + "name": "contact_counter_environment_fk", + "tableFrom": "contact_counter", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "contact_counter_count_check": { + "name": "contact_counter_count_check", + "value": "\"contact_counter\".\"count\" >= 0" + } + }, + "isRLSEnabled": false + }, + "public.contact_property": { + "name": "contact_property", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "contact_property_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "fallback": { + "name": "fallback", + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "contact_property_environment_fk": { + "name": "contact_property_environment_fk", + "tableFrom": "contact_property", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "contact_property_environment_key_unique": { + "name": "contact_property_environment_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contact_topic": { + "name": "contact_topic", + "schema": "", + "columns": { + "contact_id": { + "name": "contact_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "topic_id": { + "name": "topic_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "contact_topic_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "contact_source", + "typeSchema": "public", + "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": { + "contact_topic_topic_status_idx": { + "name": "contact_topic_topic_status_idx", + "columns": [ + { + "expression": "topic_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "contact_topic_contact_fk": { + "name": "contact_topic_contact_fk", + "tableFrom": "contact_topic", + "tableTo": "contact", + "columnsFrom": [ + "contact_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "contact_topic_topic_fk": { + "name": "contact_topic_topic_fk", + "tableFrom": "contact_topic", + "tableTo": "topic", + "columnsFrom": [ + "topic_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "contact_topic_contact_id_topic_id_pk": { + "name": "contact_topic_contact_id_topic_id_pk", + "columns": [ + "contact_id", + "topic_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.content_screening": { + "name": "content_screening", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "product": { + "name": "product", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject_id": { + "name": "subject_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "classifier": { + "name": "classifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "verdict": { + "name": "verdict", + "type": "content_screening_verdict", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "enforced": { + "name": "enforced", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "scores": { + "name": "scores", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "top_category": { + "name": "top_category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "top_score": { + "name": "top_score", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "input_tokens": { + "name": "input_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "latency_ms": { + "name": "latency_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "content_screening_organization_created_at_idx": { + "name": "content_screening_organization_created_at_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_screening_created_at_idx": { + "name": "content_screening_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_screening_subject_idx": { + "name": "content_screening_subject_idx", + "columns": [ + { + "expression": "product", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "subject_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "content_screening_environment_fk": { + "name": "content_screening_environment_fk", + "tableFrom": "content_screening", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.content_screening_counter": { + "name": "content_screening_counter", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "product": { + "name": "product", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "seen": { + "name": "seen", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "owed": { + "name": "owed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "content_screening_counter_organization_id_organization_id_fk": { + "name": "content_screening_counter_organization_id_organization_id_fk", + "tableFrom": "content_screening_counter", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "content_screening_counter_organization_id_product_group_id_pk": { + "name": "content_screening_counter_organization_id_product_group_id_pk", + "columns": [ + "organization_id", + "product", + "group_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dedicated_ip_delivery_rollup": { + "name": "dedicated_ip_delivery_rollup", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hour": { + "name": "hour", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "sending_ip": { + "name": "sending_ip", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "delivered": { + "name": "delivered", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "dedicated_ip_delivery_rollup_hour_idx": { + "name": "dedicated_ip_delivery_rollup_hour_idx", + "columns": [ + { + "expression": "hour", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dedicated_ip_delivery_rollup_organization_id_organization_id_fk": { + "name": "dedicated_ip_delivery_rollup_organization_id_organization_id_fk", + "tableFrom": "dedicated_ip_delivery_rollup", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "dedicated_ip_delivery_rollup_organization_id_hour_sending_ip_pk": { + "name": "dedicated_ip_delivery_rollup_organization_id_hour_sending_ip_pk", + "columns": [ + "organization_id", + "hour", + "sending_ip" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dedicated_ip_pool": { + "name": "dedicated_ip_pool", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "dedicated_ip_pool_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "ips": { + "name": "ips", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "dedicated_share": { + "name": "dedicated_share", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "status_message": { + "name": "status_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_checked_at": { + "name": "last_checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "provisioned_at": { + "name": "provisioned_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "ready_at": { + "name": "ready_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "release_after": { + "name": "release_after", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "release_started_at": { + "name": "release_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "tls_required_at": { + "name": "tls_required_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "marketing_configured_at": { + "name": "marketing_configured_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "dedicated_ip_pool_next_check_at_idx": { + "name": "dedicated_ip_pool_next_check_at_idx", + "columns": [ + { + "expression": "next_check_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"dedicated_ip_pool\".\"next_check_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dedicated_ip_pool_organization_id_organization_id_fk": { + "name": "dedicated_ip_pool_organization_id_organization_id_fk", + "tableFrom": "dedicated_ip_pool", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "dedicated_ip_pool_organization_unique": { + "name": "dedicated_ip_pool_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dmarc_notification": { + "name": "dmarc_notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_id": { + "name": "domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "dmarc_notification_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "policy_changed_at": { + "name": "policy_changed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "detail": { + "name": "detail", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "dmarc_notification_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "recipients": { + "name": "recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "dmarc_notification_due_idx": { + "name": "dmarc_notification_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"dmarc_notification\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_notification_created_at_idx": { + "name": "dmarc_notification_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dmarc_notification_domain_fk": { + "name": "dmarc_notification_domain_fk", + "tableFrom": "dmarc_notification", + "tableTo": "domain", + "columnsFrom": [ + "domain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "dmarc_notification_dedupe_unique": { + "name": "dmarc_notification_dedupe_unique", + "nullsNotDistinct": false, + "columns": [ + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dmarc_report": { + "name": "dmarc_report", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_id": { + "name": "domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reporter_org": { + "name": "reporter_org", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reporter_email": { + "name": "reporter_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "report_id": { + "name": "report_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_begin": { + "name": "period_begin", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "period_end": { + "name": "period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "policy_published": { + "name": "policy_published", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "message_count": { + "name": "message_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "pass_count": { + "name": "pass_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "truncated": { + "name": "truncated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "dmarc_report_domain_period_idx": { + "name": "dmarc_report_domain_period_idx", + "columns": [ + { + "expression": "domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_end", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_report_domain_id_idx": { + "name": "dmarc_report_domain_id_idx", + "columns": [ + { + "expression": "domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_report_created_at_idx": { + "name": "dmarc_report_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_report_organization_idx": { + "name": "dmarc_report_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dmarc_report_domain_fk": { + "name": "dmarc_report_domain_fk", + "tableFrom": "dmarc_report", + "tableTo": "domain", + "columnsFrom": [ + "domain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "dmarc_report_reporter_unique": { + "name": "dmarc_report_reporter_unique", + "nullsNotDistinct": false, + "columns": [ + "domain_id", + "reporter_org", + "report_id" + ] + }, + "dmarc_report_id_organization_unique": { + "name": "dmarc_report_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dmarc_report_record": { + "name": "dmarc_report_record", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_id": { + "name": "domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dmarc_report_id": { + "name": "dmarc_report_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_begin": { + "name": "period_begin", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "period_end": { + "name": "period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "source_ip": { + "name": "source_ip", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "disposition": { + "name": "disposition", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dkim": { + "name": "dkim", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "spf": { + "name": "spf", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dmarc_pass": { + "name": "dmarc_pass", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "header_from": { + "name": "header_from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "envelope_from": { + "name": "envelope_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auth_results": { + "name": "auth_results", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "reasons": { + "name": "reasons", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "via_coss": { + "name": "via_coss", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "dmarc_report_record_report_idx": { + "name": "dmarc_report_record_report_idx", + "columns": [ + { + "expression": "dmarc_report_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "position", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_report_record_domain_period_idx": { + "name": "dmarc_report_record_domain_period_idx", + "columns": [ + { + "expression": "domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_end", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_report_record_organization_idx": { + "name": "dmarc_report_record_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dmarc_report_record_report_fk": { + "name": "dmarc_report_record_report_fk", + "tableFrom": "dmarc_report_record", + "tableTo": "dmarc_report", + "columnsFrom": [ + "dmarc_report_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.domain": { + "name": "domain", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "domain_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "can_send": { + "name": "can_send", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "region": { + "name": "region", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dkim_tokens": { + "name": "dkim_tokens", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "dkim_hosted_zone": { + "name": "dkim_hosted_zone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mail_from_domain": { + "name": "mail_from_domain", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mail_from_status": { + "name": "mail_from_status", + "type": "mail_from_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "records": { + "name": "records", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "bimi": { + "name": "bimi", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "verification_started_at": { + "name": "verification_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_checked_at": { + "name": "last_checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "verified_at": { + "name": "verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "failed_at": { + "name": "failed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "dmarc_report_token": { + "name": "dmarc_report_token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dmarc_record": { + "name": "dmarc_record", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dmarc_inherited_record": { + "name": "dmarc_inherited_record", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dmarc_policy_changed_at": { + "name": "dmarc_policy_changed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subaccount_id": { + "name": "subaccount_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "shared_with_subaccounts": { + "name": "shared_with_subaccounts", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "domain_subaccount_idx": { + "name": "domain_subaccount_idx", + "columns": [ + { + "expression": "subaccount_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"domain\".\"subaccount_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "domain_name_active_unique": { + "name": "domain_name_active_unique", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"domain\".\"status\" <> 'failed'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "domain_organization_idx": { + "name": "domain_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "domain_next_check_at_idx": { + "name": "domain_next_check_at_idx", + "columns": [ + { + "expression": "next_check_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"domain\".\"next_check_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "domain_organization_id_organization_id_fk": { + "name": "domain_organization_id_organization_id_fk", + "tableFrom": "domain", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "domain_created_by_user_id_user_id_fk": { + "name": "domain_created_by_user_id_user_id_fk", + "tableFrom": "domain", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "domain_subaccount_fk": { + "name": "domain_subaccount_fk", + "tableFrom": "domain", + "tableTo": "email_subaccount", + "columnsFrom": [ + "subaccount_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "domain_dmarc_report_token_unique": { + "name": "domain_dmarc_report_token_unique", + "nullsNotDistinct": false, + "columns": [ + "dmarc_report_token" + ] + }, + "domain_id_organization_unique": { + "name": "domain_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "domain_shared_not_subaccount": { + "name": "domain_shared_not_subaccount", + "value": "not (\"domain\".\"shared_with_subaccounts\" and \"domain\".\"subaccount_id\" is not null)" + } + }, + "isRLSEnabled": false + }, + "public.email": { + "name": "email", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_owner_id": { + "name": "api_key_owner_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "email_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "from": { + "name": "from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to": { + "name": "to", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "cc": { + "name": "cc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "bcc": { + "name": "bcc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "reply_to": { + "name": "reply_to", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "html": { + "name": "html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "discard_body": { + "name": "discard_body", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "screening_exempt": { + "name": "screening_exempt", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "store_content": { + "name": "store_content", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "content_discarded_at": { + "name": "content_discarded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "headers": { + "name": "headers", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stream": { + "name": "stream", + "type": "email_stream", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'transactional'" + }, + "track_opens": { + "name": "track_opens", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "track_clicks": { + "name": "track_clicks", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "unsubscribe": { + "name": "unsubscribe", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "tracking_token": { + "name": "tracking_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "open_count": { + "name": "open_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "first_opened_at": { + "name": "first_opened_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_opened_at": { + "name": "last_opened_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "click_count": { + "name": "click_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "first_clicked_at": { + "name": "first_clicked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_clicked_at": { + "name": "last_clicked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "batch_id": { + "name": "batch_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "batch_index": { + "name": "batch_index", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "broadcast_id": { + "name": "broadcast_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contact_id": { + "name": "contact_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "variables": { + "name": "variables", + "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()" + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "billable_recipients": { + "name": "billable_recipients", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "template_version": { + "name": "template_version", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "template_locale": { + "name": "template_locale", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dedicated_pool": { + "name": "dedicated_pool", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "require_tls": { + "name": "require_tls", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hipaa_origin": { + "name": "hipaa_origin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "subaccount_id": { + "name": "subaccount_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subaccount_tenant": { + "name": "subaccount_tenant", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "traceparent": { + "name": "traceparent", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "email_batch_idx": { + "name": "email_batch_idx", + "columns": [ + { + "expression": "batch_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "batch_index", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email\".\"batch_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_broadcast_contact_unique": { + "name": "email_broadcast_contact_unique", + "columns": [ + { + "expression": "broadcast_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"email\".\"broadcast_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_broadcast_status_idx": { + "name": "email_broadcast_status_idx", + "columns": [ + { + "expression": "broadcast_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email\".\"broadcast_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_environment_created_at_idx": { + "name": "email_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_organization_created_at_idx": { + "name": "email_organization_created_at_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_organization_send_time_idx": { + "name": "email_organization_send_time_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"sent_at\", \"created_at\")", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_subaccount_send_time_idx": { + "name": "email_subaccount_send_time_idx", + "columns": [ + { + "expression": "subaccount_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"sent_at\", \"created_at\")", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email\".\"subaccount_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_scheduled_due_idx": { + "name": "email_scheduled_due_idx", + "columns": [ + { + "expression": "scheduled_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email\".\"status\" = 'scheduled'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_queued_created_at_idx": { + "name": "email_queued_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email\".\"status\" = 'queued'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_created_at_idx": { + "name": "email_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_environment_fk": { + "name": "email_environment_fk", + "tableFrom": "email", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "email_batch_fk": { + "name": "email_batch_fk", + "tableFrom": "email", + "tableTo": "email_batch", + "columnsFrom": [ + "batch_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_tracking_token_unique": { + "name": "email_tracking_token_unique", + "nullsNotDistinct": false, + "columns": [ + "tracking_token" + ] + }, + "email_environment_idempotency_key_unique": { + "name": "email_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + }, + "email_id_organization_unique": { + "name": "email_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_attachment": { + "name": "email_attachment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_id": { + "name": "content_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_attachment_email_fk": { + "name": "email_attachment_email_fk", + "tableFrom": "email_attachment", + "tableTo": "email", + "columnsFrom": [ + "email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_attachment_email_position_unique": { + "name": "email_attachment_email_position_unique", + "nullsNotDistinct": false, + "columns": [ + "email_id", + "position" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_batch": { + "name": "email_batch", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_batch_environment_fk": { + "name": "email_batch_environment_fk", + "tableFrom": "email_batch", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_batch_environment_idempotency_key_unique": { + "name": "email_batch_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + }, + "email_batch_id_organization_unique": { + "name": "email_batch_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_event": { + "name": "email_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "email_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_event_type": { + "name": "provider_event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "recipient": { + "name": "recipient", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "email_event_email_occurred_at_idx": { + "name": "email_event_email_occurred_at_idx", + "columns": [ + { + "expression": "email_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_event_email_fk": { + "name": "email_event_email_fk", + "tableFrom": "email_event", + "tableTo": "email", + "columnsFrom": [ + "email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_event_email_dedupe_unique": { + "name": "email_event_email_dedupe_unique", + "nullsNotDistinct": false, + "columns": [ + "email_id", + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_link": { + "name": "email_link", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "click_count": { + "name": "click_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "first_clicked_at": { + "name": "first_clicked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_clicked_at": { + "name": "last_clicked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_link_email_fk": { + "name": "email_link_email_fk", + "tableFrom": "email_link", + "tableTo": "email", + "columnsFrom": [ + "email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_link_email_position_unique": { + "name": "email_link_email_position_unique", + "nullsNotDistinct": false, + "columns": [ + "email_id", + "position" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_recipient": { + "name": "email_recipient", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "address": { + "name": "address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "email_recipient_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "email_recipient_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "last_event_at": { + "name": "last_event_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "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": { + "email_recipient_organization_address_idx": { + "name": "email_recipient_organization_address_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "address", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_recipient_email_fk": { + "name": "email_recipient_email_fk", + "tableFrom": "email_recipient", + "tableTo": "email", + "columnsFrom": [ + "email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_recipient_email_address_unique": { + "name": "email_recipient_email_address_unique", + "nullsNotDistinct": false, + "columns": [ + "email_id", + "address" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_reputation_rollup": { + "name": "email_reputation_rollup", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bucket_start": { + "name": "bucket_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "stream": { + "name": "stream", + "type": "email_stream", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'transactional'" + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "computed_revision": { + "name": "computed_revision", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "recipients": { + "name": "recipients", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "bounces": { + "name": "bounces", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "complaints": { + "name": "complaints", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "simulator_recipients": { + "name": "simulator_recipients", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "simulator_bounces": { + "name": "simulator_bounces", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "simulator_complaints": { + "name": "simulator_complaints", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_reputation_rollup_organization_id_organization_id_fk": { + "name": "email_reputation_rollup_organization_id_organization_id_fk", + "tableFrom": "email_reputation_rollup", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "email_reputation_rollup_organization_id_bucket_start_stream_pk": { + "name": "email_reputation_rollup_organization_id_bucket_start_stream_pk", + "columns": [ + "organization_id", + "bucket_start", + "stream" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_sender_domain_block": { + "name": "email_sender_domain_block", + "schema": "", + "columns": { + "domain": { + "name": "domain", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subject_id": { + "name": "subject_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "email_sender_domain_block_organization_idx": { + "name": "email_sender_domain_block_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_storage_settings": { + "name": "email_storage_settings", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "store_content": { + "name": "store_content", + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_storage_settings_environment_fk": { + "name": "email_storage_settings_environment_fk", + "tableFrom": "email_storage_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_subaccount": { + "name": "email_subaccount", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "uid": { + "name": "uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "email_subaccount_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "daily_recipient_limit": { + "name": "daily_recipient_limit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "per_second_recipient_limit": { + "name": "per_second_recipient_limit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "per_second_burst": { + "name": "per_second_burst", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reputation_status": { + "name": "reputation_status", + "type": "email_subaccount_reputation", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'good'" + }, + "reputation_trigger": { + "name": "reputation_trigger", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reputation_changed_at": { + "name": "reputation_changed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "reinstated_at": { + "name": "reinstated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "metrics": { + "name": "metrics", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_evaluation_at": { + "name": "next_evaluation_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "evaluation_lease_until": { + "name": "evaluation_lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "deletion_lease_until": { + "name": "deletion_lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "deletion_attempts": { + "name": "deletion_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "email_subaccount_environment_created_at_idx": { + "name": "email_subaccount_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_subaccount_next_evaluation_idx": { + "name": "email_subaccount_next_evaluation_idx", + "columns": [ + { + "expression": "next_evaluation_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email_subaccount\".\"next_evaluation_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_subaccount_deleting_idx": { + "name": "email_subaccount_deleting_idx", + "columns": [ + { + "expression": "deletion_lease_until", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email_subaccount\".\"status\" = 'deleting'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_subaccount_environment_fk": { + "name": "email_subaccount_environment_fk", + "tableFrom": "email_subaccount", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_subaccount_environment_uid_unique": { + "name": "email_subaccount_environment_uid_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "uid" + ] + }, + "email_subaccount_id_organization_unique": { + "name": "email_subaccount_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_suppression": { + "name": "email_suppression", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "email_suppression_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "address": { + "name": "address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "email_suppression_reason", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subaccount_id": { + "name": "subaccount_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "email_suppression_subaccount_sequence_idx": { + "name": "email_suppression_subaccount_sequence_idx", + "columns": [ + { + "expression": "subaccount_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email_suppression\".\"subaccount_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_suppression_environment_sequence_idx": { + "name": "email_suppression_environment_sequence_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_suppression_environment_fk": { + "name": "email_suppression_environment_fk", + "tableFrom": "email_suppression", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "email_suppression_subaccount_fk": { + "name": "email_suppression_subaccount_fk", + "tableFrom": "email_suppression", + "tableTo": "email_subaccount", + "columnsFrom": [ + "subaccount_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_suppression_environment_subaccount_address_scope_unique": { + "name": "email_suppression_environment_subaccount_address_scope_unique", + "nullsNotDistinct": true, + "columns": [ + "environment_id", + "subaccount_id", + "address", + "scope" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_template": { + "name": "email_template", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "alias": { + "name": "alias", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "published_version": { + "name": "published_version", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_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()" + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "email_template_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + } + }, + "indexes": { + "email_template_environment_created_at_idx": { + "name": "email_template_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_template_environment_fk": { + "name": "email_template_environment_fk", + "tableFrom": "email_template", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_template_environment_alias_unique": { + "name": "email_template_environment_alias_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "alias" + ] + }, + "email_template_id_organization_unique": { + "name": "email_template_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_template_content": { + "name": "email_template_content", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "version_id": { + "name": "version_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "locale": { + "name": "locale", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "html": { + "name": "html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_template_content_version_fk": { + "name": "email_template_content_version_fk", + "tableFrom": "email_template_content", + "tableTo": "email_template_version", + "columnsFrom": [ + "version_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_template_content_version_locale_unique": { + "name": "email_template_content_version_locale_unique", + "nullsNotDistinct": false, + "columns": [ + "version_id", + "locale" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_template_version": { + "name": "email_template_version", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "default_locale": { + "name": "default_locale", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "variables": { + "name": "variables", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "sample_variables": { + "name": "sample_variables", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "has_unpublished_changes": { + "name": "has_unpublished_changes", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "email_template_version_draft_unique": { + "name": "email_template_version_draft_unique", + "columns": [ + { + "expression": "template_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"email_template_version\".\"version\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_template_version_template_fk": { + "name": "email_template_version_template_fk", + "tableFrom": "email_template_version", + "tableTo": "email_template", + "columnsFrom": [ + "template_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_template_version_template_version_unique": { + "name": "email_template_version_template_version_unique", + "nullsNotDistinct": false, + "columns": [ + "template_id", + "version" + ] + }, + "email_template_version_id_organization_unique": { + "name": "email_template_version_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_tenant": { + "name": "email_tenant", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subaccount_id": { + "name": "subaccount_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stream": { + "name": "stream", + "type": "email_stream", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'transactional'" + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tenant_name": { + "name": "tenant_name", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "tenant_arn": { + "name": "tenant_arn", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sending_status": { + "name": "sending_status", + "type": "tenant_sending_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'enabled'" + }, + "suppression_migrated_at": { + "name": "suppression_migrated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "status_cause": { + "name": "status_cause", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_updated_at": { + "name": "status_updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_tenant_organization_id_organization_id_fk": { + "name": "email_tenant_organization_id_organization_id_fk", + "tableFrom": "email_tenant", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "email_tenant_subaccount_fk": { + "name": "email_tenant_subaccount_fk", + "tableFrom": "email_tenant", + "tableTo": "email_subaccount", + "columnsFrom": [ + "subaccount_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_tenant_owner_stream_unique": { + "name": "email_tenant_owner_stream_unique", + "nullsNotDistinct": true, + "columns": [ + "organization_id", + "subaccount_id", + "stream" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_tracking_rule": { + "name": "email_tracking_rule", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "opens": { + "name": "opens", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "clicks": { + "name": "clicks", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "unsubscribe": { + "name": "unsubscribe", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_tracking_rule_environment_fk": { + "name": "email_tracking_rule_environment_fk", + "tableFrom": "email_tracking_rule", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_tracking_rule_environment_category_unique": { + "name": "email_tracking_rule_environment_category_unique", + "nullsNotDistinct": true, + "columns": [ + "environment_id", + "category" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.environment": { + "name": "environment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mode": { + "name": "mode", + "type": "environment_mode", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "personal_keys": { + "name": "personal_keys", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "environment_organization_idx": { + "name": "environment_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "environment_project_fk": { + "name": "environment_project_fk", + "tableFrom": "environment", + "tableTo": "project", + "columnsFrom": [ + "project_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "environment_project_slug_unique": { + "name": "environment_project_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "project_id", + "slug" + ] + }, + "environment_id_organization_unique": { + "name": "environment_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.environment_api_key": { + "name": "environment_api_key", + "schema": "", + "columns": { + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access": { + "name": "access", + "type": "api_key_access", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'full'" + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "environment_api_key_environment_idx": { + "name": "environment_api_key_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "environment_api_key_owner_idx": { + "name": "environment_api_key_owner_idx", + "columns": [ + { + "expression": "owner_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "environment_api_key_api_key_id_apikey_id_fk": { + "name": "environment_api_key_api_key_id_apikey_id_fk", + "tableFrom": "environment_api_key", + "tableTo": "apikey", + "columnsFrom": [ + "api_key_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_api_key_environment_id_environment_id_fk": { + "name": "environment_api_key_environment_id_environment_id_fk", + "tableFrom": "environment_api_key", + "tableTo": "environment", + "columnsFrom": [ + "environment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_api_key_created_by_user_id_user_id_fk": { + "name": "environment_api_key_created_by_user_id_user_id_fk", + "tableFrom": "environment_api_key", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "environment_api_key_owner_user_id_user_id_fk": { + "name": "environment_api_key_owner_user_id_user_id_fk", + "tableFrom": "environment_api_key", + "tableTo": "user", + "columnsFrom": [ + "owner_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.environment_inbound_address": { + "name": "environment_inbound_address", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "environment_inbound_address_environment_fk": { + "name": "environment_inbound_address_environment_fk", + "tableFrom": "environment_inbound_address", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "environment_inbound_address_label_unique": { + "name": "environment_inbound_address_label_unique", + "nullsNotDistinct": false, + "columns": [ + "label" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hipaa_session_activity": { + "name": "hipaa_session_activity", + "schema": "", + "columns": { + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "last_active_at": { + "name": "last_active_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "hipaa_session_activity_session_id_session_id_fk": { + "name": "hipaa_session_activity_session_id_session_id_fk", + "tableFrom": "hipaa_session_activity", + "tableTo": "session", + "columnsFrom": [ + "session_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_application": { + "name": "hook_application", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "uid": { + "name": "uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "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": { + "hook_application_environment_created_at_idx": { + "name": "hook_application_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_application_environment_fk": { + "name": "hook_application_environment_fk", + "tableFrom": "hook_application", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_application_environment_uid_unique": { + "name": "hook_application_environment_uid_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "uid" + ] + }, + "hook_application_id_organization_unique": { + "name": "hook_application_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_attempt": { + "name": "hook_attempt", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_created_at": { + "name": "message_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "delivery_id": { + "name": "delivery_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "endpoint_id": { + "name": "endpoint_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempted_at": { + "name": "attempted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "response_excerpt": { + "name": "response_excerpt", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "hook_attempt_delivery_idx": { + "name": "hook_attempt_delivery_idx", + "columns": [ + { + "expression": "delivery_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "attempted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_attempt_environment_idx": { + "name": "hook_attempt_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "message_created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "hook_attempt_pkey": { + "name": "hook_attempt_pkey", + "columns": [ + "message_created_at", + "id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_delivery": { + "name": "hook_delivery", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_created_at": { + "name": "message_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "endpoint_id": { + "name": "endpoint_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "hook_delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "lease_expires_at": { + "name": "lease_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_status_code": { + "name": "last_status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "hook_delivery_due_idx": { + "name": "hook_delivery_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"hook_delivery\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_delivery_endpoint_idx": { + "name": "hook_delivery_endpoint_idx", + "columns": [ + { + "expression": "endpoint_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "message_created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_delivery_environment_idx": { + "name": "hook_delivery_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "message_created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "hook_delivery_pkey": { + "name": "hook_delivery_pkey", + "columns": [ + "message_created_at", + "id" + ] + } + }, + "uniqueConstraints": { + "hook_delivery_message_endpoint_unique": { + "name": "hook_delivery_message_endpoint_unique", + "nullsNotDistinct": false, + "columns": [ + "message_created_at", + "message_id", + "endpoint_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_delivery_rollup": { + "name": "hook_delivery_rollup", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hour": { + "name": "hour", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "succeeded": { + "name": "succeeded", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "failed": { + "name": "failed", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "hook_delivery_rollup_hour_idx": { + "name": "hook_delivery_rollup_hour_idx", + "columns": [ + { + "expression": "hour", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_delivery_rollup_organization_id_organization_id_fk": { + "name": "hook_delivery_rollup_organization_id_organization_id_fk", + "tableFrom": "hook_delivery_rollup", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "hook_delivery_rollup_pkey": { + "name": "hook_delivery_rollup_pkey", + "columns": [ + "organization_id", + "hour" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_endpoint": { + "name": "hook_endpoint", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filter_types": { + "name": "filter_types", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "secret_ciphertext": { + "name": "secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "previous_secret_ciphertext": { + "name": "previous_secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previous_secret_expires_at": { + "name": "previous_secret_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "rate_limit_per_second": { + "name": "rate_limit_per_second", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "disabled_reason": { + "name": "disabled_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "failing_since": { + "name": "failing_since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "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": { + "hook_endpoint_application_idx": { + "name": "hook_endpoint_application_idx", + "columns": [ + { + "expression": "application_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_endpoint_application_fk": { + "name": "hook_endpoint_application_fk", + "tableFrom": "hook_endpoint", + "tableTo": "hook_application", + "columnsFrom": [ + "application_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_endpoint_id_organization_unique": { + "name": "hook_endpoint_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "hook_endpoint_previous_secret_check": { + "name": "hook_endpoint_previous_secret_check", + "value": "(\"hook_endpoint\".\"previous_secret_ciphertext\" is null) = (\"hook_endpoint\".\"previous_secret_expires_at\" is null)" + }, + "hook_endpoint_disabled_check": { + "name": "hook_endpoint_disabled_check", + "value": "\"hook_endpoint\".\"enabled\" = (\"hook_endpoint\".\"disabled_reason\" is null) and (\"hook_endpoint\".\"disabled_reason\" is null) = (\"hook_endpoint\".\"disabled_at\" is null)" + }, + "hook_endpoint_rate_limit_check": { + "name": "hook_endpoint_rate_limit_check", + "value": "\"hook_endpoint\".\"rate_limit_per_second\" is null or \"hook_endpoint\".\"rate_limit_per_second\" > 0" + } + }, + "isRLSEnabled": false + }, + "public.hook_endpoint_recovery": { + "name": "hook_endpoint_recovery", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "endpoint_id": { + "name": "endpoint_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "since": { + "name": "since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "until": { + "name": "until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "hook_recovery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "cursor_created_at": { + "name": "cursor_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cursor_id": { + "name": "cursor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requeued": { + "name": "requeued", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "lease_expires_at": { + "name": "lease_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "hook_endpoint_recovery_pending_idx": { + "name": "hook_endpoint_recovery_pending_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"hook_endpoint_recovery\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_endpoint_recovery_endpoint_idx": { + "name": "hook_endpoint_recovery_endpoint_idx", + "columns": [ + { + "expression": "endpoint_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_endpoint_recovery_endpoint_fk": { + "name": "hook_endpoint_recovery_endpoint_fk", + "tableFrom": "hook_endpoint_recovery", + "tableTo": "hook_endpoint", + "columnsFrom": [ + "endpoint_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_event_type": { + "name": "hook_event_type", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "schema": { + "name": "schema", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "examples": { + "name": "examples", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "hook_event_type_environment_fk": { + "name": "hook_event_type_environment_fk", + "tableFrom": "hook_event_type", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_event_type_environment_name_unique": { + "name": "hook_event_type_environment_name_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_idempotency_key": { + "name": "hook_idempotency_key", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_created_at": { + "name": "message_created_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": { + "hook_idempotency_key_created_at_idx": { + "name": "hook_idempotency_key_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_idempotency_key_environment_fk": { + "name": "hook_idempotency_key_environment_fk", + "tableFrom": "hook_idempotency_key", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_idempotency_key_environment_key_unique": { + "name": "hook_idempotency_key_environment_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_message": { + "name": "hook_message", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "payload_bytes": { + "name": "payload_bytes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "only_endpoint_id": { + "name": "only_endpoint_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "hook_message_application_created_at_idx": { + "name": "hook_message_application_created_at_idx", + "columns": [ + { + "expression": "application_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_message_environment_created_at_idx": { + "name": "hook_message_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "hook_message_pkey": { + "name": "hook_message_pkey", + "columns": [ + "created_at", + "id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_portal_session": { + "name": "hook_portal_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "read_only": { + "name": "read_only", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "hook_portal_session_expires_at_idx": { + "name": "hook_portal_session_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_portal_session_organization_idx": { + "name": "hook_portal_session_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_portal_session_created_by_user_id_user_id_fk": { + "name": "hook_portal_session_created_by_user_id_user_id_fk", + "tableFrom": "hook_portal_session", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "hook_portal_session_application_fk": { + "name": "hook_portal_session_application_fk", + "tableFrom": "hook_portal_session", + "tableTo": "hook_application", + "columnsFrom": [ + "application_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_portal_session_token_hash_unique": { + "name": "hook_portal_session_token_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "token_hash" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_portal_settings": { + "name": "hook_portal_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "allowed_origins": { + "name": "allowed_origins", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "accent_color": { + "name": "accent_color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "theme": { + "name": "theme", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'system'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "hook_portal_settings_environment_fk": { + "name": "hook_portal_settings_environment_fk", + "tableFrom": "hook_portal_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_portal_settings_environment_unique": { + "name": "hook_portal_settings_environment_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.inbound_drop_counter": { + "name": "inbound_drop_counter", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "day": { + "name": "day", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "inbound_drop_counter_organization_id_organization_id_fk": { + "name": "inbound_drop_counter_organization_id_organization_id_fk", + "tableFrom": "inbound_drop_counter", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "inbound_drop_counter_pk": { + "name": "inbound_drop_counter_pk", + "columns": [ + "organization_id", + "day" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.inbound_fake_object": { + "name": "inbound_fake_object", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "inbound_fake_object_organization_idx": { + "name": "inbound_fake_object_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbound_fake_object_created_at_idx": { + "name": "inbound_fake_object_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.log_drain": { + "name": "log_drain", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sources": { + "name": "sources", + "type": "log_drain_source[]", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'{}'::log_drain_source[]" + }, + "secret_ciphertext": { + "name": "secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "format": { + "name": "format", + "type": "log_drain_format", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'ndjson'" + }, + "auth_header_name": { + "name": "auth_header_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auth_header_ciphertext": { + "name": "auth_header_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "disabled_reason": { + "name": "disabled_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "log_drain_environment_idx": { + "name": "log_drain_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_drain\".\"enabled\"", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "log_drain_created_by_user_id_user_id_fk": { + "name": "log_drain_created_by_user_id_user_id_fk", + "tableFrom": "log_drain", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "log_drain_environment_fk": { + "name": "log_drain_environment_fk", + "tableFrom": "log_drain", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "log_drain_id_organization_unique": { + "name": "log_drain_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "log_drain_auth_header_check": { + "name": "log_drain_auth_header_check", + "value": "(\"log_drain\".\"auth_header_name\" is null) = (\"log_drain\".\"auth_header_ciphertext\" is null)" + } + }, + "isRLSEnabled": false + }, + "public.log_drain_attempt": { + "name": "log_drain_attempt", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "batch_id": { + "name": "batch_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempted_at": { + "name": "attempted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "response_excerpt": { + "name": "response_excerpt", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "log_drain_attempt_batch_idx": { + "name": "log_drain_attempt_batch_idx", + "columns": [ + { + "expression": "batch_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "attempted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "log_drain_attempt_batch_fk": { + "name": "log_drain_attempt_batch_fk", + "tableFrom": "log_drain_attempt", + "tableTo": "log_drain_batch", + "columnsFrom": [ + "batch_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.log_drain_batch": { + "name": "log_drain_batch", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "drain_id": { + "name": "drain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "log_drain_batch_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "record_count": { + "name": "record_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "lease_expires_at": { + "name": "lease_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_status_code": { + "name": "last_status_code", + "type": "integer", + "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()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "log_drain_batch_pending_unique": { + "name": "log_drain_batch_pending_unique", + "columns": [ + { + "expression": "drain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"log_drain_batch\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_drain_batch_due_idx": { + "name": "log_drain_batch_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_drain_batch\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_drain_batch_drain_created_at_idx": { + "name": "log_drain_batch_drain_created_at_idx", + "columns": [ + { + "expression": "drain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_drain_batch_updated_at_idx": { + "name": "log_drain_batch_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_drain_batch\".\"status\" <> 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "log_drain_batch_drain_fk": { + "name": "log_drain_batch_drain_fk", + "tableFrom": "log_drain_batch", + "tableTo": "log_drain", + "columnsFrom": [ + "drain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "log_drain_batch_id_organization_unique": { + "name": "log_drain_batch_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.log_drain_record": { + "name": "log_drain_record", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "drain_id": { + "name": "drain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "batch_id": { + "name": "batch_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "log_drain_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "source_id": { + "name": "source_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "line": { + "name": "line", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "log_drain_record_queued_idx": { + "name": "log_drain_record_queued_idx", + "columns": [ + { + "expression": "drain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_drain_record\".\"batch_id\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_drain_record_batch_idx": { + "name": "log_drain_record_batch_idx", + "columns": [ + { + "expression": "batch_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "log_drain_record_drain_fk": { + "name": "log_drain_record_drain_fk", + "tableFrom": "log_drain_record", + "tableTo": "log_drain", + "columnsFrom": [ + "drain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "log_drain_record_batch_fk": { + "name": "log_drain_record_batch_fk", + "tableFrom": "log_drain_record", + "tableTo": "log_drain_batch", + "columnsFrom": [ + "batch_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "log_drain_record_drain_source_unique": { + "name": "log_drain_record_drain_source_unique", + "nullsNotDistinct": false, + "columns": [ + "drain_id", + "source_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.log_entry": { + "name": "log_entry", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "log_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "level": { + "name": "level", + "type": "log_level", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "route": { + "name": "route", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "client_ip": { + "name": "client_ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "resource_type": { + "name": "resource_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "resource_id": { + "name": "resource_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "recipient": { + "name": "recipient", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attributes": { + "name": "attributes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "search_text": { + "name": "search_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + } + }, + "indexes": { + "log_entry_environment_occurred_at_idx": { + "name": "log_entry_environment_occurred_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_entry_environment_request_idx": { + "name": "log_entry_environment_request_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_entry\".\"request_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_entry_environment_resource_idx": { + "name": "log_entry_environment_resource_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "resource_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_entry\".\"resource_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_entry_search_text_idx": { + "name": "log_entry_search_text_idx", + "columns": [ + { + "expression": "search_text", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "gin_trgm_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + } + }, + "foreignKeys": { + "log_entry_environment_fk": { + "name": "log_entry_environment_fk", + "tableFrom": "log_entry", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "log_entry_pkey": { + "name": "log_entry_pkey", + "columns": [ + "occurred_at", + "id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.marketing_settings": { + "name": "marketing_settings", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mailing_address": { + "name": "mailing_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_from": { + "name": "confirmation_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_subject": { + "name": "confirmation_subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_html": { + "name": "confirmation_html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_text": { + "name": "confirmation_text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmed_redirect_url": { + "name": "confirmed_redirect_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "double_opt_in_default": { + "name": "double_opt_in_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "marketing_settings_environment_fk": { + "name": "marketing_settings_environment_fk", + "tableFrom": "marketing_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.migration": { + "name": "migration", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "migration_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "migration_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'inspecting'" + }, + "credentials_ciphertext": { + "name": "credentials_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "credential_hint": { + "name": "credential_hint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "inventory": { + "name": "inventory", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "selection": { + "name": "selection", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "phase": { + "name": "phase", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cursor": { + "name": "cursor", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "progress": { + "name": "progress", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_run_at": { + "name": "next_run_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "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 + }, + "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": { + "migration_environment_created_at_idx": { + "name": "migration_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "migration_due_idx": { + "name": "migration_due_idx", + "columns": [ + { + "expression": "next_run_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"migration\".\"status\" in ('inspecting', 'queued', 'running')", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "migration_created_by_user_id_user_id_fk": { + "name": "migration_created_by_user_id_user_id_fk", + "tableFrom": "migration", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "migration_environment_fk": { + "name": "migration_environment_fk", + "tableFrom": "migration", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "migration_id_organization_unique": { + "name": "migration_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.migration_item": { + "name": "migration_item", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "migration_id": { + "name": "migration_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "migration_item_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "source_id": { + "name": "source_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_name": { + "name": "source_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target_name": { + "name": "target_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "outcome": { + "name": "outcome", + "type": "migration_item_outcome", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "needs_review": { + "name": "needs_review", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "warnings": { + "name": "warnings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "migration_item_migration_fk": { + "name": "migration_item_migration_fk", + "tableFrom": "migration_item", + "tableTo": "migration", + "columnsFrom": [ + "migration_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "migration_item_source_unique": { + "name": "migration_item_source_unique", + "nullsNotDistinct": false, + "columns": [ + "migration_id", + "kind", + "source_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.org_audit_event": { + "name": "org_audit_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "org_audit_event_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_type": { + "name": "actor_type", + "type": "org_audit_actor_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_label": { + "name": "actor_label", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target_id": { + "name": "target_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target_label": { + "name": "target_label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "client_ip": { + "name": "client_ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "org_audit_event_organization_idx": { + "name": "org_audit_event_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "org_audit_event_organization_action_idx": { + "name": "org_audit_event_organization_action_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "org_audit_event_organization_id_organization_id_fk": { + "name": "org_audit_event_organization_id_organization_id_fk", + "tableFrom": "org_audit_event", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_api_version": { + "name": "organization_api_version", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "api_version": { + "name": "api_version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "updated_by_user_id": { + "name": "updated_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "organization_api_version_organization_id_organization_id_fk": { + "name": "organization_api_version_organization_id_organization_id_fk", + "tableFrom": "organization_api_version", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "organization_api_version_updated_by_user_id_user_id_fk": { + "name": "organization_api_version_updated_by_user_id_user_id_fk", + "tableFrom": "organization_api_version", + "tableTo": "user", + "columnsFrom": [ + "updated_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_deletion": { + "name": "organization_deletion", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_name": { + "name": "organization_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_slug": { + "name": "organization_slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "requested_by_user_id": { + "name": "requested_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requested_by_email": { + "name": "requested_by_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "by_platform_admin": { + "name": "by_platform_admin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "status": { + "name": "status", + "type": "organization_deletion_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "organization_deletion_next_attempt_idx": { + "name": "organization_deletion_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"organization_deletion\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "organization_deletion_org_unique": { + "name": "organization_deletion_org_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_hipaa_mode": { + "name": "organization_hipaa_mode", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "baa_signed_at": { + "name": "baa_signed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "baa_reference": { + "name": "baa_reference", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled_by_user_id": { + "name": "enabled_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "organization_hipaa_mode_organization_id_organization_id_fk": { + "name": "organization_hipaa_mode_organization_id_organization_id_fk", + "tableFrom": "organization_hipaa_mode", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "organization_hipaa_mode_enabled_by_user_id_user_id_fk": { + "name": "organization_hipaa_mode_enabled_by_user_id_user_id_fk", + "tableFrom": "organization_hipaa_mode", + "tableTo": "user", + "columnsFrom": [ + "enabled_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_logo": { + "name": "organization_logo", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "status": { + "name": "status", + "type": "organization_logo_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_url": { + "name": "source_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "image": { + "name": "image", + "type": "bytea", + "primaryKey": false, + "notNull": false + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "failures": { + "name": "failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "checked_at": { + "name": "checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "organization_logo_organization_id_organization_id_fk": { + "name": "organization_logo_organization_id_organization_id_fk", + "tableFrom": "organization_logo", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_suspension": { + "name": "organization_suspension", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "suspended_by_user_id": { + "name": "suspended_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "organization_suspension_organization_id_organization_id_fk": { + "name": "organization_suspension_organization_id_organization_id_fk", + "tableFrom": "organization_suspension", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "organization_suspension_suspended_by_user_id_user_id_fk": { + "name": "organization_suspension_suspended_by_user_id_user_id_fk", + "tableFrom": "organization_suspension", + "tableTo": "user", + "columnsFrom": [ + "suspended_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.product_preference": { + "name": "product_preference", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "product": { + "name": "product", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pinned": { + "name": "pinned", + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "product_preference_organization_id_organization_id_fk": { + "name": "product_preference_organization_id_organization_id_fk", + "tableFrom": "product_preference", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "product_preference_user_id_user_id_fk": { + "name": "product_preference_user_id_user_id_fk", + "tableFrom": "product_preference", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "product_preference_member_unique": { + "name": "product_preference_member_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "user_id", + "product" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.project": { + "name": "project", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "project_organization_id_organization_id_fk": { + "name": "project_organization_id_organization_id_fk", + "tableFrom": "project", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "project_organization_slug_unique": { + "name": "project_organization_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "slug" + ] + }, + "project_id_organization_unique": { + "name": "project_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.rate_limit_override": { + "name": "rate_limit_override", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bucket": { + "name": "bucket", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "limit": { + "name": "limit", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "period_ms": { + "name": "period_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "burst": { + "name": "burst", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "rate_limit_override_organization_id_organization_id_fk": { + "name": "rate_limit_override_organization_id_organization_id_fk", + "tableFrom": "rate_limit_override", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "rate_limit_override_organization_bucket_unique": { + "name": "rate_limit_override_organization_bucket_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "bucket" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.received_email": { + "name": "received_email", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "received_email_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "blocked_reason": { + "name": "blocked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mail_from": { + "name": "mail_from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "recipients": { + "name": "recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "from": { + "name": "from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "to": { + "name": "to", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "cc": { + "name": "cc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "reply_to": { + "name": "reply_to", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "in_reply_to": { + "name": "in_reply_to", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "references": { + "name": "references", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "headers": { + "name": "headers", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "html": { + "name": "html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "truncated": { + "name": "truncated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "spam_verdict": { + "name": "spam_verdict", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "virus_verdict": { + "name": "virus_verdict", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "spf_verdict": { + "name": "spf_verdict", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dkim_verdict": { + "name": "dkim_verdict", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dmarc_verdict": { + "name": "dmarc_verdict", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dmarc_policy": { + "name": "dmarc_policy", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "raw_key": { + "name": "raw_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "received_at": { + "name": "received_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": { + "received_email_environment_id_idx": { + "name": "received_email_environment_id_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "received_email_created_at_idx": { + "name": "received_email_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "received_email_organization_idx": { + "name": "received_email_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "received_email_environment_fk": { + "name": "received_email_environment_fk", + "tableFrom": "received_email", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "received_email_provider_message_unique": { + "name": "received_email_provider_message_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "provider", + "provider_message_id" + ] + }, + "received_email_id_organization_unique": { + "name": "received_email_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.received_email_attachment": { + "name": "received_email_attachment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "received_email_id": { + "name": "received_email_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_id": { + "name": "content_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "disposition": { + "name": "disposition", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_key": { + "name": "content_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "received_email_attachment_email_fk": { + "name": "received_email_attachment_email_fk", + "tableFrom": "received_email_attachment", + "tableTo": "received_email", + "columnsFrom": [ + "received_email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "received_email_attachment_position_unique": { + "name": "received_email_attachment_position_unique", + "nullsNotDistinct": false, + "columns": [ + "received_email_id", + "position" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.receiving_domain": { + "name": "receiving_domain", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_id": { + "name": "domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "record": { + "name": "record", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "last_checked_at": { + "name": "last_checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "receiving_domain_environment_idx": { + "name": "receiving_domain_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "receiving_domain_next_check_at_idx": { + "name": "receiving_domain_next_check_at_idx", + "columns": [ + { + "expression": "next_check_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"receiving_domain\".\"next_check_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "receiving_domain_domain_fk": { + "name": "receiving_domain_domain_fk", + "tableFrom": "receiving_domain", + "tableTo": "domain", + "columnsFrom": [ + "domain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "receiving_domain_environment_fk": { + "name": "receiving_domain_environment_fk", + "tableFrom": "receiving_domain", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "receiving_domain_domain_unique": { + "name": "receiving_domain_domain_unique", + "nullsNotDistinct": false, + "columns": [ + "domain_id" + ] + }, + "receiving_domain_hostname_unique": { + "name": "receiving_domain_hostname_unique", + "nullsNotDistinct": false, + "columns": [ + "hostname" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reputation_event": { + "name": "reputation_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "reputation_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "trigger": { + "name": "trigger", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor": { + "name": "actor", + "type": "reputation_actor", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "actor_user_id": { + "name": "actor_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metrics": { + "name": "metrics", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "reputation_event_organization_created_at_idx": { + "name": "reputation_event_organization_created_at_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "reputation_event_organization_id_organization_id_fk": { + "name": "reputation_event_organization_id_organization_id_fk", + "tableFrom": "reputation_event", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "reputation_event_actor_user_id_user_id_fk": { + "name": "reputation_event_actor_user_id_user_id_fk", + "tableFrom": "reputation_event", + "tableTo": "user", + "columnsFrom": [ + "actor_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "reputation_event_id_organization_unique": { + "name": "reputation_event_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reputation_notification": { + "name": "reputation_notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reputation_event_id": { + "name": "reputation_event_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "reputation_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "reputation_notification_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "recipients": { + "name": "recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "reputation_notification_event_idx": { + "name": "reputation_notification_event_idx", + "columns": [ + { + "expression": "reputation_event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reputation_notification_next_attempt_idx": { + "name": "reputation_notification_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"reputation_notification\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "reputation_notification_organization_id_organization_id_fk": { + "name": "reputation_notification_organization_id_organization_id_fk", + "tableFrom": "reputation_notification", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "reputation_notification_event_fk": { + "name": "reputation_notification_event_fk", + "tableFrom": "reputation_notification", + "tableTo": "reputation_event", + "columnsFrom": [ + "reputation_event_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reputation_standing": { + "name": "reputation_standing", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "status": { + "name": "status", + "type": "reputation_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'good'" + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_changed_at": { + "name": "status_changed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "reinstated_at": { + "name": "reinstated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "marketing_paused_at": { + "name": "marketing_paused_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "marketing_reason": { + "name": "marketing_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "marketing_reinstated_at": { + "name": "marketing_reinstated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "policy_overrides": { + "name": "policy_overrides", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "metrics": { + "name": "metrics", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "last_evaluated_at": { + "name": "last_evaluated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "evaluation_lease_until": { + "name": "evaluation_lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_evaluation_at": { + "name": "next_evaluation_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "reputation_standing_next_evaluation_idx": { + "name": "reputation_standing_next_evaluation_idx", + "columns": [ + { + "expression": "next_evaluation_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"reputation_standing\".\"next_evaluation_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "reputation_standing_organization_id_organization_id_fk": { + "name": "reputation_standing_organization_id_organization_id_fk", + "tableFrom": "reputation_standing", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_assessment": { + "name": "risk_assessment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "risk_assessment_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event": { + "name": "event", + "type": "risk_event", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "event_name": { + "name": "event_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip": { + "name": "ip", + "type": "inet", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_hash": { + "name": "email_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_hash": { + "name": "ip_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subnet_hash": { + "name": "subnet_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "card_hash": { + "name": "card_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "device_hash": { + "name": "device_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "decision": { + "name": "decision", + "type": "risk_decision", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "score": { + "name": "score", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "reasons": { + "name": "reasons", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "signals": { + "name": "signals", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "degraded": { + "name": "degraded", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "outcome": { + "name": "outcome", + "type": "risk_outcome", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "outcome_at": { + "name": "outcome_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "review_status": { + "name": "review_status", + "type": "risk_review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "personal_data_purged_at": { + "name": "personal_data_purged_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": { + "risk_assessment_environment_sequence_idx": { + "name": "risk_assessment_environment_sequence_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_assessment_environment_user_idx": { + "name": "risk_assessment_environment_user_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"risk_assessment\".\"user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_assessment_open_review_idx": { + "name": "risk_assessment_open_review_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"risk_assessment\".\"review_status\" = 'open'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_assessment_created_at_idx": { + "name": "risk_assessment_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_assessment_personal_data_idx": { + "name": "risk_assessment_personal_data_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"risk_assessment\".\"personal_data_purged_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_assessment_environment_fk": { + "name": "risk_assessment_environment_fk", + "tableFrom": "risk_assessment", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_assessment_id_organization_unique": { + "name": "risk_assessment_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "risk_assessment_environment_idempotency_key_unique": { + "name": "risk_assessment_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_assessment_preparation": { + "name": "risk_assessment_preparation", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "risk_assessment_preparation_created_idx": { + "name": "risk_assessment_preparation_created_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_assessment_preparation_environment_id_environment_id_fk": { + "name": "risk_assessment_preparation_environment_id_environment_id_fk", + "tableFrom": "risk_assessment_preparation", + "tableTo": "environment", + "columnsFrom": [ + "environment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "risk_assessment_preparation_environment_id_idempotency_key_pk": { + "name": "risk_assessment_preparation_environment_id_idempotency_key_pk", + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_dataset": { + "name": "risk_dataset", + "schema": "", + "columns": { + "name": { + "name": "name", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entries": { + "name": "entries", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "checked_at": { + "name": "checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_domain_age": { + "name": "risk_domain_age", + "schema": "", + "columns": { + "domain": { + "name": "domain", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "registered_at": { + "name": "registered_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "checked_at": { + "name": "checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_feedback": { + "name": "risk_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "assessment_id": { + "name": "assessment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "outcome": { + "name": "outcome", + "type": "risk_outcome", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "risk_feedback_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "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()" + } + }, + "indexes": { + "risk_feedback_assessment_idx": { + "name": "risk_feedback_assessment_idx", + "columns": [ + { + "expression": "assessment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_feedback_assessment_fk": { + "name": "risk_feedback_assessment_fk", + "tableFrom": "risk_feedback", + "tableTo": "risk_assessment", + "columnsFrom": [ + "assessment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_identity": { + "name": "risk_identity", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "risk_identity_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "value_hash": { + "name": "value_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "assessment_id": { + "name": "assessment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "first_seen_at": { + "name": "first_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "risk_identity_environment_user_idx": { + "name": "risk_identity_environment_user_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"risk_identity\".\"user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_identity_last_seen_idx": { + "name": "risk_identity_last_seen_idx", + "columns": [ + { + "expression": "last_seen_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_identity_environment_fk": { + "name": "risk_identity_environment_fk", + "tableFrom": "risk_identity", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_identity_value_user_unique": { + "name": "risk_identity_value_user_unique", + "nullsNotDistinct": true, + "columns": [ + "environment_id", + "kind", + "value_hash", + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_limit_bucket": { + "name": "risk_limit_bucket", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "limit": { + "name": "limit", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "period_ms": { + "name": "period_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "burst": { + "name": "burst", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "on_failure": { + "name": "on_failure", + "type": "risk_limit_failure_mode", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'allow'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "risk_limit_bucket_environment_fk": { + "name": "risk_limit_bucket_environment_fk", + "tableFrom": "risk_limit_bucket", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_limit_bucket_name_unique": { + "name": "risk_limit_bucket_name_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "name" + ] + } + }, + "policies": {}, + "checkConstraints": { + "risk_limit_bucket_values_check": { + "name": "risk_limit_bucket_values_check", + "value": "\"risk_limit_bucket\".\"limit\" > 0 and \"risk_limit_bucket\".\"period_ms\" > 0 and \"risk_limit_bucket\".\"burst\" > 0" + } + }, + "isRLSEnabled": false + }, + "public.risk_list_entry": { + "name": "risk_list_entry", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "risk_list_entry_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "list": { + "name": "list", + "type": "risk_list", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "risk_list_entry_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "network": { + "name": "network", + "type": "cidr", + "primaryKey": false, + "notNull": false + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_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": { + "risk_list_entry_environment_sequence_idx": { + "name": "risk_list_entry_environment_sequence_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_list_entry_network_idx": { + "name": "risk_list_entry_network_idx", + "columns": [ + { + "expression": "network", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "inet_ops" + } + ], + "isUnique": false, + "where": "\"risk_list_entry\".\"network\" is not null", + "concurrently": false, + "method": "gist", + "with": {} + } + }, + "foreignKeys": { + "risk_list_entry_environment_fk": { + "name": "risk_list_entry_environment_fk", + "tableFrom": "risk_list_entry", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_list_entry_value_unique": { + "name": "risk_list_entry_value_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "list", + "type", + "value" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_report": { + "name": "risk_report", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "risk_report_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "value_hash": { + "name": "value_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "assessment_id": { + "name": "assessment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reported_at": { + "name": "reported_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "risk_report_assessment_idx": { + "name": "risk_report_assessment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "assessment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_report_reported_at_idx": { + "name": "risk_report_reported_at_idx", + "columns": [ + { + "expression": "reported_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_report_environment_fk": { + "name": "risk_report_environment_fk", + "tableFrom": "risk_report", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_report_value_unique": { + "name": "risk_report_value_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "kind", + "value_hash", + "assessment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_rule": { + "name": "risk_rule", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "events": { + "name": "events", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "match": { + "name": "match", + "type": "risk_rule_match", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'all'" + }, + "conditions": { + "name": "conditions", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "risk_decision", + "typeSchema": "public", + "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": { + "risk_rule_environment_position_idx": { + "name": "risk_rule_environment_position_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "position", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_rule_environment_fk": { + "name": "risk_rule_environment_fk", + "tableFrom": "risk_rule", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_settings": { + "name": "risk_settings", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "review_threshold": { + "name": "review_threshold", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "block_threshold": { + "name": "block_threshold", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "disabled_reasons": { + "name": "disabled_reasons", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "captcha_provider": { + "name": "captcha_provider", + "type": "risk_captcha_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "captcha_secret_ciphertext": { + "name": "captcha_secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "captcha_required": { + "name": "captcha_required", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "content_thresholds": { + "name": "content_thresholds", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "reason_weights": { + "name": "reason_weights", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "risk_settings_environment_fk": { + "name": "risk_settings_environment_fk", + "tableFrom": "risk_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "risk_settings_thresholds_check": { + "name": "risk_settings_thresholds_check", + "value": "\"risk_settings\".\"review_threshold\" > 0 and \"risk_settings\".\"review_threshold\" <= \"risk_settings\".\"block_threshold\" and \"risk_settings\".\"block_threshold\" <= 1" + }, + "risk_settings_captcha_check": { + "name": "risk_settings_captcha_check", + "value": "(\"risk_settings\".\"captcha_provider\" is null) = (\"risk_settings\".\"captcha_secret_ciphertext\" is null)" + } + }, + "isRLSEnabled": false + }, + "public.risk_user_network": { + "name": "risk_user_network", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_hash": { + "name": "user_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "risk_user_network_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "first_seen_at": { + "name": "first_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "risk_user_network_last_seen_idx": { + "name": "risk_user_network_last_seen_idx", + "columns": [ + { + "expression": "last_seen_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_user_network_environment_fk": { + "name": "risk_user_network_environment_fk", + "tableFrom": "risk_user_network", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_user_network_value_unique": { + "name": "risk_user_network_value_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "user_hash", + "kind", + "value" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_group_role": { + "name": "scim_group_role", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_name": { + "name": "group_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "scim_group_role_organization_id_organization_id_fk": { + "name": "scim_group_role_organization_id_organization_id_fk", + "tableFrom": "scim_group_role", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_group_role_organization_group_unique": { + "name": "scim_group_role_organization_group_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "group_name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.segment": { + "name": "segment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "filter": { + "name": "filter", + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "segment_environment_fk": { + "name": "segment_environment_fk", + "tableFrom": "segment", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "segment_environment_name_unique": { + "name": "segment_environment_name_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.topic": { + "name": "topic", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_subscription": { + "name": "default_subscription", + "type": "topic_default_subscription", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "visibility": { + "name": "visibility", + "type": "topic_visibility", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'public'" + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "topic_environment_fk": { + "name": "topic_environment_fk", + "tableFrom": "topic", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "topic_environment_key_unique": { + "name": "topic_environment_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "key" + ] + }, + "topic_id_organization_unique": { + "name": "topic_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tracking_domain": { + "name": "tracking_domain", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_id": { + "name": "domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "tracking_domain_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_hostname_id": { + "name": "provider_hostname_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "record": { + "name": "record", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "provider_message": { + "name": "provider_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "verification_started_at": { + "name": "verification_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_checked_at": { + "name": "last_checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "activated_at": { + "name": "activated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "failed_at": { + "name": "failed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "tracking_domain_hostname_active_unique": { + "name": "tracking_domain_hostname_active_unique", + "columns": [ + { + "expression": "hostname", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"tracking_domain\".\"status\" <> 'failed'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "tracking_domain_next_check_at_idx": { + "name": "tracking_domain_next_check_at_idx", + "columns": [ + { + "expression": "next_check_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"tracking_domain\".\"next_check_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "tracking_domain_domain_fk": { + "name": "tracking_domain_domain_fk", + "tableFrom": "tracking_domain", + "tableTo": "domain", + "columnsFrom": [ + "domain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "tracking_domain_domain_unique": { + "name": "tracking_domain_domain_unique", + "nullsNotDistinct": false, + "columns": [ + "domain_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_attempt": { + "name": "webhook_attempt", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "delivery_id": { + "name": "delivery_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempted_at": { + "name": "attempted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "response_excerpt": { + "name": "response_excerpt", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "webhook_attempt_delivery_idx": { + "name": "webhook_attempt_delivery_idx", + "columns": [ + { + "expression": "delivery_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "attempted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_attempt_delivery_fk": { + "name": "webhook_attempt_delivery_fk", + "tableFrom": "webhook_attempt", + "tableTo": "webhook_delivery", + "columnsFrom": [ + "delivery_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_delivery": { + "name": "webhook_delivery", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "endpoint_id": { + "name": "endpoint_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "webhook_delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "lease_expires_at": { + "name": "lease_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_status_code": { + "name": "last_status_code", + "type": "integer", + "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()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "webhook_delivery_due_idx": { + "name": "webhook_delivery_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"webhook_delivery\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "webhook_delivery_endpoint_created_at_idx": { + "name": "webhook_delivery_endpoint_created_at_idx", + "columns": [ + { + "expression": "endpoint_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_delivery_message_fk": { + "name": "webhook_delivery_message_fk", + "tableFrom": "webhook_delivery", + "tableTo": "webhook_message", + "columnsFrom": [ + "message_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "webhook_delivery_endpoint_fk": { + "name": "webhook_delivery_endpoint_fk", + "tableFrom": "webhook_delivery", + "tableTo": "webhook_endpoint", + "columnsFrom": [ + "endpoint_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhook_delivery_message_endpoint_unique": { + "name": "webhook_delivery_message_endpoint_unique", + "nullsNotDistinct": false, + "columns": [ + "message_id", + "endpoint_id" + ] + }, + "webhook_delivery_id_organization_unique": { + "name": "webhook_delivery_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_endpoint": { + "name": "webhook_endpoint", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_version": { + "name": "api_version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_types": { + "name": "event_types", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "secret_ciphertext": { + "name": "secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "previous_secret_ciphertext": { + "name": "previous_secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previous_secret_expires_at": { + "name": "previous_secret_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "disabled_reason": { + "name": "disabled_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_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_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "webhook_endpoint_environment_idx": { + "name": "webhook_endpoint_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_endpoint_created_by_user_id_user_id_fk": { + "name": "webhook_endpoint_created_by_user_id_user_id_fk", + "tableFrom": "webhook_endpoint", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "webhook_endpoint_environment_fk": { + "name": "webhook_endpoint_environment_fk", + "tableFrom": "webhook_endpoint", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhook_endpoint_id_organization_unique": { + "name": "webhook_endpoint_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "webhook_endpoint_previous_secret_check": { + "name": "webhook_endpoint_previous_secret_check", + "value": "(\"webhook_endpoint\".\"previous_secret_ciphertext\" is null) = (\"webhook_endpoint\".\"previous_secret_expires_at\" is null)" + } + }, + "isRLSEnabled": false + }, + "public.webhook_listener": { + "name": "webhook_listener", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_version": { + "name": "api_version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_types": { + "name": "event_types", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_api_key_id": { + "name": "created_by_api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_polled_at": { + "name": "last_polled_at", + "type": "timestamp with time zone", + "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": { + "webhook_listener_environment_expires_idx": { + "name": "webhook_listener_environment_expires_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "webhook_listener_expires_at_idx": { + "name": "webhook_listener_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_listener_environment_fk": { + "name": "webhook_listener_environment_fk", + "tableFrom": "webhook_listener", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhook_listener_id_organization_unique": { + "name": "webhook_listener_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_listener_delivery": { + "name": "webhook_listener_delivery", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "listener_id": { + "name": "listener_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "webhook_delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "handed_out_count": { + "name": "handed_out_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "lease_expires_at": { + "name": "lease_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "forwarded_at": { + "name": "forwarded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "webhook_listener_delivery_pending_idx": { + "name": "webhook_listener_delivery_pending_idx", + "columns": [ + { + "expression": "listener_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, + "where": "\"webhook_listener_delivery\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "webhook_listener_delivery_listener_idx": { + "name": "webhook_listener_delivery_listener_idx", + "columns": [ + { + "expression": "listener_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_listener_delivery_listener_fk": { + "name": "webhook_listener_delivery_listener_fk", + "tableFrom": "webhook_listener_delivery", + "tableTo": "webhook_listener", + "columnsFrom": [ + "listener_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "webhook_listener_delivery_message_fk": { + "name": "webhook_listener_delivery_message_fk", + "tableFrom": "webhook_listener_delivery", + "tableTo": "webhook_message", + "columnsFrom": [ + "message_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhook_listener_delivery_message_listener_unique": { + "name": "webhook_listener_delivery_message_listener_unique", + "nullsNotDistinct": false, + "columns": [ + "message_id", + "listener_id" + ] + }, + "webhook_listener_delivery_id_organization_unique": { + "name": "webhook_listener_delivery_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_message": { + "name": "webhook_message", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "webhook_message_environment_idx": { + "name": "webhook_message_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "webhook_message_created_at_idx": { + "name": "webhook_message_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_message_environment_fk": { + "name": "webhook_message_environment_fk", + "tableFrom": "webhook_message", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhook_message_id_organization_unique": { + "name": "webhook_message_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form": { + "name": "form", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "fields": { + "name": "fields", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "strict_fields": { + "name": "strict_fields", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "allowed_origins": { + "name": "allowed_origins", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "redirect_url": { + "name": "redirect_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "honeypot_field": { + "name": "honeypot_field", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'_gotcha'" + }, + "captcha": { + "name": "captcha", + "type": "form_captcha", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'off'" + }, + "captcha_site_key": { + "name": "captcha_site_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "on_review": { + "name": "on_review", + "type": "form_on_review", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'hold'" + }, + "content_threshold": { + "name": "content_threshold", + "type": "double precision", + "primaryKey": false, + "notNull": false, + "default": 0.9 + }, + "email_field": { + "name": "email_field", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'email'" + }, + "verify_submitter": { + "name": "verify_submitter", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "notify_recipients": { + "name": "notify_recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "notification_from": { + "name": "notification_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_from": { + "name": "confirmation_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contacts": { + "name": "contacts", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "files": { + "name": "files", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "hosted": { + "name": "hosted", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "hosted_published_at": { + "name": "hosted_published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_by_admin_at": { + "name": "disabled_by_admin_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_environment_created_at_idx": { + "name": "form_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "form_environment_fk": { + "name": "form_environment_fk", + "tableFrom": "form", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "form_id_organization_unique": { + "name": "form_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_delivery": { + "name": "form_delivery", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "submission_id": { + "name": "submission_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "form_delivery_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "form_delivery_state", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "delivered_at": { + "name": "delivered_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_delivery_due_idx": { + "name": "form_delivery_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"form_delivery\".\"state\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "form_delivery_submission_fk": { + "name": "form_delivery_submission_fk", + "tableFrom": "form_delivery", + "tableTo": "form_submission", + "columnsFrom": [ + "submission_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "form_delivery_submission_kind_unique": { + "name": "form_delivery_submission_kind_unique", + "nullsNotDistinct": false, + "columns": [ + "submission_id", + "kind" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_fake_object": { + "name": "form_fake_object", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_fake_object_organization_idx": { + "name": "form_fake_object_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_store_cleanup": { + "name": "form_store_cleanup", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_store_cleanup_next_attempt_at_idx": { + "name": "form_store_cleanup_next_attempt_at_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "form_store_cleanup_organization_idx": { + "name": "form_store_cleanup_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_submission": { + "name": "form_submission", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "form_id": { + "name": "form_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "form_submission_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "submitter_email": { + "name": "submitter_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip": { + "name": "ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "origin": { + "name": "origin", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "referrer": { + "name": "referrer", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "risk_assessment_id": { + "name": "risk_assessment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "risk_decision": { + "name": "risk_decision", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "risk_score": { + "name": "risk_score", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "spam_reason": { + "name": "spam_reason", + "type": "form_spam_reason", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "confirmation_token_hash": { + "name": "confirmation_token_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_expires_at": { + "name": "confirmation_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "confirmed_at": { + "name": "confirmed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "released_at": { + "name": "released_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "released_by": { + "name": "released_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_submission_form_created_at_idx": { + "name": "form_submission_form_created_at_idx", + "columns": [ + { + "expression": "form_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "form_submission_created_at_idx": { + "name": "form_submission_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "form_submission_environment_idx": { + "name": "form_submission_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "form_submission_form_fk": { + "name": "form_submission_form_fk", + "tableFrom": "form_submission", + "tableTo": "form", + "columnsFrom": [ + "form_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "form_submission_confirmation_token_unique": { + "name": "form_submission_confirmation_token_unique", + "nullsNotDistinct": false, + "columns": [ + "confirmation_token_hash" + ] + }, + "form_submission_id_organization_unique": { + "name": "form_submission_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_submission_file": { + "name": "form_submission_file", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "submission_id": { + "name": "submission_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "field": { + "name": "field", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "store_key": { + "name": "store_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_submission_file_submission_idx": { + "name": "form_submission_file_submission_idx", + "columns": [ + { + "expression": "submission_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "form_submission_file_submission_fk": { + "name": "form_submission_file_submission_fk", + "tableFrom": "form_submission_file", + "tableTo": "form_submission", + "columnsFrom": [ + "submission_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.inbox": { + "name": "inbox", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "inbox_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "address": { + "name": "address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "next_fee_at": { + "name": "next_fee_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "inbox_environment_id_idx": { + "name": "inbox_environment_id_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_organization_idx": { + "name": "inbox_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_next_fee_at_idx": { + "name": "inbox_next_fee_at_idx", + "columns": [ + { + "expression": "next_fee_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"inbox\".\"next_fee_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "inbox_environment_fk": { + "name": "inbox_environment_fk", + "tableFrom": "inbox", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "inbox_environment_address_unique": { + "name": "inbox_environment_address_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "address" + ] + }, + "inbox_environment_client_id_unique": { + "name": "inbox_environment_client_id_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "client_id" + ] + }, + "inbox_id_organization_unique": { + "name": "inbox_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.inbox_message": { + "name": "inbox_message", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "inbox_id": { + "name": "inbox_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "thread_id": { + "name": "thread_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "direction": { + "name": "direction", + "type": "inbox_message_direction", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "received_email_id": { + "name": "received_email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rfc_message_id": { + "name": "rfc_message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "inbox_message_thread_idx": { + "name": "inbox_message_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, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_message_inbox_id_idx": { + "name": "inbox_message_inbox_id_idx", + "columns": [ + { + "expression": "inbox_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_message_inbox_rfc_message_id_idx": { + "name": "inbox_message_inbox_rfc_message_id_idx", + "columns": [ + { + "expression": "inbox_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "rfc_message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"inbox_message\".\"rfc_message_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_message_received_email_idx": { + "name": "inbox_message_received_email_idx", + "columns": [ + { + "expression": "received_email_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_message_organization_idx": { + "name": "inbox_message_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "inbox_message_thread_fk": { + "name": "inbox_message_thread_fk", + "tableFrom": "inbox_message", + "tableTo": "inbox_thread", + "columnsFrom": [ + "thread_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "inbox_message_received_email_fk": { + "name": "inbox_message_received_email_fk", + "tableFrom": "inbox_message", + "tableTo": "received_email", + "columnsFrom": [ + "received_email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "inbox_message_email_fk": { + "name": "inbox_message_email_fk", + "tableFrom": "inbox_message", + "tableTo": "email", + "columnsFrom": [ + "email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "inbox_message_inbox_received_email_unique": { + "name": "inbox_message_inbox_received_email_unique", + "nullsNotDistinct": false, + "columns": [ + "inbox_id", + "received_email_id" + ] + }, + "inbox_message_email_unique": { + "name": "inbox_message_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "inbox_message_source_check": { + "name": "inbox_message_source_check", + "value": "(\"inbox_message\".\"direction\" = 'inbound' and \"inbox_message\".\"received_email_id\" is not null and \"inbox_message\".\"email_id\" is null) or (\"inbox_message\".\"direction\" = 'outbound' and \"inbox_message\".\"email_id\" is not null and \"inbox_message\".\"received_email_id\" is null)" + } + }, + "isRLSEnabled": false + }, + "public.inbox_thread": { + "name": "inbox_thread", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "inbox_id": { + "name": "inbox_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subject_key": { + "name": "subject_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "participants": { + "name": "participants", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_message_at": { + "name": "last_message_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": { + "inbox_thread_inbox_last_message_idx": { + "name": "inbox_thread_inbox_last_message_idx", + "columns": [ + { + "expression": "inbox_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "last_message_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_thread_inbox_subject_idx": { + "name": "inbox_thread_inbox_subject_idx", + "columns": [ + { + "expression": "inbox_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "subject_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_thread_last_message_at_idx": { + "name": "inbox_thread_last_message_at_idx", + "columns": [ + { + "expression": "last_message_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_thread_organization_idx": { + "name": "inbox_thread_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "inbox_thread_inbox_fk": { + "name": "inbox_thread_inbox_fk", + "tableFrom": "inbox_thread", + "tableTo": "inbox", + "columnsFrom": [ + "inbox_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "inbox_thread_id_organization_unique": { + "name": "inbox_thread_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notification": { + "name": "notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "notification_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "recipients": { + "name": "recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "notification_dedupe_unique": { + "name": "notification_dedupe_unique", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "dedupe_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_next_attempt_idx": { + "name": "notification_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"notification\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_created_at_idx": { + "name": "notification_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notification_organization_id_organization_id_fk": { + "name": "notification_organization_id_organization_id_fk", + "tableFrom": "notification", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.push_device": { + "name": "push_device", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "apns_environment": { + "name": "apns_environment", + "type": "apns_environment", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "categories": { + "name": "categories", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "push_device_session_idx": { + "name": "push_device_session_idx", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_device_token_idx": { + "name": "push_device_token_idx", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_device_user_idx": { + "name": "push_device_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "push_device_user_id_user_id_fk": { + "name": "push_device_user_id_user_id_fk", + "tableFrom": "push_device", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "push_device_session_id_session_id_fk": { + "name": "push_device_session_id_session_id_fk", + "tableFrom": "push_device", + "tableTo": "session", + "columnsFrom": [ + "session_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.push_notification": { + "name": "push_notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "push_notification_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "subject_id": { + "name": "subject_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "collapse_key": { + "name": "collapse_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "status": { + "name": "status", + "type": "push_notification_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "delivered_device_ids": { + "name": "delivered_device_ids", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "push_notification_pending_collapse_idx": { + "name": "push_notification_pending_collapse_idx", + "columns": [ + { + "expression": "collapse_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"push_notification\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_notification_collapse_sent_idx": { + "name": "push_notification_collapse_sent_idx", + "columns": [ + { + "expression": "collapse_key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sent_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"push_notification\".\"collapse_key\" IS NOT NULL AND \"push_notification\".\"sent_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_notification_next_attempt_idx": { + "name": "push_notification_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"push_notification\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_notification_created_at_idx": { + "name": "push_notification_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_notification_organization_idx": { + "name": "push_notification_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "push_notification_organization_id_organization_id_fk": { + "name": "push_notification_organization_id_organization_id_fk", + "tableFrom": "push_notification", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "push_notification_environment_fk": { + "name": "push_notification_environment_fk", + "tableFrom": "push_notification", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_attendee": { + "name": "scheduling_attendee", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "uid": { + "name": "uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_contact": { + "name": "encrypted_contact", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_hmac": { + "name": "email_hmac", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_answers": { + "name": "encrypted_answers", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "time_zone": { + "name": "time_zone", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "locale": { + "name": "locale", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "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": { + "scheduling_attendee_booking_idx": { + "name": "scheduling_attendee_booking_idx", + "columns": [ + { + "expression": "booking_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_attendee_environment_uid_idx": { + "name": "scheduling_attendee_environment_uid_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "uid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_attendee_environment_email_idx": { + "name": "scheduling_attendee_environment_email_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email_hmac", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_attendee_booking_fk": { + "name": "scheduling_attendee_booking_fk", + "tableFrom": "scheduling_attendee", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_booking": { + "name": "scheduling_booking", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "scheduling_booking_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "start_at": { + "name": "start_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_at": { + "name": "end_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "buffer_before_minutes": { + "name": "buffer_before_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "buffer_after_minutes": { + "name": "buffer_after_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "location": { + "name": "location", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "hold_expires_at": { + "name": "hold_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "approval_expires_at": { + "name": "approval_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "series_id": { + "name": "series_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "series_index": { + "name": "series_index", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "group_session_id": { + "name": "group_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "calendar_unverified": { + "name": "calendar_unverified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "external_conflict_at": { + "name": "external_conflict_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "no_show_at": { + "name": "no_show_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancelled_at": { + "name": "cancelled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "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()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_booking_environment_start_idx": { + "name": "scheduling_booking_environment_start_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_event_type_start_idx": { + "name": "scheduling_booking_event_type_start_idx", + "columns": [ + { + "expression": "event_type_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_series_idx": { + "name": "scheduling_booking_series_idx", + "columns": [ + { + "expression": "series_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "series_index", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_group_session_idx": { + "name": "scheduling_booking_group_session_idx", + "columns": [ + { + "expression": "group_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_end_idx": { + "name": "scheduling_booking_end_idx", + "columns": [ + { + "expression": "end_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_unredacted_end_idx": { + "name": "scheduling_booking_unredacted_end_idx", + "columns": [ + { + "expression": "end_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_booking\".\"redacted_at\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_hold_expiry_idx": { + "name": "scheduling_booking_hold_expiry_idx", + "columns": [ + { + "expression": "hold_expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_booking\".\"status\" = 'held'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_approval_expiry_idx": { + "name": "scheduling_booking_approval_expiry_idx", + "columns": [ + { + "expression": "approval_expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_booking\".\"status\" = 'pending_approval'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_booking_environment_fk": { + "name": "scheduling_booking_environment_fk", + "tableFrom": "scheduling_booking", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_booking_event_type_fk": { + "name": "scheduling_booking_event_type_fk", + "tableFrom": "scheduling_booking", + "tableTo": "scheduling_event_type", + "columnsFrom": [ + "event_type_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_booking_series_fk": { + "name": "scheduling_booking_series_fk", + "tableFrom": "scheduling_booking", + "tableTo": "scheduling_series", + "columnsFrom": [ + "series_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "scheduling_booking_group_session_fk": { + "name": "scheduling_booking_group_session_fk", + "tableFrom": "scheduling_booking", + "tableTo": "scheduling_group_session", + "columnsFrom": [ + "group_session_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_booking_id_organization_unique": { + "name": "scheduling_booking_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "scheduling_booking_environment_idempotency_unique": { + "name": "scheduling_booking_environment_idempotency_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": { + "scheduling_booking_time_order": { + "name": "scheduling_booking_time_order", + "value": "\"scheduling_booking\".\"start_at\" < \"scheduling_booking\".\"end_at\"" + }, + "scheduling_booking_hold_has_expiry": { + "name": "scheduling_booking_hold_has_expiry", + "value": "\"scheduling_booking\".\"status\" <> 'held' OR \"scheduling_booking\".\"hold_expires_at\" IS NOT NULL" + }, + "scheduling_booking_approval_has_expiry": { + "name": "scheduling_booking_approval_has_expiry", + "value": "\"scheduling_booking\".\"status\" <> 'pending_approval' OR \"scheduling_booking\".\"approval_expires_at\" IS NOT NULL" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_booking_event": { + "name": "scheduling_booking_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor": { + "name": "actor", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "scheduling_booking_event_booking_fk": { + "name": "scheduling_booking_event_booking_fk", + "tableFrom": "scheduling_booking_event", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_booking_event_sequence_unique": { + "name": "scheduling_booking_event_sequence_unique", + "nullsNotDistinct": false, + "columns": [ + "booking_id", + "sequence" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_booking_host": { + "name": "scheduling_booking_host", + "schema": "", + "columns": { + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "scheduling_host_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'member'" + } + }, + "indexes": { + "scheduling_booking_host_host_idx": { + "name": "scheduling_booking_host_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_booking_host_booking_fk": { + "name": "scheduling_booking_host_booking_fk", + "tableFrom": "scheduling_booking_host", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_booking_host_host_fk": { + "name": "scheduling_booking_host_host_fk", + "tableFrom": "scheduling_booking_host", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "scheduling_booking_host_booking_id_host_id_pk": { + "name": "scheduling_booking_host_booking_id_host_id_pk", + "columns": [ + "booking_id", + "host_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_busy_interval": { + "name": "scheduling_busy_interval", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "calendar_id": { + "name": "calendar_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start_at": { + "name": "start_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_at": { + "name": "end_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scheduling_busy_interval_host_idx": { + "name": "scheduling_busy_interval_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "end_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_busy_interval_calendar_idx": { + "name": "scheduling_busy_interval_calendar_idx", + "columns": [ + { + "expression": "calendar_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_busy_interval_calendar_fk": { + "name": "scheduling_busy_interval_calendar_fk", + "tableFrom": "scheduling_busy_interval", + "tableTo": "scheduling_calendar", + "columnsFrom": [ + "calendar_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_calendar": { + "name": "scheduling_calendar", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "read_busy": { + "name": "read_busy", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "write_target": { + "name": "write_target", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "verified_at": { + "name": "verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "covered_until": { + "name": "covered_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "dirty_at": { + "name": "dirty_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_fetch_started_at": { + "name": "last_fetch_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_sync_at": { + "name": "next_sync_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sync_failures": { + "name": "sync_failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "channel_id": { + "name": "channel_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "channel_resource_id": { + "name": "channel_resource_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "channel_token_hash": { + "name": "channel_token_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "channel_expires_at": { + "name": "channel_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_calendar_host_write_target_unique": { + "name": "scheduling_calendar_host_write_target_unique", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"scheduling_calendar\".\"write_target\"", + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_calendar_host_idx": { + "name": "scheduling_calendar_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_calendar_channel_idx": { + "name": "scheduling_calendar_channel_idx", + "columns": [ + { + "expression": "channel_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_calendar_next_sync_idx": { + "name": "scheduling_calendar_next_sync_idx", + "columns": [ + { + "expression": "next_sync_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_calendar_connection_fk": { + "name": "scheduling_calendar_connection_fk", + "tableFrom": "scheduling_calendar", + "tableTo": "scheduling_calendar_connection", + "columnsFrom": [ + "connection_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_calendar_id_organization_unique": { + "name": "scheduling_calendar_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "scheduling_calendar_connection_external_unique": { + "name": "scheduling_calendar_connection_external_unique", + "nullsNotDistinct": false, + "columns": [ + "connection_id", + "external_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_calendar_connection": { + "name": "scheduling_calendar_connection", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "scheduling_calendar_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "encrypted_credentials": { + "name": "encrypted_credentials", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "scheduling_connection_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "last_error_code": { + "name": "last_error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_error_at": { + "name": "last_error_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "scheduling_calendar_connection_host_fk": { + "name": "scheduling_calendar_connection_host_fk", + "tableFrom": "scheduling_calendar_connection", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_calendar_connection_id_organization_unique": { + "name": "scheduling_calendar_connection_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "scheduling_calendar_connection_account_unique": { + "name": "scheduling_calendar_connection_account_unique", + "nullsNotDistinct": false, + "columns": [ + "host_id", + "provider", + "account_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_calendar_event": { + "name": "scheduling_calendar_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "group_session_id": { + "name": "group_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "calendar_id": { + "name": "calendar_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "desired_start": { + "name": "desired_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "desired_end": { + "name": "desired_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "desired_state": { + "name": "desired_state", + "type": "scheduling_calendar_event_state", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'present'" + }, + "desired_version": { + "name": "desired_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "applied_version": { + "name": "applied_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider_event_id": { + "name": "provider_event_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key_generation": { + "name": "key_generation", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "external_state": { + "name": "external_state", + "type": "scheduling_external_state", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'in_sync'" + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_error_code": { + "name": "last_error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_calendar_event_host_idx": { + "name": "scheduling_calendar_event_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "desired_end", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "desired_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_calendar_event_due_idx": { + "name": "scheduling_calendar_event_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_calendar_event\".\"applied_version\" < \"scheduling_calendar_event\".\"desired_version\"", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_calendar_event_booking_fk": { + "name": "scheduling_calendar_event_booking_fk", + "tableFrom": "scheduling_calendar_event", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_calendar_event_group_session_fk": { + "name": "scheduling_calendar_event_group_session_fk", + "tableFrom": "scheduling_calendar_event", + "tableTo": "scheduling_group_session", + "columnsFrom": [ + "group_session_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_calendar_event_calendar_fk": { + "name": "scheduling_calendar_event_calendar_fk", + "tableFrom": "scheduling_calendar_event", + "tableTo": "scheduling_calendar", + "columnsFrom": [ + "calendar_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_calendar_event_target_unique": { + "name": "scheduling_calendar_event_target_unique", + "nullsNotDistinct": false, + "columns": [ + "booking_id", + "host_id", + "calendar_id" + ] + }, + "scheduling_calendar_event_session_target_unique": { + "name": "scheduling_calendar_event_session_target_unique", + "nullsNotDistinct": false, + "columns": [ + "group_session_id", + "host_id", + "calendar_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "scheduling_calendar_event_one_owner": { + "name": "scheduling_calendar_event_one_owner", + "value": "(\"scheduling_calendar_event\".\"booking_id\" IS NULL) <> (\"scheduling_calendar_event\".\"group_session_id\" IS NULL)" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_claim": { + "name": "scheduling_claim", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "group_session_id": { + "name": "group_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "occupied_start": { + "name": "occupied_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "occupied_end": { + "name": "occupied_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "live_from": { + "name": "live_from", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "live_until": { + "name": "live_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "limit_day": { + "name": "limit_day", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "limit_week": { + "name": "limit_week", + "type": "date", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scheduling_claim_booking_idx": { + "name": "scheduling_claim_booking_idx", + "columns": [ + { + "expression": "booking_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_claim_group_session_idx": { + "name": "scheduling_claim_group_session_idx", + "columns": [ + { + "expression": "group_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_claim_host_day_idx": { + "name": "scheduling_claim_host_day_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "limit_day", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_claim_host_week_idx": { + "name": "scheduling_claim_host_week_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "limit_week", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_claim_occupied_end_idx": { + "name": "scheduling_claim_occupied_end_idx", + "columns": [ + { + "expression": "occupied_end", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_claim_live_until_idx": { + "name": "scheduling_claim_live_until_idx", + "columns": [ + { + "expression": "live_until", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_claim\".\"live_until\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_claim_host_fk": { + "name": "scheduling_claim_host_fk", + "tableFrom": "scheduling_claim", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_claim_booking_fk": { + "name": "scheduling_claim_booking_fk", + "tableFrom": "scheduling_claim", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_claim_group_session_fk": { + "name": "scheduling_claim_group_session_fk", + "tableFrom": "scheduling_claim", + "tableTo": "scheduling_group_session", + "columnsFrom": [ + "group_session_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "scheduling_claim_occupied_order": { + "name": "scheduling_claim_occupied_order", + "value": "\"scheduling_claim\".\"occupied_start\" < \"scheduling_claim\".\"occupied_end\"" + }, + "scheduling_claim_live_order": { + "name": "scheduling_claim_live_order", + "value": "\"scheduling_claim\".\"live_until\" IS NULL OR \"scheduling_claim\".\"live_from\" < \"scheduling_claim\".\"live_until\"" + }, + "scheduling_claim_one_owner": { + "name": "scheduling_claim_one_owner", + "value": "(\"scheduling_claim\".\"booking_id\" IS NULL) <> (\"scheduling_claim\".\"group_session_id\" IS NULL)" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_event_type": { + "name": "scheduling_event_type", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "uid": { + "name": "uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "scheduling_event_type_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'one_on_one'" + }, + "status": { + "name": "status", + "type": "scheduling_event_type_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "duration_minutes": { + "name": "duration_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "duration_options": { + "name": "duration_options", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "step_minutes": { + "name": "step_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "grid_time_zone": { + "name": "grid_time_zone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "buffer_before_minutes": { + "name": "buffer_before_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "buffer_after_minutes": { + "name": "buffer_after_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "min_notice_minutes": { + "name": "min_notice_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "booking_window": { + "name": "booking_window", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "limits": { + "name": "limits", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "capacity": { + "name": "capacity", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "requires_approval": { + "name": "requires_approval", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "approval_ttl_minutes": { + "name": "approval_ttl_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1440 + }, + "hold_ttl_seconds": { + "name": "hold_ttl_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 600 + }, + "cancel_notice_minutes": { + "name": "cancel_notice_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "reschedule_notice_minutes": { + "name": "reschedule_notice_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "questions": { + "name": "questions", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "locations": { + "name": "locations", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "host_filter": { + "name": "host_filter", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "notifications": { + "name": "notifications", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "screened_at": { + "name": "screened_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_event_type_environment_created_at_idx": { + "name": "scheduling_event_type_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_event_type_environment_fk": { + "name": "scheduling_event_type_environment_fk", + "tableFrom": "scheduling_event_type", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_event_type_environment_uid_unique": { + "name": "scheduling_event_type_environment_uid_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "uid" + ] + }, + "scheduling_event_type_id_organization_unique": { + "name": "scheduling_event_type_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "scheduling_event_type_duration_positive": { + "name": "scheduling_event_type_duration_positive", + "value": "\"scheduling_event_type\".\"duration_minutes\" > 0" + }, + "scheduling_event_type_step_positive": { + "name": "scheduling_event_type_step_positive", + "value": "\"scheduling_event_type\".\"step_minutes\" > 0" + }, + "scheduling_event_type_capacity": { + "name": "scheduling_event_type_capacity", + "value": "\"scheduling_event_type\".\"capacity\" IS NULL OR (\"scheduling_event_type\".\"kind\" = 'group' AND \"scheduling_event_type\".\"capacity\" > 0)" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_event_type_host": { + "name": "scheduling_event_type_host", + "schema": "", + "columns": { + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "scheduling_host_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "weight": { + "name": "weight", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 100 + }, + "assigned": { + "name": "assigned", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "fair_units": { + "name": "fair_units", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_assigned_at": { + "name": "last_assigned_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "schedule_id": { + "name": "schedule_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "removed_at": { + "name": "removed_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": { + "scheduling_event_type_host_host_idx": { + "name": "scheduling_event_type_host_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_event_type_host_event_type_fk": { + "name": "scheduling_event_type_host_event_type_fk", + "tableFrom": "scheduling_event_type_host", + "tableTo": "scheduling_event_type", + "columnsFrom": [ + "event_type_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_event_type_host_host_fk": { + "name": "scheduling_event_type_host_host_fk", + "tableFrom": "scheduling_event_type_host", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "scheduling_event_type_host_event_type_id_host_id_pk": { + "name": "scheduling_event_type_host_event_type_id_host_id_pk", + "columns": [ + "event_type_id", + "host_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "scheduling_event_type_host_weight_positive": { + "name": "scheduling_event_type_host_weight_positive", + "value": "\"scheduling_event_type_host\".\"weight\" > 0" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_group_session": { + "name": "scheduling_group_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start_at": { + "name": "start_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_at": { + "name": "end_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "capacity": { + "name": "capacity", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "location": { + "name": "location", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "meeting_url": { + "name": "meeting_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_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": { + "scheduling_group_session_end_at_idx": { + "name": "scheduling_group_session_end_at_idx", + "columns": [ + { + "expression": "end_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_group_session_event_type_fk": { + "name": "scheduling_group_session_event_type_fk", + "tableFrom": "scheduling_group_session", + "tableTo": "scheduling_event_type", + "columnsFrom": [ + "event_type_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_group_session_host_fk": { + "name": "scheduling_group_session_host_fk", + "tableFrom": "scheduling_group_session", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_group_session_id_organization_unique": { + "name": "scheduling_group_session_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "scheduling_group_session_slot_unique": { + "name": "scheduling_group_session_slot_unique", + "nullsNotDistinct": false, + "columns": [ + "event_type_id", + "host_id", + "start_at" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_host": { + "name": "scheduling_host", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "uid": { + "name": "uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "time_zone": { + "name": "time_zone", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attributes": { + "name": "attributes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "scheduling_host_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "screened_at": { + "name": "screened_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_host_environment_created_at_idx": { + "name": "scheduling_host_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_host_attributes_idx": { + "name": "scheduling_host_attributes_idx", + "columns": [ + { + "expression": "attributes", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "jsonb_path_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + } + }, + "foreignKeys": { + "scheduling_host_environment_fk": { + "name": "scheduling_host_environment_fk", + "tableFrom": "scheduling_host", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_host_environment_uid_unique": { + "name": "scheduling_host_environment_uid_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "uid" + ] + }, + "scheduling_host_id_organization_unique": { + "name": "scheduling_host_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_limit_bucket": { + "name": "scheduling_limit_bucket", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope_id": { + "name": "scope_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period": { + "name": "period", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_limit_bucket_organization_idx": { + "name": "scheduling_limit_bucket_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_limit_bucket_created_at_idx": { + "name": "scheduling_limit_bucket_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "scheduling_limit_bucket_scope_scope_id_period_pk": { + "name": "scheduling_limit_bucket_scope_scope_id_period_pk", + "columns": [ + "scope", + "scope_id", + "period" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_logo": { + "name": "scheduling_logo", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "scheduling_logo_environment_fk": { + "name": "scheduling_logo_environment_fk", + "tableFrom": "scheduling_logo", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_logo_environment_unique": { + "name": "scheduling_logo_environment_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_notification": { + "name": "scheduling_notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "channel": { + "name": "channel", + "type": "scheduling_notification_channel", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "recipient": { + "name": "recipient", + "type": "scheduling_notification_recipient", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "booking_version": { + "name": "booking_version", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "due_at": { + "name": "due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "outcome": { + "name": "outcome", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_notification_due_idx": { + "name": "scheduling_notification_due_idx", + "columns": [ + { + "expression": "due_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_notification\".\"finished_at\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_notification_booking_idx": { + "name": "scheduling_notification_booking_idx", + "columns": [ + { + "expression": "booking_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_notification_environment_fk": { + "name": "scheduling_notification_environment_fk", + "tableFrom": "scheduling_notification", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_notification_booking_fk": { + "name": "scheduling_notification_booking_fk", + "tableFrom": "scheduling_notification", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_notification_dedupe_unique": { + "name": "scheduling_notification_dedupe_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_oauth_state": { + "name": "scheduling_oauth_state", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "scheduling_calendar_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "state_hash": { + "name": "state_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "encrypted_code_verifier": { + "name": "encrypted_code_verifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "return_url": { + "name": "return_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_oauth_state_expires_at_idx": { + "name": "scheduling_oauth_state_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_oauth_state_host_fk": { + "name": "scheduling_oauth_state_host_fk", + "tableFrom": "scheduling_oauth_state", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_oauth_state_hash_unique": { + "name": "scheduling_oauth_state_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "state_hash" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_schedule": { + "name": "scheduling_schedule", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "time_zone": { + "name": "time_zone", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "rules": { + "name": "rules", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_schedule_host_default_unique": { + "name": "scheduling_schedule_host_default_unique", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"scheduling_schedule\".\"is_default\"", + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_schedule_host_idx": { + "name": "scheduling_schedule_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_schedule_host_fk": { + "name": "scheduling_schedule_host_fk", + "tableFrom": "scheduling_schedule", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_schedule_id_organization_unique": { + "name": "scheduling_schedule_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_schedule_override": { + "name": "scheduling_schedule_override", + "schema": "", + "columns": { + "schedule_id": { + "name": "schedule_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "date": { + "name": "date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "ranges": { + "name": "ranges", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + } + }, + "indexes": {}, + "foreignKeys": { + "scheduling_schedule_override_schedule_fk": { + "name": "scheduling_schedule_override_schedule_fk", + "tableFrom": "scheduling_schedule_override", + "tableTo": "scheduling_schedule", + "columnsFrom": [ + "schedule_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "scheduling_schedule_override_schedule_id_date_pk": { + "name": "scheduling_schedule_override_schedule_id_date_pk", + "columns": [ + "schedule_id", + "date" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_series": { + "name": "scheduling_series", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "rule": { + "name": "rule", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "anchor_time_zone": { + "name": "anchor_time_zone", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_series_environment_idx": { + "name": "scheduling_series_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_series_created_at_idx": { + "name": "scheduling_series_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_series_event_type_fk": { + "name": "scheduling_series_event_type_fk", + "tableFrom": "scheduling_series", + "tableTo": "scheduling_event_type", + "columnsFrom": [ + "event_type_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_series_id_organization_unique": { + "name": "scheduling_series_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "scheduling_series_environment_idempotency_unique": { + "name": "scheduling_series_environment_idempotency_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_session": { + "name": "scheduling_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "scheduling_session_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_attendee": { + "name": "encrypted_attendee", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_attributes": { + "name": "encrypted_attributes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attendee_uid": { + "name": "attendee_uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "read_only": { + "name": "read_only", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_session_expires_at_idx": { + "name": "scheduling_session_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_session_booking_idx": { + "name": "scheduling_session_booking_idx", + "columns": [ + { + "expression": "booking_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_session_attendee_uid_idx": { + "name": "scheduling_session_attendee_uid_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "attendee_uid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_session\".\"attendee_uid\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_session_environment_fk": { + "name": "scheduling_session_environment_fk", + "tableFrom": "scheduling_session", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_session_host_fk": { + "name": "scheduling_session_host_fk", + "tableFrom": "scheduling_session", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_session_event_type_fk": { + "name": "scheduling_session_event_type_fk", + "tableFrom": "scheduling_session", + "tableTo": "scheduling_event_type", + "columnsFrom": [ + "event_type_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_session_booking_fk": { + "name": "scheduling_session_booking_fk", + "tableFrom": "scheduling_session", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_session_token_hash_unique": { + "name": "scheduling_session_token_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "token_hash" + ] + } + }, + "policies": {}, + "checkConstraints": { + "scheduling_session_scope": { + "name": "scheduling_session_scope", + "value": "(\"scheduling_session\".\"kind\" = 'host' AND \"scheduling_session\".\"host_id\" IS NOT NULL)\n OR (\"scheduling_session\".\"kind\" = 'booker' AND (\"scheduling_session\".\"event_type_id\" IS NOT NULL OR \"scheduling_session\".\"host_id\" IS NOT NULL))\n OR (\"scheduling_session\".\"kind\" = 'manage' AND \"scheduling_session\".\"booking_id\" IS NOT NULL)" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_settings": { + "name": "scheduling_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "allowed_origins": { + "name": "allowed_origins", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "brand_name": { + "name": "brand_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "accent_color": { + "name": "accent_color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_from": { + "name": "email_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sms_from": { + "name": "sms_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notifications": { + "name": "notifications", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "calendar_failure_mode": { + "name": "calendar_failure_mode", + "type": "scheduling_calendar_failure_mode", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'hide'" + }, + "screened_at": { + "name": "screened_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "scheduling_settings_environment_fk": { + "name": "scheduling_settings_environment_fk", + "tableFrom": "scheduling_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_settings_environment_unique": { + "name": "scheduling_settings_environment_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_builder_session": { + "name": "sign_builder_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "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 + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_builder_session_expires_at_idx": { + "name": "sign_builder_session_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_builder_session_template_fk": { + "name": "sign_builder_session_template_fk", + "tableFrom": "sign_builder_session", + "tableTo": "sign_template", + "columnsFrom": [ + "template_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_builder_session_token_hash_unique": { + "name": "sign_builder_session_token_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "token_hash" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_document": { + "name": "sign_document", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "store_key": { + "name": "store_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "pages": { + "name": "pages", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "anchors": { + "name": "anchors", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_document_environment_created_at_idx": { + "name": "sign_document_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_document_created_at_idx": { + "name": "sign_document_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_document_environment_fk": { + "name": "sign_document_environment_fk", + "tableFrom": "sign_document", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_document_id_organization_unique": { + "name": "sign_document_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_event": { + "name": "sign_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "sign_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "signer_id": { + "name": "signer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor": { + "name": "actor", + "type": "text", + "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 + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "previous_hash": { + "name": "previous_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hash": { + "name": "hash", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "sign_event_request_fk": { + "name": "sign_event_request_fk", + "tableFrom": "sign_event", + "tableTo": "sign_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_event_request_sequence_unique": { + "name": "sign_event_request_sequence_unique", + "nullsNotDistinct": false, + "columns": [ + "request_id", + "sequence" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_fake_object": { + "name": "sign_fake_object", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_fake_object_organization_idx": { + "name": "sign_fake_object_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_field": { + "name": "sign_field", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "signer_id": { + "name": "signer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "document_id": { + "name": "document_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "sign_field_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "page": { + "name": "page", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "x": { + "name": "x", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "y": { + "name": "y", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "width": { + "name": "width", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "required": { + "name": "required", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "anchor": { + "name": "anchor", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefilled": { + "name": "prefilled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_field_request_idx": { + "name": "sign_field_request_idx", + "columns": [ + { + "expression": "request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_field_signer_idx": { + "name": "sign_field_signer_idx", + "columns": [ + { + "expression": "signer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_field_signer_fk": { + "name": "sign_field_signer_fk", + "tableFrom": "sign_field", + "tableTo": "sign_signer", + "columnsFrom": [ + "signer_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "sign_field_request_fk": { + "name": "sign_field_request_fk", + "tableFrom": "sign_field", + "tableTo": "sign_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_request": { + "name": "sign_request", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "sign_request_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signing_order": { + "name": "signing_order", + "type": "sign_signing_order", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'parallel'" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "canceled_at": { + "name": "canceled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "declined_at": { + "name": "declined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "signed_document_key": { + "name": "signed_document_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signed_document_sha256": { + "name": "signed_document_sha256", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sealed_at": { + "name": "sealed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "seal_lease_until": { + "name": "seal_lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "seal_attempts": { + "name": "seal_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "seal_next_attempt_at": { + "name": "seal_next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "seal_error": { + "name": "seal_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reminder_interval_days": { + "name": "reminder_interval_days", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "expired_at": { + "name": "expired_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_request_environment_created_at_idx": { + "name": "sign_request_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_request_expires_at_idx": { + "name": "sign_request_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sign_request\".\"status\" = 'sent'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_request_created_at_idx": { + "name": "sign_request_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_request_unsealed_idx": { + "name": "sign_request_unsealed_idx", + "columns": [ + { + "expression": "completed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sign_request\".\"status\" = 'completed' and \"sign_request\".\"sealed_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_request_environment_fk": { + "name": "sign_request_environment_fk", + "tableFrom": "sign_request", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_request_environment_idempotency_key_unique": { + "name": "sign_request_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + }, + "sign_request_id_organization_unique": { + "name": "sign_request_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_request_document": { + "name": "sign_request_document", + "schema": "", + "columns": { + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "document_id": { + "name": "document_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "sign_request_document_document_idx": { + "name": "sign_request_document_document_idx", + "columns": [ + { + "expression": "document_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_request_document_request_fk": { + "name": "sign_request_document_request_fk", + "tableFrom": "sign_request_document", + "tableTo": "sign_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "sign_request_document_document_fk": { + "name": "sign_request_document_document_fk", + "tableFrom": "sign_request_document", + "tableTo": "sign_document", + "columnsFrom": [ + "document_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "sign_request_document_request_id_position_pk": { + "name": "sign_request_document_request_id_position_pk", + "columns": [ + "request_id", + "position" + ] + } + }, + "uniqueConstraints": { + "sign_request_document_unique": { + "name": "sign_request_document_unique", + "nullsNotDistinct": false, + "columns": [ + "request_id", + "document_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_session": { + "name": "sign_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "signer_id": { + "name": "signer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "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 + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_session_expires_at_idx": { + "name": "sign_session_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_session_signer_idx": { + "name": "sign_session_signer_idx", + "columns": [ + { + "expression": "signer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_session_signer_fk": { + "name": "sign_session_signer_fk", + "tableFrom": "sign_session", + "tableTo": "sign_signer", + "columnsFrom": [ + "signer_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_session_token_hash_unique": { + "name": "sign_session_token_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "token_hash" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_settings": { + "name": "sign_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "allowed_origins": { + "name": "allowed_origins", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "accent_color": { + "name": "accent_color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "theme": { + "name": "theme", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'system'" + }, + "disclosure": { + "name": "disclosure", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_from": { + "name": "email_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reminder_interval_days": { + "name": "reminder_interval_days", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "sign_settings_environment_fk": { + "name": "sign_settings_environment_fk", + "tableFrom": "sign_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_settings_environment_unique": { + "name": "sign_settings_environment_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_signer": { + "name": "sign_signer", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "delivery": { + "name": "delivery", + "type": "sign_delivery", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "authentication": { + "name": "authentication", + "type": "sign_authentication", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "sign_signer_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "client_ref": { + "name": "client_ref", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "viewed_at": { + "name": "viewed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "consented_at": { + "name": "consented_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "signed_at": { + "name": "signed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "declined_at": { + "name": "declined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "decline_reason": { + "name": "decline_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signature_key": { + "name": "signature_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signature_sha256": { + "name": "signature_sha256", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "initials_key": { + "name": "initials_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "initials_sha256": { + "name": "initials_sha256", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notified_at": { + "name": "notified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "reminder_count": { + "name": "reminder_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_reminded_at": { + "name": "last_reminded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_reminder_at": { + "name": "next_reminder_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "remind_requested_at": { + "name": "remind_requested_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "copy_sent_at": { + "name": "copy_sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "email_failures": { + "name": "email_failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "email_retry_at": { + "name": "email_retry_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_signer_request_idx": { + "name": "sign_signer_request_idx", + "columns": [ + { + "expression": "request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "position", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_signer_email_due_idx": { + "name": "sign_signer_email_due_idx", + "columns": [ + { + "expression": "request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sign_signer\".\"delivery\" = 'email' and (\"sign_signer\".\"notified_at\" is null or \"sign_signer\".\"next_reminder_at\" is not null or \"sign_signer\".\"remind_requested_at\" is not null or (\"sign_signer\".\"status\" = 'signed' and \"sign_signer\".\"copy_sent_at\" is null))", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_signer_request_fk": { + "name": "sign_signer_request_fk", + "tableFrom": "sign_signer", + "tableTo": "sign_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_signer_id_organization_unique": { + "name": "sign_signer_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "sign_signer_request_email_unique": { + "name": "sign_signer_request_email_unique", + "nullsNotDistinct": false, + "columns": [ + "request_id", + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_store_cleanup": { + "name": "sign_store_cleanup", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_store_cleanup_next_attempt_at_idx": { + "name": "sign_store_cleanup_next_attempt_at_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_store_cleanup_organization_idx": { + "name": "sign_store_cleanup_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_template": { + "name": "sign_template", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signing_order": { + "name": "signing_order", + "type": "sign_signing_order", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'parallel'" + }, + "roles": { + "name": "roles", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "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": { + "sign_template_environment_created_at_idx": { + "name": "sign_template_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_template_environment_fk": { + "name": "sign_template_environment_fk", + "tableFrom": "sign_template", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_template_id_organization_unique": { + "name": "sign_template_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_template_document": { + "name": "sign_template_document", + "schema": "", + "columns": { + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "document_id": { + "name": "document_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "sign_template_document_document_idx": { + "name": "sign_template_document_document_idx", + "columns": [ + { + "expression": "document_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_template_document_template_fk": { + "name": "sign_template_document_template_fk", + "tableFrom": "sign_template_document", + "tableTo": "sign_template", + "columnsFrom": [ + "template_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "sign_template_document_document_fk": { + "name": "sign_template_document_document_fk", + "tableFrom": "sign_template_document", + "tableTo": "sign_document", + "columnsFrom": [ + "document_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "sign_template_document_template_id_position_pk": { + "name": "sign_template_document_template_id_position_pk", + "columns": [ + "template_id", + "position" + ] + } + }, + "uniqueConstraints": { + "sign_template_document_unique": { + "name": "sign_template_document_unique", + "nullsNotDistinct": false, + "columns": [ + "template_id", + "document_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_template_field": { + "name": "sign_template_field", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "document": { + "name": "document", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "sign_field_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "page": { + "name": "page", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "x": { + "name": "x", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "y": { + "name": "y", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "width": { + "name": "width", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "required": { + "name": "required", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "merge_key": { + "name": "merge_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_template_field_template_idx": { + "name": "sign_template_field_template_idx", + "columns": [ + { + "expression": "template_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_template_field_template_fk": { + "name": "sign_template_field_template_fk", + "tableFrom": "sign_template_field", + "tableTo": "sign_template", + "columnsFrom": [ + "template_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_account": { + "name": "sms_account", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subaccount_sid": { + "name": "subaccount_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auth_token": { + "name": "auth_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "sms_account_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "allowed_countries": { + "name": "allowed_countries", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{US,CA}'::text[]" + }, + "unlocked_countries": { + "name": "unlocked_countries", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "sms_account_organization_id_organization_id_fk": { + "name": "sms_account_organization_id_organization_id_fk", + "tableFrom": "sms_account", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_account_subaccount_sid_unique": { + "name": "sms_account_subaccount_sid_unique", + "nullsNotDistinct": false, + "columns": [ + "subaccount_sid" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_event": { + "name": "sms_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "sms_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_status": { + "name": "provider_status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_event_message_occurred_at_idx": { + "name": "sms_event_message_occurred_at_idx", + "columns": [ + { + "expression": "message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_event_message_fk": { + "name": "sms_event_message_fk", + "tableFrom": "sms_event", + "tableTo": "sms_message", + "columnsFrom": [ + "message_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_event_message_dedupe_unique": { + "name": "sms_event_message_dedupe_unique", + "nullsNotDistinct": false, + "columns": [ + "message_id", + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_inbound_receipt": { + "name": "sms_inbound_receipt", + "schema": "", + "columns": { + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "from_number": { + "name": "from_number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "keyword": { + "name": "keyword", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_inbound_receipt_created_at_idx": { + "name": "sms_inbound_receipt_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_inbound_receipt_organization_created_at_idx": { + "name": "sms_inbound_receipt_organization_created_at_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_inbound_receipt_organization_id_organization_id_fk": { + "name": "sms_inbound_receipt_organization_id_organization_id_fk", + "tableFrom": "sms_inbound_receipt", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "sms_inbound_receipt_provider_provider_message_id_pk": { + "name": "sms_inbound_receipt_provider_provider_message_id_pk", + "columns": [ + "provider", + "provider_message_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_message": { + "name": "sms_message", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_owner_id": { + "name": "api_key_owner_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "sms_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "from": { + "name": "from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to": { + "name": "to", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to_country": { + "name": "to_country", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "number_id": { + "name": "number_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "discard_body": { + "name": "discard_body", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "encoding": { + "name": "encoding", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "segments": { + "name": "segments", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "delivered_at": { + "name": "delivered_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "traceparent": { + "name": "traceparent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_message_environment_created_at_idx": { + "name": "sms_message_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_message_organization_send_time_idx": { + "name": "sms_message_organization_send_time_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"sent_at\", \"created_at\")", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_message_scheduled_due_idx": { + "name": "sms_message_scheduled_due_idx", + "columns": [ + { + "expression": "scheduled_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sms_message\".\"status\" = 'scheduled'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_message_queued_created_at_idx": { + "name": "sms_message_queued_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sms_message\".\"status\" = 'queued'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_message_created_at_idx": { + "name": "sms_message_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_message_environment_fk": { + "name": "sms_message_environment_fk", + "tableFrom": "sms_message", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_message_environment_idempotency_key_unique": { + "name": "sms_message_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + }, + "sms_message_id_organization_unique": { + "name": "sms_message_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_number": { + "name": "sms_number", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "phone_number": { + "name": "phone_number", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "sms_number_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_sid": { + "name": "provider_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "sms_number_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "registration_id": { + "name": "registration_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "receiving_environment_id": { + "name": "receiving_environment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "next_fee_at": { + "name": "next_fee_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_number_organization_idx": { + "name": "sms_number_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_number_next_fee_idx": { + "name": "sms_number_next_fee_idx", + "columns": [ + { + "expression": "next_fee_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sms_number\".\"next_fee_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_number_organization_id_organization_id_fk": { + "name": "sms_number_organization_id_organization_id_fk", + "tableFrom": "sms_number", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_number_phone_number_unique": { + "name": "sms_number_phone_number_unique", + "nullsNotDistinct": false, + "columns": [ + "phone_number" + ] + }, + "sms_number_id_organization_unique": { + "name": "sms_number_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_received": { + "name": "sms_received", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "number_id": { + "name": "number_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "from": { + "name": "from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to": { + "name": "to", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "segments": { + "name": "segments", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "keyword": { + "name": "keyword", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "usage_recorded_at": { + "name": "usage_recorded_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": { + "sms_received_environment_created_at_idx": { + "name": "sms_received_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_received_created_at_idx": { + "name": "sms_received_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_received_environment_fk": { + "name": "sms_received_environment_fk", + "tableFrom": "sms_received", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_received_provider_message_unique": { + "name": "sms_received_provider_message_unique", + "nullsNotDistinct": false, + "columns": [ + "provider", + "provider_message_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_registration": { + "name": "sms_registration", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "sms_registration_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "sms_registration_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "step": { + "name": "step", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "brand_type": { + "name": "brand_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "profile": { + "name": "profile", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "campaign": { + "name": "campaign", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "customer_profile_sid": { + "name": "customer_profile_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "trust_product_sid": { + "name": "trust_product_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "brand_sid": { + "name": "brand_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "messaging_service_sid": { + "name": "messaging_service_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "campaign_sid": { + "name": "campaign_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "toll_free_verification_sid": { + "name": "toll_free_verification_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "number_id": { + "name": "number_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rejection_reason": { + "name": "rejection_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_fee_at": { + "name": "next_fee_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "submitted_at": { + "name": "submitted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "approved_at": { + "name": "approved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_registration_organization_idx": { + "name": "sms_registration_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_registration_next_check_idx": { + "name": "sms_registration_next_check_idx", + "columns": [ + { + "expression": "next_check_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sms_registration\".\"next_check_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_registration_organization_id_organization_id_fk": { + "name": "sms_registration_organization_id_organization_id_fk", + "tableFrom": "sms_registration", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_registration_id_organization_unique": { + "name": "sms_registration_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_suppression": { + "name": "sms_suppression", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "sms_suppression_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "phone_number": { + "name": "phone_number", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "sms_suppression_reason", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_suppression_environment_sequence_idx": { + "name": "sms_suppression_environment_sequence_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_suppression_environment_fk": { + "name": "sms_suppression_environment_fk", + "tableFrom": "sms_suppression", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_suppression_environment_phone_unique": { + "name": "sms_suppression_environment_phone_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "phone_number" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_attachment": { + "name": "support_attachment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "ticket_id": { + "name": "ticket_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploaded_by_user_id": { + "name": "uploaded_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "support_attachment_state", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "source_key": { + "name": "source_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "store_key": { + "name": "store_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_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": { + "support_attachment_message_idx": { + "name": "support_attachment_message_idx", + "columns": [ + { + "expression": "message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_attachment_ticket_idx": { + "name": "support_attachment_ticket_idx", + "columns": [ + { + "expression": "ticket_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_attachment_copy_idx": { + "name": "support_attachment_copy_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_attachment\".\"state\" = 'pending_copy'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_attachment_unclaimed_idx": { + "name": "support_attachment_unclaimed_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_attachment\".\"message_id\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "support_attachment_ticket_id_support_ticket_id_fk": { + "name": "support_attachment_ticket_id_support_ticket_id_fk", + "tableFrom": "support_attachment", + "tableTo": "support_ticket", + "columnsFrom": [ + "ticket_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "support_attachment_message_id_support_message_id_fk": { + "name": "support_attachment_message_id_support_message_id_fk", + "tableFrom": "support_attachment", + "tableTo": "support_message", + "columnsFrom": [ + "message_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "support_attachment_uploaded_by_user_id_user_id_fk": { + "name": "support_attachment_uploaded_by_user_id_user_id_fk", + "tableFrom": "support_attachment", + "tableTo": "user", + "columnsFrom": [ + "uploaded_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_fake_object": { + "name": "support_fake_object", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_intake": { + "name": "support_intake", + "schema": "", + "columns": { + "received_email_id": { + "name": "received_email_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "outcome": { + "name": "outcome", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ticket_id": { + "name": "ticket_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "settled_at": { + "name": "settled_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": { + "support_intake_created_idx": { + "name": "support_intake_created_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_message": { + "name": "support_message", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "ticket_id": { + "name": "ticket_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "support_message_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "event": { + "name": "event", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "event_data": { + "name": "event_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "author_user_id": { + "name": "author_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "author_name": { + "name": "author_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "author_email": { + "name": "author_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "visible_text": { + "name": "visible_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "sender_auth": { + "name": "sender_auth", + "type": "support_sender_auth", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "customer_visible": { + "name": "customer_visible", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "low_signal": { + "name": "low_signal", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "rfc_message_id": { + "name": "rfc_message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "received_email_id": { + "name": "received_email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "delivery_status": { + "name": "delivery_status", + "type": "support_delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "delivery_attempts": { + "name": "delivery_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_delivery_at": { + "name": "next_delivery_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "delivery_error": { + "name": "delivery_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rep_alert_pending": { + "name": "rep_alert_pending", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "support_message_ticket_idx": { + "name": "support_message_ticket_idx", + "columns": [ + { + "expression": "ticket_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_message_rfc_unique": { + "name": "support_message_rfc_unique", + "columns": [ + { + "expression": "ticket_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "rfc_message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"support_message\".\"rfc_message_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_message_rfc_idx": { + "name": "support_message_rfc_idx", + "columns": [ + { + "expression": "rfc_message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_message\".\"rfc_message_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_message_delivery_idx": { + "name": "support_message_delivery_idx", + "columns": [ + { + "expression": "next_delivery_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_message\".\"delivery_status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_message_accepted_idx": { + "name": "support_message_accepted_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_message\".\"delivery_status\" = 'accepted'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_message_alert_idx": { + "name": "support_message_alert_idx", + "columns": [ + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_message\".\"rep_alert_pending\"", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "support_message_ticket_id_support_ticket_id_fk": { + "name": "support_message_ticket_id_support_ticket_id_fk", + "tableFrom": "support_message", + "tableTo": "support_ticket", + "columnsFrom": [ + "ticket_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "support_message_author_user_id_user_id_fk": { + "name": "support_message_author_user_id_user_id_fk", + "tableFrom": "support_message", + "tableTo": "user", + "columnsFrom": [ + "author_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_saved_reply": { + "name": "support_saved_reply", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "support_saved_reply_title_unique": { + "name": "support_saved_reply_title_unique", + "columns": [ + { + "expression": "title", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "support_saved_reply_created_by_user_id_user_id_fk": { + "name": "support_saved_reply_created_by_user_id_user_id_fk", + "tableFrom": "support_saved_reply", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_ticket": { + "name": "support_ticket", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "number": { + "name": "number", + "type": "integer", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "support_ticket_number_seq", + "schema": "public", + "increment": "1", + "startWith": "1001", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "reply_token": { + "name": "reply_token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'other'" + }, + "severity": { + "name": "severity", + "type": "support_severity", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'normal'" + }, + "status": { + "name": "status", + "type": "support_ticket_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'open'" + }, + "source": { + "name": "source", + "type": "support_ticket_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "filter_reason": { + "name": "filter_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_name": { + "name": "organization_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_match": { + "name": "org_match", + "type": "support_org_match", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "suggested_organization_id": { + "name": "suggested_organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requester_user_id": { + "name": "requester_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requester_email": { + "name": "requester_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "requester_name": { + "name": "requester_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sender_auth": { + "name": "sender_auth", + "type": "support_sender_auth", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "cc": { + "name": "cc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "suggested_cc": { + "name": "suggested_cc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "assignee_user_id": { + "name": "assignee_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'free'" + }, + "all_hours": { + "name": "all_hours", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "awaiting_since": { + "name": "awaiting_since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "response_due_at": { + "name": "response_due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "first_responded_at": { + "name": "first_responded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "breached_at": { + "name": "breached_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "risk_alerted_due_at": { + "name": "risk_alerted_due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "breach_alerted_due_at": { + "name": "breach_alerted_due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "snoozed_until": { + "name": "snoozed_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_customer_message_at": { + "name": "last_customer_message_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_agent_message_at": { + "name": "last_agent_message_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_message_at": { + "name": "last_message_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "context": { + "name": "context", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "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": { + "support_ticket_number_unique": { + "name": "support_ticket_number_unique", + "columns": [ + { + "expression": "number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_reply_token_unique": { + "name": "support_ticket_reply_token_unique", + "columns": [ + { + "expression": "reply_token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_queue_idx": { + "name": "support_ticket_queue_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "response_due_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_organization_idx": { + "name": "support_ticket_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "last_message_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_suggested_idx": { + "name": "support_ticket_suggested_idx", + "columns": [ + { + "expression": "suggested_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_requester_idx": { + "name": "support_ticket_requester_idx", + "columns": [ + { + "expression": "requester_email", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_requester_user_idx": { + "name": "support_ticket_requester_user_idx", + "columns": [ + { + "expression": "requester_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_assignee_idx": { + "name": "support_ticket_assignee_idx", + "columns": [ + { + "expression": "assignee_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_snoozed_idx": { + "name": "support_ticket_snoozed_idx", + "columns": [ + { + "expression": "snoozed_until", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_ticket\".\"snoozed_until\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "support_ticket_organization_id_organization_id_fk": { + "name": "support_ticket_organization_id_organization_id_fk", + "tableFrom": "support_ticket", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "support_ticket_suggested_organization_id_organization_id_fk": { + "name": "support_ticket_suggested_organization_id_organization_id_fk", + "tableFrom": "support_ticket", + "tableTo": "organization", + "columnsFrom": [ + "suggested_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "support_ticket_requester_user_id_user_id_fk": { + "name": "support_ticket_requester_user_id_user_id_fk", + "tableFrom": "support_ticket", + "tableTo": "user", + "columnsFrom": [ + "requester_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "support_ticket_assignee_user_id_user_id_fk": { + "name": "support_ticket_assignee_user_id_user_id_fk", + "tableFrom": "support_ticket", + "tableTo": "user", + "columnsFrom": [ + "assignee_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_ticket_read": { + "name": "support_ticket_read", + "schema": "", + "columns": { + "ticket_id": { + "name": "ticket_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "support_ticket_read_unique": { + "name": "support_ticket_read_unique", + "columns": [ + { + "expression": "ticket_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "support_ticket_read_ticket_id_support_ticket_id_fk": { + "name": "support_ticket_read_ticket_id_support_ticket_id_fk", + "tableFrom": "support_ticket_read", + "tableTo": "support_ticket", + "columnsFrom": [ + "ticket_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "support_ticket_read_user_id_user_id_fk": { + "name": "support_ticket_read_user_id_user_id_fk", + "tableFrom": "support_ticket_read", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verify_check": { + "name": "verify_check", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "valid": { + "name": "valid", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "verify_check_request_fk": { + "name": "verify_check_request_fk", + "tableFrom": "verify_check", + "tableTo": "verify_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "verify_check_request_idempotency_key_unique": { + "name": "verify_check_request_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "request_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verify_request": { + "name": "verify_request", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_owner_id": { + "name": "api_key_owner_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "channel": { + "name": "channel", + "type": "verify_channel", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "to": { + "name": "to", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to_country": { + "name": "to_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "verify_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "failure_code": { + "name": "failure_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "risk_reasons": { + "name": "risk_reasons", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "code_hash": { + "name": "code_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "code_length": { + "name": "code_length", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "sends": { + "name": "sends", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "approved_at": { + "name": "approved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "verify_request_environment_created_at_idx": { + "name": "verify_request_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "verify_request_pending_to_idx": { + "name": "verify_request_pending_to_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "to", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "channel", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"verify_request\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "verify_request_created_at_idx": { + "name": "verify_request_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "verify_request_environment_fk": { + "name": "verify_request_environment_fk", + "tableFrom": "verify_request", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "verify_request_environment_idempotency_key_unique": { + "name": "verify_request_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + }, + "verify_request_id_organization_unique": { + "name": "verify_request_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verify_send": { + "name": "verify_send", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "channel": { + "name": "channel", + "type": "verify_channel", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "route": { + "name": "route", + "type": "verify_send_route", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "sms_id": { + "name": "sms_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message_environment_id": { + "name": "message_environment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_owner_id": { + "name": "api_key_owner_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "verify_send_unmetered_idx": { + "name": "verify_send_unmetered_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"verify_send\".\"route\" = 'shared_number' and \"verify_send\".\"usage_recorded_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "verify_send_request_fk": { + "name": "verify_send_request_fk", + "tableFrom": "verify_send", + "tableTo": "verify_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "verify_send_request_sequence_unique": { + "name": "verify_send_request_sequence_unique", + "nullsNotDistinct": false, + "columns": [ + "request_id", + "sequence" + ] + }, + "verify_send_environment_idempotency_key_unique": { + "name": "verify_send_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verify_settings": { + "name": "verify_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "app_name": { + "name": "app_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "code_length": { + "name": "code_length", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 6 + }, + "ttl_seconds": { + "name": "ttl_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 600 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 5 + }, + "sms_from": { + "name": "sms_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_from": { + "name": "email_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "allowed_countries": { + "name": "allowed_countries", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{US,CA}'::text[]" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "verify_settings_environment_fk": { + "name": "verify_settings_environment_fk", + "tableFrom": "verify_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "verify_settings_environment_unique": { + "name": "verify_settings_environment_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.billing_account_status": { + "name": "billing_account_status", + "schema": "public", + "values": [ + "active", + "past_due", + "delinquent" + ] + }, + "public.billing_budget_scope": { + "name": "billing_budget_scope", + "schema": "public", + "values": [ + "member_default", + "user", + "project", + "api_key" + ] + }, + "public.billing_collection_method": { + "name": "billing_collection_method", + "schema": "public", + "values": [ + "charge_automatically", + "send_invoice" + ] + }, + "public.billing_contract_kind": { + "name": "billing_contract_kind", + "schema": "public", + "values": [ + "self_serve", + "sales", + "internal" + ] + }, + "public.billing_contract_status": { + "name": "billing_contract_status", + "schema": "public", + "values": [ + "pending", + "confirmed", + "canceled" + ] + }, + "public.billing_credit_entry_kind": { + "name": "billing_credit_entry_kind", + "schema": "public", + "values": [ + "applied", + "reversed", + "voided", + "rolled_over" + ] + }, + "public.billing_credit_note_status": { + "name": "billing_credit_note_status", + "schema": "public", + "values": [ + "pending", + "issued", + "failed" + ] + }, + "public.billing_grant_applies_to": { + "name": "billing_grant_applies_to", + "schema": "public", + "values": [ + "usage", + "any" + ] + }, + "public.billing_grant_kind": { + "name": "billing_grant_kind", + "schema": "public", + "values": [ + "amount", + "units" + ] + }, + "public.billing_grant_source": { + "name": "billing_grant_source", + "schema": "public", + "values": [ + "fee", + "commitment", + "support", + "promotion", + "refund", + "sla" + ] + }, + "public.billing_hold_reason": { + "name": "billing_hold_reason", + "schema": "public", + "values": [ + "delinquent", + "spend_limit", + "admin" + ] + }, + "public.billing_invoice_kind": { + "name": "billing_invoice_kind", + "schema": "public", + "values": [ + "period", + "plan_change", + "one_off", + "final" + ] + }, + "public.billing_invoice_status": { + "name": "billing_invoice_status", + "schema": "public", + "values": [ + "draft", + "open", + "paid", + "void", + "uncollectible" + ] + }, + "public.billing_line_kind": { + "name": "billing_line_kind", + "schema": "public", + "values": [ + "plan_fee", + "proration", + "usage", + "credit", + "discount", + "commitment_fee", + "commitment_shortfall", + "add_on", + "adjustment", + "write_off" + ] + }, + "public.billing_notification_status": { + "name": "billing_notification_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.billing_provider": { + "name": "billing_provider", + "schema": "public", + "values": [ + "fake", + "stripe", + "manual" + ] + }, + "public.billing_provider_event_status": { + "name": "billing_provider_event_status", + "schema": "public", + "values": [ + "pending", + "processed", + "ignored", + "failed" + ] + }, + "public.billing_sync_action": { + "name": "billing_sync_action", + "schema": "public", + "values": [ + "push", + "collect", + "void", + "mark_uncollectible" + ] + }, + "public.billing_tax_mode": { + "name": "billing_tax_mode", + "schema": "public", + "values": [ + "none", + "stripe_automatic" + ] + }, + "public.api_key_access": { + "name": "api_key_access", + "schema": "public", + "values": [ + "full", + "restricted" + ] + }, + "public.auth_email_kind": { + "name": "auth_email_kind", + "schema": "public", + "values": [ + "verify_email", + "reset_password", + "invitation" + ] + }, + "public.auth_email_status": { + "name": "auth_email_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.broadcast_screening_status": { + "name": "broadcast_screening_status", + "schema": "public", + "values": [ + "pending", + "passed", + "held", + "blocked" + ] + }, + "public.broadcast_status": { + "name": "broadcast_status", + "schema": "public", + "values": [ + "draft", + "scheduled", + "sending", + "paused", + "sent", + "canceled", + "failed" + ] + }, + "public.contact_property_type": { + "name": "contact_property_type", + "schema": "public", + "values": [ + "string", + "number", + "boolean", + "date" + ] + }, + "public.contact_source": { + "name": "contact_source", + "schema": "public", + "values": [ + "api", + "dashboard", + "import", + "preference_center", + "form" + ] + }, + "public.contact_status": { + "name": "contact_status", + "schema": "public", + "values": [ + "subscribed", + "unsubscribed", + "pending" + ] + }, + "public.contact_topic_status": { + "name": "contact_topic_status", + "schema": "public", + "values": [ + "opted_in", + "opted_out" + ] + }, + "public.content_screening_verdict": { + "name": "content_screening_verdict", + "schema": "public", + "values": [ + "clean", + "flagged", + "blocked", + "error" + ] + }, + "public.dedicated_ip_pool_status": { + "name": "dedicated_ip_pool_status", + "schema": "public", + "values": [ + "waiting", + "provisioning", + "warming", + "ready", + "releasing" + ] + }, + "public.dmarc_notification_kind": { + "name": "dmarc_notification_kind", + "schema": "public", + "values": [ + "ready_quarantine", + "ready_reject", + "pass_rate_dropped" + ] + }, + "public.dmarc_notification_status": { + "name": "dmarc_notification_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.domain_status": { + "name": "domain_status", + "schema": "public", + "values": [ + "pending", + "verified", + "temporary_failure", + "failed", + "deleting" + ] + }, + "public.email_event_type": { + "name": "email_event_type", + "schema": "public", + "values": [ + "email.sent", + "email.delivered", + "email.delivery_delayed", + "email.bounced", + "email.complained", + "email.failed", + "email.suppressed", + "email.scheduled", + "email.canceled", + "email.opened", + "email.clicked", + "email.rescheduled", + "email.unsubscribed" + ] + }, + "public.email_recipient_kind": { + "name": "email_recipient_kind", + "schema": "public", + "values": [ + "to", + "cc", + "bcc" + ] + }, + "public.email_recipient_status": { + "name": "email_recipient_status", + "schema": "public", + "values": [ + "queued", + "sent", + "delivery_delayed", + "delivered", + "bounced", + "suppressed", + "complained", + "failed", + "canceled" + ] + }, + "public.email_status": { + "name": "email_status", + "schema": "public", + "values": [ + "queued", + "sent", + "failed", + "scheduled", + "canceled" + ] + }, + "public.email_stream": { + "name": "email_stream", + "schema": "public", + "values": [ + "transactional", + "marketing" + ] + }, + "public.email_subaccount_reputation": { + "name": "email_subaccount_reputation", + "schema": "public", + "values": [ + "good", + "warning", + "paused" + ] + }, + "public.email_subaccount_status": { + "name": "email_subaccount_status", + "schema": "public", + "values": [ + "active", + "disabled", + "deleting" + ] + }, + "public.email_suppression_reason": { + "name": "email_suppression_reason", + "schema": "public", + "values": [ + "bounce", + "complaint", + "manual", + "import", + "unsubscribe" + ] + }, + "public.environment_mode": { + "name": "environment_mode", + "schema": "public", + "values": [ + "live", + "sandbox" + ] + }, + "public.hook_delivery_status": { + "name": "hook_delivery_status", + "schema": "public", + "values": [ + "pending", + "succeeded", + "failed" + ] + }, + "public.hook_recovery_status": { + "name": "hook_recovery_status", + "schema": "public", + "values": [ + "pending", + "completed" + ] + }, + "public.log_drain_batch_status": { + "name": "log_drain_batch_status", + "schema": "public", + "values": [ + "pending", + "succeeded", + "failed" + ] + }, + "public.log_drain_format": { + "name": "log_drain_format", + "schema": "public", + "values": [ + "ndjson", + "loki", + "datadog", + "otlp" + ] + }, + "public.log_drain_source": { + "name": "log_drain_source", + "schema": "public", + "values": [ + "api", + "email", + "webhook", + "risk", + "audit", + "smtp", + "sms", + "sign", + "verify", + "forms", + "scheduling" + ] + }, + "public.log_level": { + "name": "log_level", + "schema": "public", + "values": [ + "info", + "warning", + "error" + ] + }, + "public.log_source": { + "name": "log_source", + "schema": "public", + "values": [ + "api", + "email", + "webhook", + "risk", + "smtp", + "sms", + "sign", + "verify", + "forms", + "scheduling" + ] + }, + "public.mail_from_status": { + "name": "mail_from_status", + "schema": "public", + "values": [ + "pending", + "success", + "temporary_failure", + "failed" + ] + }, + "public.migration_item_kind": { + "name": "migration_item_kind", + "schema": "public", + "values": [ + "domain", + "property", + "topic", + "audience", + "template", + "webhook_endpoint" + ] + }, + "public.migration_item_outcome": { + "name": "migration_item_outcome", + "schema": "public", + "values": [ + "pending", + "created", + "existing", + "skipped", + "failed" + ] + }, + "public.migration_provider": { + "name": "migration_provider", + "schema": "public", + "values": [ + "resend", + "sendgrid", + "postmark" + ] + }, + "public.migration_status": { + "name": "migration_status", + "schema": "public", + "values": [ + "inspecting", + "ready", + "queued", + "running", + "completed", + "failed", + "canceled" + ] + }, + "public.org_audit_actor_type": { + "name": "org_audit_actor_type", + "schema": "public", + "values": [ + "user", + "api_key", + "system" + ] + }, + "public.organization_deletion_status": { + "name": "organization_deletion_status", + "schema": "public", + "values": [ + "pending", + "completed" + ] + }, + "public.organization_logo_status": { + "name": "organization_logo_status", + "schema": "public", + "values": [ + "found", + "not_found", + "hidden" + ] + }, + "public.received_email_status": { + "name": "received_email_status", + "schema": "public", + "values": [ + "received", + "blocked" + ] + }, + "public.reputation_actor": { + "name": "reputation_actor", + "schema": "public", + "values": [ + "system", + "admin" + ] + }, + "public.reputation_event_type": { + "name": "reputation_event_type", + "schema": "public", + "values": [ + "warning_raised", + "warning_cleared", + "suspended", + "reinstated", + "policy_updated", + "marketing_paused", + "marketing_reinstated" + ] + }, + "public.reputation_notification_status": { + "name": "reputation_notification_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.reputation_status": { + "name": "reputation_status", + "schema": "public", + "values": [ + "good", + "warning", + "suspended" + ] + }, + "public.risk_captcha_provider": { + "name": "risk_captcha_provider", + "schema": "public", + "values": [ + "turnstile", + "hcaptcha" + ] + }, + "public.risk_decision": { + "name": "risk_decision", + "schema": "public", + "values": [ + "allow", + "review", + "block" + ] + }, + "public.risk_event": { + "name": "risk_event", + "schema": "public", + "values": [ + "signup", + "login", + "message", + "checkout", + "custom" + ] + }, + "public.risk_feedback_source": { + "name": "risk_feedback_source", + "schema": "public", + "values": [ + "api", + "dashboard" + ] + }, + "public.risk_identity_kind": { + "name": "risk_identity_kind", + "schema": "public", + "values": [ + "mailbox", + "device" + ] + }, + "public.risk_limit_failure_mode": { + "name": "risk_limit_failure_mode", + "schema": "public", + "values": [ + "allow", + "deny" + ] + }, + "public.risk_list": { + "name": "risk_list", + "schema": "public", + "values": [ + "allow", + "block" + ] + }, + "public.risk_list_entry_type": { + "name": "risk_list_entry_type", + "schema": "public", + "values": [ + "email", + "domain", + "ip", + "asn", + "country", + "user" + ] + }, + "public.risk_outcome": { + "name": "risk_outcome", + "schema": "public", + "values": [ + "legitimate", + "fraud", + "abuse" + ] + }, + "public.risk_report_kind": { + "name": "risk_report_kind", + "schema": "public", + "values": [ + "mailbox", + "ip", + "subnet", + "user", + "card", + "device" + ] + }, + "public.risk_review_status": { + "name": "risk_review_status", + "schema": "public", + "values": [ + "open", + "resolved" + ] + }, + "public.risk_rule_match": { + "name": "risk_rule_match", + "schema": "public", + "values": [ + "all", + "any" + ] + }, + "public.risk_user_network_kind": { + "name": "risk_user_network_kind", + "schema": "public", + "values": [ + "country", + "asn" + ] + }, + "public.tenant_sending_status": { + "name": "tenant_sending_status", + "schema": "public", + "values": [ + "enabled", + "disabled", + "reinstated" + ] + }, + "public.topic_default_subscription": { + "name": "topic_default_subscription", + "schema": "public", + "values": [ + "opt_in", + "opt_out" + ] + }, + "public.topic_visibility": { + "name": "topic_visibility", + "schema": "public", + "values": [ + "public", + "private" + ] + }, + "public.tracking_domain_status": { + "name": "tracking_domain_status", + "schema": "public", + "values": [ + "pending", + "active", + "temporary_failure", + "failed", + "deleting" + ] + }, + "public.webhook_delivery_status": { + "name": "webhook_delivery_status", + "schema": "public", + "values": [ + "pending", + "succeeded", + "failed" + ] + }, + "public.form_captcha": { + "name": "form_captcha", + "schema": "public", + "values": [ + "off", + "required" + ] + }, + "public.form_delivery_kind": { + "name": "form_delivery_kind", + "schema": "public", + "values": [ + "notification", + "contact", + "verification" + ] + }, + "public.form_delivery_state": { + "name": "form_delivery_state", + "schema": "public", + "values": [ + "pending", + "delivered", + "failed", + "skipped" + ] + }, + "public.form_on_review": { + "name": "form_on_review", + "schema": "public", + "values": [ + "deliver", + "hold" + ] + }, + "public.form_spam_reason": { + "name": "form_spam_reason", + "schema": "public", + "values": [ + "honeypot", + "risk_block", + "risk_review", + "content" + ] + }, + "public.form_submission_status": { + "name": "form_submission_status", + "schema": "public", + "values": [ + "pending_confirmation", + "accepted", + "held", + "spam" + ] + }, + "public.inbox_kind": { + "name": "inbox_kind", + "schema": "public", + "values": [ + "managed", + "domain" + ] + }, + "public.inbox_message_direction": { + "name": "inbox_message_direction", + "schema": "public", + "values": [ + "inbound", + "outbound" + ] + }, + "public.notification_status": { + "name": "notification_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.apns_environment": { + "name": "apns_environment", + "schema": "public", + "values": [ + "production", + "sandbox" + ] + }, + "public.push_notification_kind": { + "name": "push_notification_kind", + "schema": "public", + "values": [ + "reputation_warning", + "reputation_suspended", + "billing_payment_failed", + "billing_hold_placed", + "billing_budget_paused", + "webhook_endpoint_disabled", + "hook_endpoint_disabled", + "log_drain_disabled", + "risk_review" + ] + }, + "public.push_notification_status": { + "name": "push_notification_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.scheduling_booking_status": { + "name": "scheduling_booking_status", + "schema": "public", + "values": [ + "held", + "pending_approval", + "confirmed", + "cancelled", + "declined" + ] + }, + "public.scheduling_calendar_event_state": { + "name": "scheduling_calendar_event_state", + "schema": "public", + "values": [ + "present", + "absent" + ] + }, + "public.scheduling_calendar_failure_mode": { + "name": "scheduling_calendar_failure_mode", + "schema": "public", + "values": [ + "hide", + "last_known" + ] + }, + "public.scheduling_calendar_provider": { + "name": "scheduling_calendar_provider", + "schema": "public", + "values": [ + "google", + "microsoft", + "caldav", + "simulated", + "zoom" + ] + }, + "public.scheduling_connection_status": { + "name": "scheduling_connection_status", + "schema": "public", + "values": [ + "active", + "needs_reauth" + ] + }, + "public.scheduling_event_type_kind": { + "name": "scheduling_event_type_kind", + "schema": "public", + "values": [ + "one_on_one", + "pool", + "collective", + "group" + ] + }, + "public.scheduling_event_type_status": { + "name": "scheduling_event_type_status", + "schema": "public", + "values": [ + "active", + "archived" + ] + }, + "public.scheduling_external_state": { + "name": "scheduling_external_state", + "schema": "public", + "values": [ + "in_sync", + "moved", + "deleted" + ] + }, + "public.scheduling_host_role": { + "name": "scheduling_host_role", + "schema": "public", + "values": [ + "required", + "member" + ] + }, + "public.scheduling_host_status": { + "name": "scheduling_host_status", + "schema": "public", + "values": [ + "active", + "disabled" + ] + }, + "public.scheduling_notification_channel": { + "name": "scheduling_notification_channel", + "schema": "public", + "values": [ + "email", + "sms" + ] + }, + "public.scheduling_notification_recipient": { + "name": "scheduling_notification_recipient", + "schema": "public", + "values": [ + "attendee", + "host" + ] + }, + "public.scheduling_session_kind": { + "name": "scheduling_session_kind", + "schema": "public", + "values": [ + "host", + "booker", + "manage" + ] + }, + "public.sign_authentication": { + "name": "sign_authentication", + "schema": "public", + "values": [ + "email_link", + "customer_asserted" + ] + }, + "public.sign_delivery": { + "name": "sign_delivery", + "schema": "public", + "values": [ + "embedded", + "email" + ] + }, + "public.sign_event_type": { + "name": "sign_event_type", + "schema": "public", + "values": [ + "created", + "sent", + "notified", + "viewed", + "consented", + "signed", + "declined", + "reminded", + "canceled", + "expired", + "completed", + "sealed" + ] + }, + "public.sign_field_type": { + "name": "sign_field_type", + "schema": "public", + "values": [ + "signature", + "initials", + "date_signed", + "name", + "email", + "text", + "checkbox" + ] + }, + "public.sign_request_status": { + "name": "sign_request_status", + "schema": "public", + "values": [ + "draft", + "sent", + "completed", + "declined", + "canceled", + "expired" + ] + }, + "public.sign_signer_status": { + "name": "sign_signer_status", + "schema": "public", + "values": [ + "pending", + "notified", + "viewed", + "signed", + "declined" + ] + }, + "public.sign_signing_order": { + "name": "sign_signing_order", + "schema": "public", + "values": [ + "parallel", + "sequential" + ] + }, + "public.sms_account_status": { + "name": "sms_account_status", + "schema": "public", + "values": [ + "active", + "closing", + "closed" + ] + }, + "public.sms_event_type": { + "name": "sms_event_type", + "schema": "public", + "values": [ + "sms.scheduled", + "sms.sent", + "sms.delivered", + "sms.undelivered", + "sms.failed", + "sms.suppressed", + "sms.canceled" + ] + }, + "public.sms_number_kind": { + "name": "sms_number_kind", + "schema": "public", + "values": [ + "local", + "toll_free" + ] + }, + "public.sms_number_status": { + "name": "sms_number_status", + "schema": "public", + "values": [ + "pending", + "active", + "releasing" + ] + }, + "public.sms_registration_kind": { + "name": "sms_registration_kind", + "schema": "public", + "values": [ + "us_10dlc", + "toll_free" + ] + }, + "public.sms_registration_status": { + "name": "sms_registration_status", + "schema": "public", + "values": [ + "draft", + "submitted", + "in_review", + "approved", + "rejected", + "failed" + ] + }, + "public.sms_status": { + "name": "sms_status", + "schema": "public", + "values": [ + "queued", + "scheduled", + "sent", + "delivered", + "undelivered", + "failed", + "canceled" + ] + }, + "public.sms_suppression_reason": { + "name": "sms_suppression_reason", + "schema": "public", + "values": [ + "opt_out", + "manual", + "invalid_number" + ] + }, + "public.support_attachment_state": { + "name": "support_attachment_state", + "schema": "public", + "values": [ + "uploaded", + "pending_copy", + "stored", + "failed" + ] + }, + "public.support_delivery_status": { + "name": "support_delivery_status", + "schema": "public", + "values": [ + "pending", + "accepted", + "delivered", + "bounced", + "failed" + ] + }, + "public.support_message_kind": { + "name": "support_message_kind", + "schema": "public", + "values": [ + "customer", + "agent", + "note", + "event" + ] + }, + "public.support_org_match": { + "name": "support_org_match", + "schema": "public", + "values": [ + "session", + "email", + "manual" + ] + }, + "public.support_sender_auth": { + "name": "support_sender_auth", + "schema": "public", + "values": [ + "session", + "dmarc_pass", + "unverified" + ] + }, + "public.support_severity": { + "name": "support_severity", + "schema": "public", + "values": [ + "normal", + "urgent" + ] + }, + "public.support_ticket_source": { + "name": "support_ticket_source", + "schema": "public", + "values": [ + "email", + "dashboard" + ] + }, + "public.support_ticket_status": { + "name": "support_ticket_status", + "schema": "public", + "values": [ + "open", + "pending", + "snoozed", + "resolved", + "spam" + ] + }, + "public.verify_channel": { + "name": "verify_channel", + "schema": "public", + "values": [ + "sms", + "email" + ] + }, + "public.verify_send_route": { + "name": "verify_send_route", + "schema": "public", + "values": [ + "own_number", + "shared_number", + "email", + "coss_email" + ] + }, + "public.verify_status": { + "name": "verify_status", + "schema": "public", + "values": [ + "pending", + "approved", + "expired", + "canceled", + "failed", + "blocked" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/db/migrations/meta/_journal.json b/packages/db/migrations/meta/_journal.json index 9c6d55886..01e12b5f1 100644 --- a/packages/db/migrations/meta/_journal.json +++ b/packages/db/migrations/meta/_journal.json @@ -883,6 +883,13 @@ "when": 1793760054282, "tag": "0125_scheduling_unassign_filter_hosts", "breakpoints": true + }, + { + "idx": 126, + "version": "7", + "when": 1793813887482, + "tag": "0126_tidy_marauders", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/db/src/schema/scheduling.ts b/packages/db/src/schema/scheduling.ts index 31a2091b3..e76a58743 100644 --- a/packages/db/src/schema/scheduling.ts +++ b/packages/db/src/schema/scheduling.ts @@ -766,6 +766,8 @@ export const schedulingCalendarEvent = pgTable( desiredVersion: integer("desired_version").notNull().default(1), appliedVersion: integer("applied_version").notNull().default(0), providerEventId: text("provider_event_id"), + // Goes up each time the event is deleted, so one that comes back gets a key not yet used. + keyGeneration: integer("key_generation").notNull().default(0), externalState: schedulingExternalState("external_state").notNull().default("in_sync"), nextAttemptAt: instant("next_attempt_at").notNull().defaultNow(), leaseUntil: instant("lease_until"), diff --git a/packages/scheduling/AGENTS.md b/packages/scheduling/AGENTS.md index 51d553d5d..f21f58f7a 100644 --- a/packages/scheduling/AGENTS.md +++ b/packages/scheduling/AGENTS.md @@ -105,9 +105,18 @@ embeds the booker. Local dates (overrides, limits) never pass through `Date`. idle ones alive. `notZoomMeeting()` keeps these rows out of what's subtracted from busy times. Losing Zoom never hides a host. The app's deauthorization event comes to `POST /scheduling/zoom/events`. -A Meet or Teams link becomes a `link` location on the booking, stored with `conference` (stripped from the wire), so a -new host gets a meeting of their own (`locationForNewHost`). A browser only chooses among an event type's `locations` -(`locationFromBrowser`): it can't supply its own link or address. +A Meet or Teams link becomes a `link` location on the booking, stored with `conference` and `conference_host_id` (both +stripped from the wire), so when a host leaves, the link only resets if the meeting was theirs (`locationWithoutHost`). +A Zoom meeting's owner is its ledger row (`meetingOwnerOf`), and it keeps running the meeting however hosts sort. Links +older than `conference_host_id` have no known owner, so they reset. Co-hosts each ask for a Meet at creation, and only +the first answer becomes the booking's link: a co-host's event can hold its own unused conference, though its location +text is rewritten to the booking's. A browser only chooses among an event type's `locations` (`locationFromBrowser`): +it can't supply its own link or address. + +A booking's ledger row can come back when a host leaves and returns, and its `key_generation` makes a key not yet used +(`eventKey`). Removing an event (`setCalendarState` with `absent`) goes by the ledger's rows, not today's write target, +so an event on a calendar that's stopped being one still goes. Slots for moving a booking come from the hosts it has +(`listBookingSlots`), never `candidatesOf`, which answers who'd take a new one. ## Sessions and the client API diff --git a/packages/scheduling/src/availability.ts b/packages/scheduling/src/availability.ts index 332038b33..9a118fa90 100644 --- a/packages/scheduling/src/availability.ts +++ b/packages/scheduling/src/availability.ts @@ -22,6 +22,8 @@ import { MAX_SLOT_WINDOW_DAYS } from "./schemas.ts"; import type { SchedulingEnvironment } from "./types.ts"; const { + schedulingBooking, + schedulingBookingHost, schedulingBusyInterval, schedulingCalendar, schedulingCalendarConnection, @@ -522,6 +524,74 @@ export async function listEventTypeSlots( hostRefs: input.hostRefs, attributes: input.attributes, }); + return slotsAmong(scope, eventType, candidates, input, duration); +} + +/** + * Where a booking could move, keeping its hosts: not who the event type would pick today. Filters + * and hosts change after a booking is made, and moving one never changes who it's with. + */ +export async function listBookingSlots( + scope: Scope, + input: { bookingId: string; fromMs: number; toMs: number; nowMs: number }, +): Promise { + checkWindow(input.fromMs, input.toMs); + const [booking] = await db + .select() + .from(schedulingBooking) + .where( + and( + eq(schedulingBooking.id, input.bookingId), + eq(schedulingBooking.organizationId, scope.organizationId), + eq(schedulingBooking.environmentId, scope.environmentId), + ), + ); + if (!booking) return []; + const eventType = await resolveEventType(db, scope, booking.eventTypeId); + if (eventType.status !== "active") return []; + const assigned = await db + .select({ hostId: schedulingBookingHost.hostId, role: schedulingBookingHost.role }) + .from(schedulingBookingHost) + .where( + and( + eq(schedulingBookingHost.bookingId, booking.id), + eq(schedulingBookingHost.organizationId, scope.organizationId), + ), + ); + const [hosts, memberships] = await Promise.all([ + hostsByIds( + db, + scope, + assigned.map((row) => row.hostId), + ), + eventTypeHosts(db, eventType), + ]); + const byHost = new Map(memberships.map((row) => [row.hostId, row])); + // As booking refuses them: a slot here would only fail on the way in. + const movable = + assigned.length > 0 && + hosts.length === assigned.length && + hosts.every((host) => host.status === "active" && !byHost.get(host.id)?.removedAt); + if (!movable) return []; + const entryOf = (role: "required" | "member") => + assigned + .filter((row) => row.role === role) + .flatMap((row) => { + const host = hosts.find((candidate) => candidate.id === row.hostId); + return host ? [{ host, membership: byHost.get(host.id) ?? null }] : []; + }); + const candidates = { required: entryOf("required"), members: entryOf("member") } as Candidates; + const duration = (booking.endAt.getTime() - booking.startAt.getTime()) / MINUTE_MS; + return slotsAmong(scope, eventType, candidates, input, duration); +} + +async function slotsAmong( + scope: Scope, + eventType: EventTypeRow, + candidates: Candidates, + input: { fromMs: number; toMs: number; nowMs: number }, + duration: number, +): Promise { const all = [...candidates.required, ...candidates.members]; const loaded = await loadHostInputs(db, { scope, diff --git a/packages/scheduling/src/bookings.ts b/packages/scheduling/src/bookings.ts index b5a149150..ee5fd313b 100644 --- a/packages/scheduling/src/bookings.ts +++ b/packages/scheduling/src/bookings.ts @@ -181,12 +181,46 @@ function locationForNewHost(location: BookingRow["location"]): BookingRow["locat function wireLocation(location: BookingRow["location"]): BookingRow["location"] { if (!location || !("conference" in location)) return location ?? null; - const { conference: _conference, ...rest } = location as typeof location & { - conference: string; - }; + const { + conference: _conference, + conference_host_id: _conferenceHost, + ...rest + } = location as typeof location & { conference: string; conference_host_id?: string }; return rest as BookingRow["location"]; } +/** Whose account runs a booking's meeting, when that's known: older Meet and Teams links don't say. */ +async function meetingOwnerOf(tx: Executor, booking: BookingRow): Promise { + const location = booking.location; + if (location?.type === "link" && "conference_host_id" in location) { + return location.conference_host_id as string; + } + if (location?.type !== "zoom") return null; + const [row] = await tx + .select({ hostId: schedulingCalendarEvent.hostId }) + .from(schedulingCalendarEvent) + .innerJoin(schedulingCalendar, eq(schedulingCalendar.id, schedulingCalendarEvent.calendarId)) + .where( + and( + eq(schedulingCalendarEvent.bookingId, booking.id), + eq(schedulingCalendarEvent.organizationId, booking.organizationId), + eq(schedulingCalendarEvent.desiredState, "present"), + eq(schedulingCalendar.externalId, ZOOM_CALENDAR_ID), + ), + ); + return row?.hostId ?? null; +} + +/** The location once a host leaves, or null if it stands: the meeting may be someone else's. */ +async function locationWithoutHost( + tx: Executor, + booking: BookingRow, + hostId: string, +): Promise { + const owner = await meetingOwnerOf(tx, booking); + return owner && owner !== hostId ? null : locationForNewHost(booking.location); +} + function chooseLocation( eventType: EventTypeRow, wanted: Location | undefined, @@ -677,6 +711,29 @@ async function setCalendarState( state: "present" | "absent", ): Promise { if (hostIds.length === 0) return; + const sessionId = booking.groupSessionId; + if (state === "absent") { + // Whatever these hosts' events are on now, which may not be where they'd be written today. + await tx + .update(schedulingCalendarEvent) + .set({ + desiredState: "absent", + desiredVersion: sql`${schedulingCalendarEvent.desiredVersion} + 1`, + nextAttemptAt: sql`clock_timestamp()`, + attempts: 0, + }) + .where( + and( + sessionId + ? eq(schedulingCalendarEvent.groupSessionId, sessionId) + : eq(schedulingCalendarEvent.bookingId, booking.id), + eq(schedulingCalendarEvent.organizationId, booking.organizationId), + inArray(schedulingCalendarEvent.hostId, [...hostIds]), + eq(schedulingCalendarEvent.desiredState, "present"), + ), + ); + return; + } const calendars = await tx .select({ id: schedulingCalendar.id, @@ -703,14 +760,12 @@ async function setCalendarState( .orderBy(asc(schedulingCalendar.hostId)); const targets = calendars.filter((calendar) => calendar.writeTarget); if (booking.location?.type === "zoom") { - // One meeting however many hosts there are: the first with Zoom connected runs it. - const meeting = calendars.find((calendar) => calendar.externalId === ZOOM_CALENDAR_ID); + // One meeting however many hosts there are: whoever runs it now, or the first with Zoom connected. + const zooms = calendars.filter((calendar) => calendar.externalId === ZOOM_CALENDAR_ID); + const owner = await meetingOwnerOf(tx, booking); + const meeting = zooms.find((calendar) => calendar.hostId === owner) ?? zooms[0]; if (meeting) targets.push(meeting); - else if ( - state === "present" && - !booking.location.url && - !targets.some((target) => target.provider === "simulated") - ) { + else if (!booking.location.url && !targets.some((target) => target.provider === "simulated")) { await announce( tx, booking, @@ -720,9 +775,8 @@ async function setCalendarState( ); } } - const sessionId = booking.groupSessionId; // A session can come back after its event went, and a provider's key doesn't work twice. - if (sessionId && state === "present") { + if (sessionId) { await tx .delete(schedulingCalendarEvent) .where( @@ -1970,12 +2024,13 @@ export async function rescheduleBooking( }) .onConflictDoNothing(); } - const newLocation = replacement ? locationForNewHost(booking.location) : null; + // The old host's meeting goes with them, so someone else's gets a new link. + const newLocation = + replacement && member ? await locationWithoutHost(tx, booking, member.hostId) : null; const updated = await bumped(tx, booking, { startAt: new Date(input.startMs), endAt: new Date(input.startMs + durationMinutes * MINUTE_MS), externalConflictAt: null, - // The old host's meeting goes with them, so the new host's gets a new link. ...(newLocation ? { location: newLocation } : {}), }); const after = await participants(tx, updated); diff --git a/packages/scheduling/src/calendar/writes.ts b/packages/scheduling/src/calendar/writes.ts index e505d7a0d..27385f5a4 100644 --- a/packages/scheduling/src/calendar/writes.ts +++ b/packages/scheduling/src/calendar/writes.ts @@ -94,9 +94,17 @@ async function renewLease(row: LedgerRow, now: Date): Promise return renewed ?? null; } -// A session's event can go and come back, as a new row, while a booking's key lasts for good. +/** + * A session's event can go and come back, as a new row. A booking's row comes back itself when a + * host leaves and returns, so its generation makes a key not yet used: Graph's answer to a repeated + * `transactionId` is undocumented, and it could be the deleted event. It goes first because Meet's + * `requestId` is the key's first 64 characters, and a new event needs a new one of those too. + */ const eventKey = (row: LedgerRow) => - (row.groupSessionId ? row.id : `${row.bookingId}-${row.calendarId}`).replace(/[^a-z0-9_-]/gi, ""); + (row.groupSessionId + ? row.id + : `${row.keyGeneration > 0 ? `g${row.keyGeneration}-` : ""}${row.bookingId}-${row.calendarId}` + ).replace(/[^a-z0-9_-]/gi, ""); type Location = BookingRow["location"]; @@ -200,10 +208,15 @@ async function setMeetingLink( const [updated] = await tx .update(schedulingBooking) .set({ - // Remembers where the link came from, for when another host takes the booking. + // Remembers where the link came from and whose it is, for when hosts change. location: zoom ? { type: "zoom", url } - : ({ type: "link", url, conference: location.type } as never), + : ({ + type: "link", + url, + conference: location.type, + conference_host_id: hostId, + } as never), version: sql`${schedulingBooking.version} + 1`, }) .where( @@ -215,24 +228,23 @@ async function setMeetingLink( .returning(); if (!updated) return; await carryReminders(tx, updated); - // The host's calendar event went out without the link. - if (zoom) { - await tx - .update(schedulingCalendarEvent) - .set({ - desiredVersion: sql`${schedulingCalendarEvent.desiredVersion} + 1`, - nextAttemptAt: now, - attempts: 0, - }) - .where( - and( - eq(schedulingCalendarEvent.bookingId, booking.id), - eq(schedulingCalendarEvent.organizationId, booking.organizationId), - eq(schedulingCalendarEvent.desiredState, "present"), - notZoomMeeting(), - ), - ); - } + // Other events went out without the link. A Meet's own event already shows it. + await tx + .update(schedulingCalendarEvent) + .set({ + desiredVersion: sql`${schedulingCalendarEvent.desiredVersion} + 1`, + nextAttemptAt: now, + attempts: 0, + }) + .where( + and( + eq(schedulingCalendarEvent.bookingId, booking.id), + eq(schedulingCalendarEvent.organizationId, booking.organizationId), + eq(schedulingCalendarEvent.desiredState, "present"), + notZoomMeeting(), + zoom ? undefined : ne(schedulingCalendarEvent.hostId, hostId), + ), + ); await announce(tx, updated, "scheduling.booking.location_ready", "Meeting link ready", now); }); } @@ -398,6 +410,7 @@ async function writeOne(claimed: LedgerRow, deps: CalendarDeps): Promise { await settle({ appliedVersion: row.desiredVersion, providerEventId: null, + keyGeneration: row.keyGeneration + 1, attempts: 0, lastErrorCode: null, }); diff --git a/packages/scheduling/src/testing.ts b/packages/scheduling/src/testing.ts index d24849e01..bc29000c3 100644 --- a/packages/scheduling/src/testing.ts +++ b/packages/scheduling/src/testing.ts @@ -26,7 +26,15 @@ export function testSchedulingDeps(overrides: Partial = {}): Sch }; } -type FakeEvent = { id: string; startMs: number; endMs: number; deleted?: boolean; title: string }; +type FakeEvent = { + id: string; + calendarId?: string; + startMs: number; + endMs: number; + deleted?: boolean; + title: string; + location?: string | undefined; +}; /** * Google Calendar as a `fetch`, for `CalendarDeps.fetcher`. Written events echo back as busy, as @@ -45,6 +53,8 @@ export class FakeGoogleCalendarApi { readonly erroredCalendars = new Set(); failNext: { path: RegExp; status: number; body?: unknown } | null = null; loseNextAnswer = false; + /** The next event's conference is still being created, so its answer has no link yet. */ + conferencePendingNext = false; refreshFails = false; emptyFreeBusy = false; delayMs = 0; @@ -125,7 +135,7 @@ export class FakeGoogleCalendarApi { busy: [ ...(this.busy.get(id) ?? []), ...[...this.events.values()] - .filter((event) => !event.deleted) + .filter((event) => !event.deleted && event.calendarId === id) .map((event) => ({ start: new Date(event.startMs).toISOString(), end: new Date(event.endMs).toISOString(), @@ -141,13 +151,15 @@ export class FakeGoogleCalendarApi { return json(200, { id: body.id, resourceId: "resource", expiration: body.expiration }); } if (path === "/channels/stop") return new Response(null, { status: 204 }); - const eventMatch = /^\/calendars\/[^/]+\/events(?:\/([^/]+))?$/.exec(path); + const eventMatch = /^\/calendars\/([^/]+)\/events(?:\/([^/]+))?$/.exec(path); if (eventMatch) { - const id = eventMatch[1] ? decodeURIComponent(eventMatch[1]) : undefined; + const calendarId = decodeURIComponent(eventMatch[1] as string); + const id = eventMatch[2] ? decodeURIComponent(eventMatch[2]) : undefined; const body = init?.body ? (JSON.parse(String(init.body)) as { id?: string; summary?: string; + location?: string; start?: { dateTime: string }; end?: { dateTime: string }; conferenceData?: unknown; @@ -155,17 +167,25 @@ export class FakeGoogleCalendarApi { : {}; const toEvent = (eventId: string): FakeEvent => ({ id: eventId, + calendarId, title: body.summary ?? "", + location: body.location, startMs: Date.parse(body.start?.dateTime ?? ""), endMs: Date.parse(body.end?.dateTime ?? ""), }); - const wire = (event: FakeEvent) => ({ - id: event.id, - status: event.deleted ? "cancelled" : "confirmed", - start: { dateTime: new Date(event.startMs).toISOString() }, - end: { dateTime: new Date(event.endMs).toISOString() }, - ...(body.conferenceData ? { hangoutLink: "https://meet.google.com/abc-defg-hij" } : {}), - }); + const wire = (event: FakeEvent) => { + const pending = this.conferencePendingNext; + if (body.conferenceData) this.conferencePendingNext = false; + return { + id: event.id, + status: event.deleted ? "cancelled" : "confirmed", + start: { dateTime: new Date(event.startMs).toISOString() }, + end: { dateTime: new Date(event.endMs).toISOString() }, + ...(body.conferenceData && !pending + ? { hangoutLink: "https://meet.google.com/abc-defg-hij" } + : {}), + }; + }; if (method === "POST") { const eventId = body.id as string; const existing = this.events.get(eventId); diff --git a/packages/scheduling/test/host-changes.test.ts b/packages/scheduling/test/host-changes.test.ts new file mode 100644 index 000000000..acd792c64 --- /dev/null +++ b/packages/scheduling/test/host-changes.test.ts @@ -0,0 +1,507 @@ +/** What a booking's calendars, meetings and slots do when its hosts change. */ +import { describe, expect, test } from "bun:test"; +import { createHash } from "node:crypto"; +import { db, schema } from "@coss/db"; +import { uniqueSuffix } from "@coss/db/testing"; +import { createTestTenant } from "@coss/tenancy/testing"; +import { secretsKeyRing } from "@coss/webhooks"; +import { and, eq } from "drizzle-orm"; +import { + type CalendarDeps, + cancelBooking, + completeCalendarAuthorization, + createBooking, + createEventType, + createHost, + createSchedule, + getBooking, + listBookingSlots, + rescheduleBooking, + runDueCalendarSyncs, + runDueCalendarWrites, + type SchedulingEnvironment, + startCalendarAuthorization, + updateEventType, + updateHost, +} from "../src/index.ts"; +import { FakeGoogleCalendarApi, FakeZoomApi, testSchedulingDeps } from "../src/testing.ts"; + +const ms = Date.parse; +const MONDAY = "2031-01-06"; +const at = (time: string) => ms(`${MONDAY}T${time}:00Z`); +const NOW = new Date(at("00:00")); +const actor = { kind: "system" } as const; +const attendee = { uid: "p", name: "Sam Lee", email: "sam@example.com", time_zone: "UTC" }; +const plain = testSchedulingDeps({ now: () => NOW }); +const scope = (env: SchedulingEnvironment) => ({ organizationIds: [env.organizationId] }); + +async function environment(): Promise { + const tenant = await createTestTenant(); + return { + organizationId: tenant.organization.id, + projectId: tenant.project.id, + environmentId: tenant.production.id, + mode: "live", + }; +} + +async function hostWithHours( + env: SchedulingEnvironment, + name: string, + extra: { attributes?: Record } = {}, + hours = { start: "09:00", end: "17:00" }, +) { + const host = await createHost(env, { name, time_zone: "UTC", ...extra }); + await createSchedule(env, host.id, { rules: [{ days: [0, 1, 2, 3, 4, 5, 6], ...hours }] }); + return host; +} + +function deps(fetcher: CalendarDeps["fetcher"]): CalendarDeps { + return { + secretsKeys: secretsKeyRing([createHash("sha256").update("host changes").digest()]), + apps: { + google: { clientId: "google-client", clientSecret: "google-secret" }, + microsoft: null, + zoom: { clientId: "zoom-client", clientSecret: "zoom-secret", webhookSecret: "token" }, + }, + publicUrl: "https://api.example.test", + fetcher, + now: () => NOW, + }; +} + +async function connect( + env: SchedulingEnvironment, + hostId: string, + provider: "google" | "zoom", + calendarDeps: CalendarDeps, +) { + const { url } = await startCalendarAuthorization( + env, + hostId, + { provider, returnUrl: null }, + calendarDeps, + ); + const state = new URL(url).searchParams.get("state") as string; + const result = await completeCalendarAuthorization( + { provider, state, code: "code", error: null }, + calendarDeps, + ); + expect(result.outcome).toBe("connected"); +} + +async function zoomPool( + env: SchedulingEnvironment, + required: readonly { id: string }[], + members: readonly { id: string }[], +) { + return createEventType(env, { + title: "Video", + kind: "pool", + duration_minutes: 30, + locations: [{ type: "zoom", url: null }], + hosts: [ + ...required.map((host) => ({ + host: host.id, + role: "required", + weight: 100, + schedule: null, + })), + ...members.map((host) => ({ host: host.id, role: "member", weight: 100, schedule: null })), + ], + } as never); +} + +const urlOf = (location: unknown) => (location as { url: string | null }).url; + +/** Deauthorization looks a Zoom user up across every organization, and the test database is shared. */ +function zoomApi(): FakeZoomApi { + const api = new FakeZoomApi(); + api.userId = `zoom_${uniqueSuffix()}`; + return api; +} + +describe("Zoom when a booking's hosts change", () => { + test("a replaced member doesn't take the required host's meeting with them", async () => { + const env = await environment(); + const required = await hostWithHours(env, "Required"); + const member = await hostWithHours(env, "Member"); + const next = await hostWithHours(env, "Next"); + const api = zoomApi(); + const calendar = deps(api.fetch); + await connect(env, required.id, "zoom", calendar); + const pool = await zoomPool(env, [required], [member, next]); + const { booking } = await createBooking( + env, + { eventType: pool.id, startMs: at("09:00"), host: member.id, attendee }, + plain, + actor, + ); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + const link = urlOf((await getBooking(env, booking.id, plain)).location); + expect(link).toContain("zoom.us/j/"); + + const moved = await rescheduleBooking( + env, + booking.id, + { startMs: at("10:00"), host: next.id }, + plain, + actor, + ); + expect(urlOf(moved.location)).toBe(link); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + expect(urlOf((await getBooking(env, booking.id, plain)).location)).toBe(link); + expect(api.meetings.size).toBe(1); + }); + + test("a new member with Zoom doesn't start a second meeting", async () => { + const env = await environment(); + // Created first, so it sorts first: the old code picked whoever sorts first. + const next = await hostWithHours(env, "Next"); + const required = await hostWithHours(env, "Required"); + const member = await hostWithHours(env, "Member"); + const api = zoomApi(); + const calendar = deps(api.fetch); + await connect(env, required.id, "zoom", calendar); + const pool = await zoomPool(env, [required], [member, next]); + const { booking } = await createBooking( + env, + { eventType: pool.id, startMs: at("09:00"), host: member.id, attendee }, + plain, + actor, + ); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + const link = urlOf((await getBooking(env, booking.id, plain)).location); + await connect(env, next.id, "zoom", calendar); + + await rescheduleBooking(env, booking.id, { startMs: at("10:00"), host: next.id }, plain, actor); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + expect(urlOf((await getBooking(env, booking.id, plain)).location)).toBe(link); + expect(api.meetings.size).toBe(1); + }); + + test("when the host running the meeting leaves, someone still here runs a new one", async () => { + const env = await environment(); + const member = await hostWithHours(env, "Member"); + const required = await hostWithHours(env, "Required"); + const next = await hostWithHours(env, "Next"); + const api = zoomApi(); + const calendar = deps(api.fetch); + await connect(env, member.id, "zoom", calendar); + await connect(env, required.id, "zoom", calendar); + const pool = await zoomPool(env, [required], [member, next]); + const { booking } = await createBooking( + env, + { eventType: pool.id, startMs: at("09:00"), host: member.id, attendee }, + plain, + actor, + ); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + const link = urlOf((await getBooking(env, booking.id, plain)).location); + + const moved = await rescheduleBooking( + env, + booking.id, + { startMs: at("10:00"), host: next.id }, + plain, + actor, + ); + expect(urlOf(moved.location)).toBeNull(); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + const after = urlOf((await getBooking(env, booking.id, plain)).location); + expect(after).toContain("zoom.us/j/"); + expect(after).not.toBe(link); + expect(api.meetings.size).toBe(1); + }); + + test("a booking that goes to another host and back has one meeting and a working link", async () => { + const env = await environment(); + const first = await hostWithHours(env, "First"); + const second = await hostWithHours(env, "Second"); + const api = zoomApi(); + const calendar = deps(api.fetch); + await connect(env, first.id, "zoom", calendar); + await connect(env, second.id, "zoom", calendar); + const pool = await zoomPool(env, [], [first, second]); + const { booking } = await createBooking( + env, + { eventType: pool.id, startMs: at("09:00"), host: first.id, attendee }, + plain, + actor, + ); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + for (const [time, host] of [ + ["10:00", second], + ["11:00", first], + ] as const) { + await rescheduleBooking(env, booking.id, { startMs: at(time), host: host.id }, plain, actor); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + } + const link = urlOf((await getBooking(env, booking.id, plain)).location) as string; + expect(api.meetings.size).toBe(1); + expect(link).toContain(String([...api.meetings.keys()][0])); + }); +}); + +describe("Google when a booking's hosts change", () => { + async function meetPool(env: SchedulingEnvironment, hosts: readonly { id: string }[]) { + return createEventType(env, { + title: "Video", + kind: "pool", + duration_minutes: 30, + locations: [{ type: "google_meet" }], + hosts: hosts.map((host) => ({ host: host.id, role: "member", weight: 100, schedule: null })), + } as never); + } + + test("going to another host and back makes a new event rather than reusing a deleted key", async () => { + const env = await environment(); + const first = await hostWithHours(env, "First"); + const second = await hostWithHours(env, "Second"); + const api = new FakeGoogleCalendarApi(); + const calendar = deps(api.fetch); + await connect(env, first.id, "google", calendar); + await connect(env, second.id, "google", calendar); + await runDueCalendarSyncs(calendar, { scope: scope(env) }); + const pool = await meetPool(env, [first, second]); + const { booking } = await createBooking( + env, + { eventType: pool.id, startMs: at("09:00"), host: first.id, attendee }, + plain, + actor, + ); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + const [firstEvent] = [...api.events.keys()]; + + await rescheduleBooking( + env, + booking.id, + { startMs: at("10:00"), host: second.id }, + plain, + actor, + ); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + api.requests.length = 0; + await rescheduleBooking( + env, + booking.id, + { startMs: at("11:00"), host: first.id }, + plain, + actor, + ); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + + expect(api.requests.filter((request) => request.startsWith("PUT"))).toEqual([]); + expect(api.events.get(firstEvent as string)?.deleted).toBe(true); + const live = [...api.events.values()].filter((event) => !event.deleted); + expect(live.map((event) => event.startMs)).toEqual([at("11:00")]); + expect((await getBooking(env, booking.id, plain)).location?.type).toBe("link"); + }); + + test("a Meet link stays when someone other than its host leaves, and is never on the wire", async () => { + const env = await environment(); + const required = await hostWithHours(env, "Required"); + const member = await hostWithHours(env, "Member"); + const next = await hostWithHours(env, "Next"); + const api = new FakeGoogleCalendarApi(); + const calendar = deps(api.fetch); + await connect(env, required.id, "google", calendar); + await runDueCalendarSyncs(calendar, { scope: scope(env) }); + const pool = await createEventType(env, { + title: "Video", + kind: "pool", + duration_minutes: 30, + locations: [{ type: "google_meet" }], + hosts: [ + { host: required.id, role: "required", weight: 100, schedule: null }, + { host: member.id, role: "member", weight: 100, schedule: null }, + { host: next.id, role: "member", weight: 100, schedule: null }, + ], + } as never); + const { booking } = await createBooking( + env, + { eventType: pool.id, startMs: at("09:00"), host: member.id, attendee }, + plain, + actor, + ); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + const before = await getBooking(env, booking.id, plain); + expect(before.location).toEqual({ type: "link", url: "https://meet.google.com/abc-defg-hij" }); + + const moved = await rescheduleBooking( + env, + booking.id, + { startMs: at("10:00"), host: next.id }, + plain, + actor, + ); + expect(moved.location).toEqual(before.location); + const [row] = await db + .select({ location: schema.schedulingBooking.location }) + .from(schema.schedulingBooking) + .where(eq(schema.schedulingBooking.id, booking.id)); + expect(row?.location).toMatchObject({ conference_host_id: required.id }); + }); + + test("a co-host's event gets the Meet link when another host's event made it", async () => { + const env = await environment(); + const required = await hostWithHours(env, "Required"); + const member = await hostWithHours(env, "Member"); + const api = new FakeGoogleCalendarApi(); + const calendar = deps(api.fetch); + await connect(env, required.id, "google", calendar); + await connect(env, member.id, "google", calendar); + await runDueCalendarSyncs(calendar, { scope: scope(env) }); + const pool = await createEventType(env, { + title: "Video", + kind: "pool", + duration_minutes: 30, + locations: [{ type: "google_meet" }], + hosts: [ + { host: required.id, role: "required", weight: 100, schedule: null }, + { host: member.id, role: "member", weight: 100, schedule: null }, + ], + } as never); + await createBooking( + env, + { eventType: pool.id, startMs: at("09:00"), host: member.id, attendee }, + plain, + actor, + ); + // Google creates a conference asynchronously, so the first event goes out with no link. + api.conferencePendingNext = true; + await runDueCalendarWrites(calendar, { scope: scope(env), limit: 1 }); + expect([...api.events.values()][0]?.location).toBeUndefined(); + await runDueCalendarWrites(calendar, { scope: scope(env), limit: 1 }); + await runDueCalendarWrites(calendar, { scope: scope(env), limit: 1 }); + const [first, second] = [...api.events.values()]; + expect(first?.location).toBe("https://meet.google.com/abc-defg-hij"); + // The event that made the link already shows it, and it isn't rewritten to say so again. + expect(second?.location).toBeUndefined(); + expect(await runDueCalendarWrites(calendar, { scope: scope(env) })).toBe(0); + }); + + test("cancelling removes an event from a calendar that's no longer the write target", async () => { + const env = await environment(); + const host = await hostWithHours(env, "Host"); + const api = new FakeGoogleCalendarApi(); + const calendar = deps(api.fetch); + await connect(env, host.id, "google", calendar); + await runDueCalendarSyncs(calendar, { scope: scope(env) }); + const eventType = await createEventType(env, { + title: "Call", + kind: "one_on_one", + duration_minutes: 30, + hosts: [{ host: host.id, role: "member", weight: 100, schedule: null }], + } as never); + const { booking } = await createBooking( + env, + { eventType: eventType.id, startMs: at("09:00"), attendee }, + plain, + actor, + ); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + expect([...api.events.values()].filter((event) => !event.deleted).length).toBe(1); + + await db + .update(schema.schedulingCalendar) + .set({ writeTarget: false }) + .where( + and( + eq(schema.schedulingCalendar.hostId, host.id), + eq(schema.schedulingCalendar.writeTarget, true), + ), + ); + await cancelBooking(env, booking.id, plain, actor); + await runDueCalendarWrites(calendar, { scope: scope(env) }); + expect([...api.events.values()].filter((event) => !event.deleted).length).toBe(0); + }); + + test("the fake's freeBusy only reports a calendar's own events", async () => { + const api = new FakeGoogleCalendarApi(); + api.events.set("a", { + id: "a", + calendarId: "doctor@example.com", + title: "", + startMs: at("09:00"), + endMs: at("10:00"), + }); + const res = await api.fetch("https://www.googleapis.com/calendar/v3/freeBusy", { + method: "POST", + body: JSON.stringify({ items: [{ id: "doctor@example.com" }, { id: "team@example.com" }] }), + }); + const body = (await res.json()) as { calendars: Record }; + expect(body.calendars["doctor@example.com"]?.busy.length).toBe(1); + expect(body.calendars["team@example.com"]?.busy.length).toBe(0); + }); +}); + +describe("slots for moving a booking", () => { + const window = { fromMs: at("09:00"), toMs: at("17:00"), nowMs: NOW.getTime() }; + + test("come from a host a filter no longer finds, who still has the booking", async () => { + const env = await environment(); + const host = await hostWithHours(env, "Filtered", { attributes: { team: "a" } }); + const pool = await createEventType(env, { + title: "Filtered", + kind: "pool", + duration_minutes: 30, + hosts: [], + host_filter: { team: "a" }, + } as never); + const { booking } = await createBooking( + env, + { eventType: pool.id, startMs: at("09:00"), attendee }, + plain, + actor, + ); + await updateHost(env, host.id, { attributes: { team: "b" } }); + const slots = await listBookingSlots(env, { bookingId: booking.id, ...window }); + expect(slots.map((slot) => slot.startMs)).toContain(at("10:00")); + await rescheduleBooking(env, booking.id, { startMs: at("10:00") }, plain, actor); + }); + + test("are empty for a host taken off the event type, since moving would be refused", async () => { + const env = await environment(); + const original = await hostWithHours(env, "Original"); + const later = await hostWithHours(env, "Later"); + const eventType = await createEventType(env, { + title: "Together", + kind: "collective", + duration_minutes: 30, + hosts: [{ host: original.id, role: "required", weight: 100, schedule: null }], + } as never); + const { booking } = await createBooking( + env, + { eventType: eventType.id, startMs: at("09:00"), attendee }, + plain, + actor, + ); + await updateEventType(env, eventType.id, { + hosts: [{ host: later.id, role: "required", weight: 100, schedule: null }], + } as never); + expect(await listBookingSlots(env, { bookingId: booking.id, ...window })).toEqual([]); + await expect( + rescheduleBooking(env, booking.id, { startMs: at("10:00") }, plain, actor), + ).rejects.toMatchObject({ code: "slot_unavailable" }); + }); + + test("are empty once one of the booking's hosts is disabled", async () => { + const env = await environment(); + const host = await hostWithHours(env, "Leaving"); + const eventType = await createEventType(env, { + title: "Call", + kind: "one_on_one", + duration_minutes: 30, + hosts: [{ host: host.id, role: "member", weight: 100, schedule: null }], + } as never); + const { booking } = await createBooking( + env, + { eventType: eventType.id, startMs: at("09:00"), attendee }, + plain, + actor, + ); + await updateHost(env, host.id, { status: "disabled" }); + expect(await listBookingSlots(env, { bookingId: booking.id, ...window })).toEqual([]); + }); +}); From f13465dcfb8f2ee2ce6cfa5c8500466a7925c6bf Mon Sep 17 00:00:00 2001 From: Bailey Pumfleet Date: Wed, 4 Nov 2026 11:43:31 -0600 Subject: [PATCH 02/30] Scheduling: remember what a booking was routed with Choosing another host for a booking has to keep to what it was routed with, and that was dropped once a host had won. It's now kept with the booking, encrypted, and goes when the attendee's details do. An empty value means nothing narrowed it, and null means it can't be known, so a later choice never mistakes one for the other. --- .../db/migrations/0127_careful_ultron.sql | 1 + .../db/migrations/meta/0127_snapshot.json | 31089 ++++++++++++++++ packages/db/migrations/meta/_journal.json | 7 + packages/db/src/schema/scheduling.ts | 3 + packages/scheduling/AGENTS.md | 3 + packages/scheduling/src/attendees.ts | 18 + packages/scheduling/src/bookings.ts | 2 + packages/scheduling/src/reencrypt.ts | 61 +- packages/scheduling/src/retention.ts | 20 +- packages/scheduling/test/host-changes.test.ts | 83 +- packages/scheduling/test/reencrypt.test.ts | 18 +- 11 files changed, 31294 insertions(+), 11 deletions(-) create mode 100644 packages/db/migrations/0127_careful_ultron.sql create mode 100644 packages/db/migrations/meta/0127_snapshot.json diff --git a/packages/db/migrations/0127_careful_ultron.sql b/packages/db/migrations/0127_careful_ultron.sql new file mode 100644 index 000000000..7d2cfc18a --- /dev/null +++ b/packages/db/migrations/0127_careful_ultron.sql @@ -0,0 +1 @@ +ALTER TABLE "scheduling_booking" ADD COLUMN "encrypted_attributes" text; \ No newline at end of file diff --git a/packages/db/migrations/meta/0127_snapshot.json b/packages/db/migrations/meta/0127_snapshot.json new file mode 100644 index 000000000..c5fd1b116 --- /dev/null +++ b/packages/db/migrations/meta/0127_snapshot.json @@ -0,0 +1,31089 @@ +{ + "id": "dfb953d5-6bf9-4249-a438-b54f4e440144", + "prevId": "a4afc925-7783-4789-aab6-062ad775edfb", + "version": "7", + "dialect": "postgresql", + "tables": { + "public.account": { + "name": "account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "refresh_token": { + "name": "refresh_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "id_token": { + "name": "id_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "access_token_expires_at": { + "name": "access_token_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "refresh_token_expires_at": { + "name": "refresh_token_expires_at", + "type": "timestamp", + "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", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "account_userId_idx": { + "name": "account_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "account_user_id_user_id_fk": { + "name": "account_user_id_user_id_fk", + "tableFrom": "account", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.apikey": { + "name": "apikey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "config_id": { + "name": "config_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'default'" + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "start": { + "name": "start", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reference_id": { + "name": "reference_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "prefix": { + "name": "prefix", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "refill_interval": { + "name": "refill_interval", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "refill_amount": { + "name": "refill_amount", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_refill_at": { + "name": "last_refill_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_enabled": { + "name": "rate_limit_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": true + }, + "rate_limit_time_window": { + "name": "rate_limit_time_window", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 86400000 + }, + "rate_limit_max": { + "name": "rate_limit_max", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 10 + }, + "request_count": { + "name": "request_count", + "type": "integer", + "primaryKey": false, + "notNull": false, + "default": 0 + }, + "remaining": { + "name": "remaining", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_request": { + "name": "last_request", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "permissions": { + "name": "permissions", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "apikey_configId_idx": { + "name": "apikey_configId_idx", + "columns": [ + { + "expression": "config_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "apikey_referenceId_idx": { + "name": "apikey_referenceId_idx", + "columns": [ + { + "expression": "reference_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "apikey_key_idx": { + "name": "apikey_key_idx", + "columns": [ + { + "expression": "key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.invitation": { + "name": "invitation", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "inviter_id": { + "name": "inviter_id", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "invitation_organizationId_idx": { + "name": "invitation_organizationId_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "invitation_email_idx": { + "name": "invitation_email_idx", + "columns": [ + { + "expression": "email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "invitation_organization_id_organization_id_fk": { + "name": "invitation_organization_id_organization_id_fk", + "tableFrom": "invitation", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "invitation_inviter_id_user_id_fk": { + "name": "invitation_inviter_id_user_id_fk", + "tableFrom": "invitation", + "tableTo": "user", + "columnsFrom": [ + "inviter_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.member": { + "name": "member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "member_organizationId_idx": { + "name": "member_organizationId_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "member_userId_idx": { + "name": "member_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "member_organization_id_organization_id_fk": { + "name": "member_organization_id_organization_id_fk", + "tableFrom": "member", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "member_user_id_user_id_fk": { + "name": "member_user_id_user_id_fk", + "tableFrom": "member", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization": { + "name": "organization", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "logo": { + "name": "logo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "require_two_factor": { + "name": "require_two_factor", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "require_sso": { + "name": "require_sso", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "organization_slug_unique": { + "name": "organization_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "slug" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.passkey": { + "name": "passkey", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "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": "text", + "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", + "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, + "concurrently": false, + "method": "btree", + "with": {} + }, + "passkey_credentialID_idx": { + "name": "passkey_credentialID_idx", + "columns": [ + { + "expression": "credential_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "passkey_user_id_user_id_fk": { + "name": "passkey_user_id_user_id_fk", + "tableFrom": "passkey", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_connection_binding": { + "name": "scim_connection_binding", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "connection_key": { + "name": "connection_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "decommissioned_at": { + "name": "decommissioned_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "decommission_status": { + "name": "decommission_status", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "decommission_cursor_user_id": { + "name": "decommission_cursor_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "decommission_reconciled_user_count": { + "name": "decommission_reconciled_user_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "decommission_batch_count": { + "name": "decommission_batch_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "decommission_revision": { + "name": "decommission_revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "decommission_completed_at": { + "name": "decommission_completed_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "decommission_lease_id": { + "name": "decommission_lease_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "decommission_lease_expires_at": { + "name": "decommission_lease_expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "scimConnectionBinding_connectionId_idx": { + "name": "scimConnectionBinding_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_connection_binding_connection_key_unique": { + "name": "scim_connection_binding_connection_key_unique", + "nullsNotDistinct": false, + "columns": [ + "connection_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_group": { + "name": "scim_group", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name_key": { + "name": "display_name_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "external_id_key": { + "name": "external_id_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "order_key": { + "name": "order_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimGroup_connectionId_idx": { + "name": "scimGroup_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimGroup_provisioningDomainId_idx": { + "name": "scimGroup_provisioningDomainId_idx", + "columns": [ + { + "expression": "provisioning_domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_group_display_name_key_unique": { + "name": "scim_group_display_name_key_unique", + "nullsNotDistinct": false, + "columns": [ + "display_name_key" + ] + }, + "scim_group_external_id_key_unique": { + "name": "scim_group_external_id_key_unique", + "nullsNotDistinct": false, + "columns": [ + "external_id_key" + ] + }, + "scim_group_order_key_unique": { + "name": "scim_group_order_key_unique", + "nullsNotDistinct": false, + "columns": [ + "order_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_group_member": { + "name": "scim_group_member", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scim_user_id": { + "name": "scim_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "membership_key": { + "name": "membership_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimGroupMember_connectionId_idx": { + "name": "scimGroupMember_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimGroupMember_groupId_idx": { + "name": "scimGroupMember_groupId_idx", + "columns": [ + { + "expression": "group_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimGroupMember_scimUserId_idx": { + "name": "scimGroupMember_scimUserId_idx", + "columns": [ + { + "expression": "scim_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_group_member_group_id_scim_group_id_fk": { + "name": "scim_group_member_group_id_scim_group_id_fk", + "tableFrom": "scim_group_member", + "tableTo": "scim_group", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scim_group_member_scim_user_id_scim_user_id_fk": { + "name": "scim_group_member_scim_user_id_scim_user_id_fk", + "tableFrom": "scim_group_member", + "tableTo": "scim_user", + "columnsFrom": [ + "scim_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_group_member_membership_key_unique": { + "name": "scim_group_member_membership_key_unique", + "nullsNotDistinct": false, + "columns": [ + "membership_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_identity_tombstone": { + "name": "scim_identity_tombstone", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "external_id_key": { + "name": "external_id_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "profile": { + "name": "profile", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "deleted_at": { + "name": "deleted_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimIdentityTombstone_connectionId_idx": { + "name": "scimIdentityTombstone_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimIdentityTombstone_provisioningDomainId_idx": { + "name": "scimIdentityTombstone_provisioningDomainId_idx", + "columns": [ + { + "expression": "provisioning_domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimIdentityTombstone_userId_idx": { + "name": "scimIdentityTombstone_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_identity_tombstone_user_id_user_id_fk": { + "name": "scim_identity_tombstone_user_id_user_id_fk", + "tableFrom": "scim_identity_tombstone", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_identity_tombstone_external_id_key_unique": { + "name": "scim_identity_tombstone_external_id_key_unique", + "nullsNotDistinct": false, + "columns": [ + "external_id_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_managed_connection": { + "name": "scim_managed_connection", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "creation_request_id": { + "name": "creation_request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "decommission_started_at": { + "name": "decommission_started_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "decommission_started_by": { + "name": "decommission_started_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "decommissioned_at": { + "name": "decommissioned_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "decommissioned_by": { + "name": "decommissioned_by", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "scimManagedConnection_provisioningDomainId_idx": { + "name": "scimManagedConnection_provisioningDomainId_idx", + "columns": [ + { + "expression": "provisioning_domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_managed_connection_creation_request_id_unique": { + "name": "scim_managed_connection_creation_request_id_unique", + "nullsNotDistinct": false, + "columns": [ + "creation_request_id" + ] + }, + "scim_managed_connection_connection_id_unique": { + "name": "scim_managed_connection_connection_id_unique", + "nullsNotDistinct": false, + "columns": [ + "connection_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_managed_connection_event": { + "name": "scim_managed_connection_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_record_id": { + "name": "connection_record_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_key": { + "name": "event_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credential_id": { + "name": "credential_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimManagedConnectionEvent_connectionRecordId_idx": { + "name": "scimManagedConnectionEvent_connectionRecordId_idx", + "columns": [ + { + "expression": "connection_record_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_managed_connection_event_connection_record_id_scim_managed_connection_id_fk": { + "name": "scim_managed_connection_event_connection_record_id_scim_managed_connection_id_fk", + "tableFrom": "scim_managed_connection_event", + "tableTo": "scim_managed_connection", + "columnsFrom": [ + "connection_record_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_managed_connection_event_event_key_unique": { + "name": "scim_managed_connection_event_event_key_unique", + "nullsNotDistinct": false, + "columns": [ + "event_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_managed_credential": { + "name": "scim_managed_credential", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_record_id": { + "name": "connection_record_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "credential_id": { + "name": "credential_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_digest": { + "name": "token_digest", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hash_version": { + "name": "hash_version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "active_slot_key": { + "name": "active_slot_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serialized_scopes": { + "name": "serialized_scopes", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_by": { + "name": "created_by", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + }, + "revoked_by": { + "name": "revoked_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "decommissioned_at": { + "name": "decommissioned_at", + "type": "timestamp", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "scimManagedCredential_connectionRecordId_idx": { + "name": "scimManagedCredential_connectionRecordId_idx", + "columns": [ + { + "expression": "connection_record_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_managed_credential_connection_record_id_scim_managed_connection_id_fk": { + "name": "scim_managed_credential_connection_record_id_scim_managed_connection_id_fk", + "tableFrom": "scim_managed_credential", + "tableTo": "scim_managed_connection", + "columnsFrom": [ + "connection_record_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_managed_credential_credential_id_unique": { + "name": "scim_managed_credential_credential_id_unique", + "nullsNotDistinct": false, + "columns": [ + "credential_id" + ] + }, + "scim_managed_credential_active_slot_key_unique": { + "name": "scim_managed_credential_active_slot_key_unique", + "nullsNotDistinct": false, + "columns": [ + "active_slot_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_projection_grant": { + "name": "scim_projection_grant", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scim_user_id": { + "name": "scim_user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_kind": { + "name": "source_kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_id": { + "name": "source_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_value": { + "name": "source_value", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "grant_key": { + "name": "grant_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimProjectionGrant_connectionId_idx": { + "name": "scimProjectionGrant_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimProjectionGrant_provisioningDomainId_idx": { + "name": "scimProjectionGrant_provisioningDomainId_idx", + "columns": [ + { + "expression": "provisioning_domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimProjectionGrant_scimUserId_idx": { + "name": "scimProjectionGrant_scimUserId_idx", + "columns": [ + { + "expression": "scim_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimProjectionGrant_userId_idx": { + "name": "scimProjectionGrant_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_projection_grant_scim_user_id_scim_user_id_fk": { + "name": "scim_projection_grant_scim_user_id_scim_user_id_fk", + "tableFrom": "scim_projection_grant", + "tableTo": "scim_user", + "columnsFrom": [ + "scim_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scim_projection_grant_user_id_user_id_fk": { + "name": "scim_projection_grant_user_id_user_id_fk", + "tableFrom": "scim_projection_grant", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_projection_grant_grant_key_unique": { + "name": "scim_projection_grant_grant_key_unique", + "nullsNotDistinct": false, + "columns": [ + "grant_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_subject": { + "name": "scim_subject", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "profile_source_id": { + "name": "profile_source_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimSubject_profileSourceId_idx": { + "name": "scimSubject_profileSourceId_idx", + "columns": [ + { + "expression": "profile_source_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_subject_user_id_user_id_fk": { + "name": "scim_subject_user_id_user_id_fk", + "tableFrom": "scim_subject", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_subject_user_id_unique": { + "name": "scim_subject_user_id_unique", + "nullsNotDistinct": false, + "columns": [ + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_user": { + "name": "scim_user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provisioning_domain_id": { + "name": "provisioning_domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "connection_user_key": { + "name": "connection_user_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_name": { + "name": "user_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_name_key": { + "name": "user_name_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "primary_email": { + "name": "primary_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "work_email_value_index": { + "name": "work_email_value_index", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_value_index": { + "name": "email_value_index", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "formatted_name": { + "name": "formatted_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "given_name": { + "name": "given_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "family_name": { + "name": "family_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "serialized_emails": { + "name": "serialized_emails", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "serialized_attributes": { + "name": "serialized_attributes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "external_id_key": { + "name": "external_id_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "active": { + "name": "active", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "order_key": { + "name": "order_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scimUser_connectionId_idx": { + "name": "scimUser_connectionId_idx", + "columns": [ + { + "expression": "connection_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimUser_provisioningDomainId_idx": { + "name": "scimUser_provisioningDomainId_idx", + "columns": [ + { + "expression": "provisioning_domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scimUser_userId_idx": { + "name": "scimUser_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scim_user_user_id_user_id_fk": { + "name": "scim_user_user_id_user_id_fk", + "tableFrom": "scim_user", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_user_connection_user_key_unique": { + "name": "scim_user_connection_user_key_unique", + "nullsNotDistinct": false, + "columns": [ + "connection_user_key" + ] + }, + "scim_user_user_name_key_unique": { + "name": "scim_user_user_name_key_unique", + "nullsNotDistinct": false, + "columns": [ + "user_name_key" + ] + }, + "scim_user_external_id_key_unique": { + "name": "scim_user_external_id_key_unique", + "nullsNotDistinct": false, + "columns": [ + "external_id_key" + ] + }, + "scim_user_order_key_unique": { + "name": "scim_user_order_key_unique", + "nullsNotDistinct": false, + "columns": [ + "order_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.session": { + "name": "session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "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": "text", + "primaryKey": false, + "notNull": true + }, + "active_organization_id": { + "name": "active_organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "impersonated_by": { + "name": "impersonated_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sso_provider_id": { + "name": "sso_provider_id", + "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, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "session_user_id_user_id_fk": { + "name": "session_user_id_user_id_fk", + "tableFrom": "session", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "session_token_unique": { + "name": "session_token_unique", + "nullsNotDistinct": false, + "columns": [ + "token" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sso_provider": { + "name": "sso_provider", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "issuer": { + "name": "issuer", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "oidc_config": { + "name": "oidc_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "saml_config": { + "name": "saml_config", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_id": { + "name": "provider_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_verified": { + "name": "domain_verified", + "type": "boolean", + "primaryKey": false, + "notNull": false + } + }, + "indexes": {}, + "foreignKeys": { + "sso_provider_user_id_user_id_fk": { + "name": "sso_provider_user_id_user_id_fk", + "tableFrom": "sso_provider", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sso_provider_provider_id_unique": { + "name": "sso_provider_provider_id_unique", + "nullsNotDistinct": false, + "columns": [ + "provider_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.two_factor": { + "name": "two_factor", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "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": "text", + "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", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "twoFactor_secret_idx": { + "name": "twoFactor_secret_idx", + "columns": [ + { + "expression": "secret", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "twoFactor_userId_idx": { + "name": "twoFactor_userId_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "two_factor_user_id_user_id_fk": { + "name": "two_factor_user_id_user_id_fk", + "tableFrom": "two_factor", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.user": { + "name": "user", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_verified": { + "name": "email_verified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "image": { + "name": "image", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "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", + "primaryKey": false, + "notNull": false + }, + "two_factor_enabled": { + "name": "two_factor_enabled", + "type": "boolean", + "primaryKey": false, + "notNull": false, + "default": false + }, + "canonical_email": { + "name": "canonical_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owned_organization_limit": { + "name": "owned_organization_limit", + "type": "integer", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "user_canonicalEmail_idx": { + "name": "user_canonicalEmail_idx", + "columns": [ + { + "expression": "canonical_email", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "user_email_unique": { + "name": "user_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verification": { + "name": "verification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "identifier": { + "name": "identifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp", + "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, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_account": { + "name": "billing_account", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "billing_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider_customer_id": { + "name": "provider_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "collection_method": { + "name": "collection_method", + "type": "billing_collection_method", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'charge_automatically'" + }, + "net_terms_days": { + "name": "net_terms_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 30 + }, + "allowed_payment_methods": { + "name": "allowed_payment_methods", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{card}'::text[]" + }, + "required_payment_methods": { + "name": "required_payment_methods", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "tax_mode": { + "name": "tax_mode", + "type": "billing_tax_mode", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'none'" + }, + "billing_email": { + "name": "billing_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "billing_cc": { + "name": "billing_cc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "billing_name": { + "name": "billing_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "billing_address": { + "name": "billing_address", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "tax_id": { + "name": "tax_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "spend_limit_cents": { + "name": "spend_limit_cents", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "alert_thresholds": { + "name": "alert_thresholds", + "type": "integer[]", + "primaryKey": false, + "notNull": true, + "default": "'{80,100}'::integer[]" + }, + "grace_days": { + "name": "grace_days", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 14 + }, + "status": { + "name": "status", + "type": "billing_account_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "past_due_since": { + "name": "past_due_since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "hold_exempt_until": { + "name": "hold_exempt_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "payment_method": { + "name": "payment_method", + "type": "jsonb", + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "billing_account_organization_id_organization_id_fk": { + "name": "billing_account_organization_id_organization_id_fk", + "tableFrom": "billing_account", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_account_organization_unique": { + "name": "billing_account_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_budget": { + "name": "billing_budget", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope": { + "name": "scope", + "type": "billing_budget_scope", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "amount_cents": { + "name": "amount_cents", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "alert_thresholds": { + "name": "alert_thresholds", + "type": "integer[]", + "primaryKey": false, + "notNull": true, + "default": "'{80,100}'::integer[]" + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_budget_member_default_idx": { + "name": "billing_budget_member_default_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_budget\".\"scope\" = 'member_default'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_budget_user_idx": { + "name": "billing_budget_user_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_budget\".\"scope\" = 'user'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_budget_project_idx": { + "name": "billing_budget_project_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "project_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_budget\".\"scope\" = 'project'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_budget_api_key_idx": { + "name": "billing_budget_api_key_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "api_key_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_budget\".\"scope\" = 'api_key'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_budget_organization_id_organization_id_fk": { + "name": "billing_budget_organization_id_organization_id_fk", + "tableFrom": "billing_budget", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_budget_user_id_user_id_fk": { + "name": "billing_budget_user_id_user_id_fk", + "tableFrom": "billing_budget", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_budget_api_key_id_apikey_id_fk": { + "name": "billing_budget_api_key_id_apikey_id_fk", + "tableFrom": "billing_budget", + "tableTo": "apikey", + "columnsFrom": [ + "api_key_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_budget_created_by_user_id_user_id_fk": { + "name": "billing_budget_created_by_user_id_user_id_fk", + "tableFrom": "billing_budget", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "billing_budget_project_fk": { + "name": "billing_budget_project_fk", + "tableFrom": "billing_budget", + "tableTo": "project", + "columnsFrom": [ + "project_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "billing_budget_target_check": { + "name": "billing_budget_target_check", + "value": "case \"billing_budget\".\"scope\"\n when 'member_default' then \"billing_budget\".\"user_id\" is null and \"billing_budget\".\"project_id\" is null and \"billing_budget\".\"api_key_id\" is null and \"billing_budget\".\"amount_cents\" is not null\n when 'user' then \"billing_budget\".\"user_id\" is not null and \"billing_budget\".\"project_id\" is null and \"billing_budget\".\"api_key_id\" is null\n when 'project' then \"billing_budget\".\"user_id\" is null and \"billing_budget\".\"project_id\" is not null and \"billing_budget\".\"api_key_id\" is null and \"billing_budget\".\"amount_cents\" is not null\n when 'api_key' then \"billing_budget\".\"user_id\" is null and \"billing_budget\".\"project_id\" is null and \"billing_budget\".\"api_key_id\" is not null and \"billing_budget\".\"amount_cents\" is not null\n end" + }, + "billing_budget_amount_check": { + "name": "billing_budget_amount_check", + "value": "\"billing_budget\".\"amount_cents\" is null or \"billing_budget\".\"amount_cents\" >= 0" + } + }, + "isRLSEnabled": false + }, + "public.billing_budget_hold": { + "name": "billing_budget_hold", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope": { + "name": "scope", + "type": "billing_budget_scope", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "spent_cents": { + "name": "spent_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "limit_cents": { + "name": "limit_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "billing_budget_hold_organization_id_organization_id_fk": { + "name": "billing_budget_hold_organization_id_organization_id_fk", + "tableFrom": "billing_budget_hold", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "billing_budget_hold_organization_id_scope_target_id_pk": { + "name": "billing_budget_hold_organization_id_scope_target_id_pk", + "columns": [ + "organization_id", + "scope", + "target_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_contract": { + "name": "billing_contract", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "billing_contract_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "billing_contract_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "plan": { + "name": "plan", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "terms": { + "name": "terms", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "effective_from": { + "name": "effective_from", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "effective_until": { + "name": "effective_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "term_end": { + "name": "term_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "auto_renew": { + "name": "auto_renew", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "supersedes_id": { + "name": "supersedes_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pending_invoice_id": { + "name": "pending_invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pending_expires_at": { + "name": "pending_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reference": { + "name": "reference", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "canceled_at": { + "name": "canceled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_contract_organization_idx": { + "name": "billing_contract_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "effective_from", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_contract_pending_idx": { + "name": "billing_contract_pending_idx", + "columns": [ + { + "expression": "pending_expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_contract\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_contract_organization_id_organization_id_fk": { + "name": "billing_contract_organization_id_organization_id_fk", + "tableFrom": "billing_contract", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_contract_account_id_billing_account_id_fk": { + "name": "billing_contract_account_id_billing_account_id_fk", + "tableFrom": "billing_contract", + "tableTo": "billing_account", + "columnsFrom": [ + "account_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_contract_created_by_user_id_user_id_fk": { + "name": "billing_contract_created_by_user_id_user_id_fk", + "tableFrom": "billing_contract", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_counter": { + "name": "billing_counter", + "schema": "", + "columns": { + "name": { + "name": "name", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "value": { + "name": "value", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_credit_entry": { + "name": "billing_credit_entry", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "grant_id": { + "name": "grant_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "billing_credit_entry_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_credit_entry_grant_idx": { + "name": "billing_credit_entry_grant_idx", + "columns": [ + { + "expression": "grant_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_credit_entry_grant_id_billing_credit_grant_id_fk": { + "name": "billing_credit_entry_grant_id_billing_credit_grant_id_fk", + "tableFrom": "billing_credit_entry", + "tableTo": "billing_credit_grant", + "columnsFrom": [ + "grant_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_credit_grant": { + "name": "billing_credit_grant", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "billing_grant_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "amount": { + "name": "amount", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "meter": { + "name": "meter", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dimension": { + "name": "dimension", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scope": { + "name": "scope", + "type": "text[]", + "primaryKey": false, + "notNull": false + }, + "applies_to": { + "name": "applies_to", + "type": "billing_grant_applies_to", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'usage'" + }, + "source": { + "name": "source", + "type": "billing_grant_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "grant_key": { + "name": "grant_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contract_id": { + "name": "contract_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "effective_at": { + "name": "effective_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "voided_at": { + "name": "voided_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": { + "billing_credit_grant_organization_idx": { + "name": "billing_credit_grant_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "effective_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_credit_grant_invoice_idx": { + "name": "billing_credit_grant_invoice_idx", + "columns": [ + { + "expression": "invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_credit_grant\".\"invoice_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_credit_grant_organization_id_organization_id_fk": { + "name": "billing_credit_grant_organization_id_organization_id_fk", + "tableFrom": "billing_credit_grant", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_credit_grant_created_by_user_id_user_id_fk": { + "name": "billing_credit_grant_created_by_user_id_user_id_fk", + "tableFrom": "billing_credit_grant", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_credit_grant_key_unique": { + "name": "billing_credit_grant_key_unique", + "nullsNotDistinct": false, + "columns": [ + "grant_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_credit_note": { + "name": "billing_credit_note", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "number": { + "name": "number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "amount_cents": { + "name": "amount_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "refund_cents": { + "name": "refund_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "memo": { + "name": "memo", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "billing_credit_note_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "provider_credit_note_id": { + "name": "provider_credit_note_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sync_attempts": { + "name": "sync_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_sync_at": { + "name": "next_sync_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sync_error": { + "name": "sync_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_credit_note_invoice_idx": { + "name": "billing_credit_note_invoice_idx", + "columns": [ + { + "expression": "invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_credit_note_sync_idx": { + "name": "billing_credit_note_sync_idx", + "columns": [ + { + "expression": "next_sync_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_credit_note\".\"next_sync_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_credit_note_invoice_id_billing_invoice_id_fk": { + "name": "billing_credit_note_invoice_id_billing_invoice_id_fk", + "tableFrom": "billing_credit_note", + "tableTo": "billing_invoice", + "columnsFrom": [ + "invoice_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_credit_note_number_unique": { + "name": "billing_credit_note_number_unique", + "nullsNotDistinct": false, + "columns": [ + "number" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_hold": { + "name": "billing_hold", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "billing_hold_reason", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "billing_hold_organization_id_organization_id_fk": { + "name": "billing_hold_organization_id_organization_id_fk", + "tableFrom": "billing_hold", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "billing_hold_organization_id_reason_pk": { + "name": "billing_hold_organization_id_reason_pk", + "columns": [ + "organization_id", + "reason" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_invoice": { + "name": "billing_invoice", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_name": { + "name": "organization_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_slug": { + "name": "organization_slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "number": { + "name": "number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "billing_invoice_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "billing_invoice_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "currency": { + "name": "currency", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'usd'" + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "period_end": { + "name": "period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "subtotal_cents": { + "name": "subtotal_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "discount_cents": { + "name": "discount_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "credit_cents": { + "name": "credit_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "tax_cents": { + "name": "tax_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "total_cents": { + "name": "total_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "amount_paid_cents": { + "name": "amount_paid_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "amount_due_cents": { + "name": "amount_due_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": "0" + }, + "collection_method": { + "name": "collection_method", + "type": "billing_collection_method", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "billing_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider_customer_id": { + "name": "provider_customer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_invoice_id": { + "name": "provider_invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hosted_url": { + "name": "hosted_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "pdf_url": { + "name": "pdf_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "billing_email": { + "name": "billing_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "due_at": { + "name": "due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "finalized_at": { + "name": "finalized_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "paid_at": { + "name": "paid_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "voided_at": { + "name": "voided_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sync_action": { + "name": "sync_action", + "type": "billing_sync_action", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "sync_attempts": { + "name": "sync_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_sync_at": { + "name": "next_sync_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sync_error": { + "name": "sync_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "collection_attempts": { + "name": "collection_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_collection_at": { + "name": "next_collection_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "payment_state": { + "name": "payment_state", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "payment_error": { + "name": "payment_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "terms_snapshot": { + "name": "terms_snapshot", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "memo": { + "name": "memo", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_invoice_organization_idx": { + "name": "billing_invoice_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_period_idx": { + "name": "billing_invoice_period_idx", + "columns": [ + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_invoice\".\"kind\" = 'period' and \"billing_invoice\".\"status\" <> 'void'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_final_idx": { + "name": "billing_invoice_final_idx", + "columns": [ + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_invoice\".\"kind\" = 'final' and \"billing_invoice\".\"status\" <> 'void'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_sync_idx": { + "name": "billing_invoice_sync_idx", + "columns": [ + { + "expression": "next_sync_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_invoice\".\"next_sync_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_collection_idx": { + "name": "billing_invoice_collection_idx", + "columns": [ + { + "expression": "next_collection_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_invoice\".\"next_collection_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_created_at_idx": { + "name": "billing_invoice_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_invoice_number_unique": { + "name": "billing_invoice_number_unique", + "nullsNotDistinct": false, + "columns": [ + "number" + ] + }, + "billing_invoice_provider_unique": { + "name": "billing_invoice_provider_unique", + "nullsNotDistinct": false, + "columns": [ + "provider_invoice_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_invoice_line": { + "name": "billing_invoice_line", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "billing_line_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "meter": { + "name": "meter", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dimension": { + "name": "dimension", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "quantity": { + "name": "quantity", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "covered_units": { + "name": "covered_units", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "unit_nanos": { + "name": "unit_nanos", + "type": "bigint", + "primaryKey": false, + "notNull": false + }, + "amount_cents": { + "name": "amount_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "period_end": { + "name": "period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "contract_id": { + "name": "contract_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "grant_id": { + "name": "grant_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "charge_key": { + "name": "charge_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "detail": { + "name": "detail", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "billing_invoice_line_invoice_idx": { + "name": "billing_invoice_line_invoice_idx", + "columns": [ + { + "expression": "invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "position", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_line_charge_key_idx": { + "name": "billing_invoice_line_charge_key_idx", + "columns": [ + { + "expression": "charge_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"billing_invoice_line\".\"charge_key\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_invoice_line_contract_idx": { + "name": "billing_invoice_line_contract_idx", + "columns": [ + { + "expression": "contract_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_invoice_line\".\"contract_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_invoice_line_invoice_id_billing_invoice_id_fk": { + "name": "billing_invoice_line_invoice_id_billing_invoice_id_fk", + "tableFrom": "billing_invoice_line", + "tableTo": "billing_invoice", + "columnsFrom": [ + "invoice_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_notification": { + "name": "billing_notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "billing_notification_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "recipients": { + "name": "recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_notification_next_attempt_idx": { + "name": "billing_notification_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_notification\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_notification_created_at_idx": { + "name": "billing_notification_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_notification_organization_id_organization_id_fk": { + "name": "billing_notification_organization_id_organization_id_fk", + "tableFrom": "billing_notification", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_notification_user_id_user_id_fk": { + "name": "billing_notification_user_id_user_id_fk", + "tableFrom": "billing_notification", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_notification_dedupe_unique": { + "name": "billing_notification_dedupe_unique", + "nullsNotDistinct": false, + "columns": [ + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_payment": { + "name": "billing_payment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "amount_cents": { + "name": "amount_cents", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reference": { + "name": "reference", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_payment_id": { + "name": "provider_payment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "received_at": { + "name": "received_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "recorded_by_user_id": { + "name": "recorded_by_user_id", + "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()" + } + }, + "indexes": { + "billing_payment_invoice_idx": { + "name": "billing_payment_invoice_idx", + "columns": [ + { + "expression": "invoice_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_payment_invoice_id_billing_invoice_id_fk": { + "name": "billing_payment_invoice_id_billing_invoice_id_fk", + "tableFrom": "billing_payment", + "tableTo": "billing_invoice", + "columnsFrom": [ + "invoice_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "billing_payment_provider_unique": { + "name": "billing_payment_provider_unique", + "nullsNotDistinct": false, + "columns": [ + "provider_payment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_period": { + "name": "billing_period", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "period_end": { + "name": "period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "invoice_id": { + "name": "invoice_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage": { + "name": "usage", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "warnings": { + "name": "warnings", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "billing_period_account_start_idx": { + "name": "billing_period_account_start_idx", + "columns": [ + { + "expression": "account_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_period_organization_id_organization_id_fk": { + "name": "billing_period_organization_id_organization_id_fk", + "tableFrom": "billing_period", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "billing_period_account_id_billing_account_id_fk": { + "name": "billing_period_account_id_billing_account_id_fk", + "tableFrom": "billing_period", + "tableTo": "billing_account", + "columnsFrom": [ + "account_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_provider_event": { + "name": "billing_provider_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "billing_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider_event_id": { + "name": "provider_event_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "billing_provider_event_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "processed_at": { + "name": "processed_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": { + "billing_provider_event_unique_idx": { + "name": "billing_provider_event_unique_idx", + "columns": [ + { + "expression": "provider", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "provider_event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_provider_event_next_attempt_idx": { + "name": "billing_provider_event_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"billing_provider_event\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "billing_provider_event_created_at_idx": { + "name": "billing_provider_event_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_quota": { + "name": "billing_quota", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "meter": { + "name": "meter", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_start": { + "name": "period_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "reserved": { + "name": "reserved", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "billing_quota_organization_id_organization_id_fk": { + "name": "billing_quota_organization_id_organization_id_fk", + "tableFrom": "billing_quota", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "billing_quota_organization_id_meter_period_start_pk": { + "name": "billing_quota_organization_id_meter_period_start_pk", + "columns": [ + "organization_id", + "meter", + "period_start" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_usage": { + "name": "billing_usage", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hour_start": { + "name": "hour_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "meter": { + "name": "meter", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dimension": { + "name": "dimension", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "shard": { + "name": "shard", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "quantity": { + "name": "quantity", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "billing_usage_hour_idx": { + "name": "billing_usage_hour_idx", + "columns": [ + { + "expression": "hour_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_usage_organization_id_organization_id_fk": { + "name": "billing_usage_organization_id_organization_id_fk", + "tableFrom": "billing_usage", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "billing_usage_organization_id_hour_start_meter_dimension_environment_id_shard_pk": { + "name": "billing_usage_organization_id_hour_start_meter_dimension_environment_id_shard_pk", + "columns": [ + "organization_id", + "hour_start", + "meter", + "dimension", + "environment_id", + "shard" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.billing_usage_attribution": { + "name": "billing_usage_attribution", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hour_start": { + "name": "hour_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "meter": { + "name": "meter", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dimension": { + "name": "dimension", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "shard": { + "name": "shard", + "type": "smallint", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "quantity": { + "name": "quantity", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "billing_usage_attribution_hour_idx": { + "name": "billing_usage_attribution_hour_idx", + "columns": [ + { + "expression": "hour_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "billing_usage_attribution_organization_id_organization_id_fk": { + "name": "billing_usage_attribution_organization_id_organization_id_fk", + "tableFrom": "billing_usage_attribution", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "billing_usage_attribution_pk": { + "name": "billing_usage_attribution_pk", + "columns": [ + "organization_id", + "hour_start", + "meter", + "dimension", + "environment_id", + "api_key_id", + "user_id", + "shard" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.admin_audit_event": { + "name": "admin_audit_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "admin_audit_event_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "actor_user_id": { + "name": "actor_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_email": { + "name": "actor_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "admin_audit_event_target_idx": { + "name": "admin_audit_event_target_idx", + "columns": [ + { + "expression": "target_type", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "target_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "admin_audit_event_organization_idx": { + "name": "admin_audit_event_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"admin_audit_event\".\"organization_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "admin_audit_event_created_at_idx": { + "name": "admin_audit_event_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audience": { + "name": "audience", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "audience_environment_fk": { + "name": "audience_environment_fk", + "tableFrom": "audience", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "audience_environment_name_unique": { + "name": "audience_environment_name_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "name" + ] + }, + "audience_id_organization_unique": { + "name": "audience_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.audience_member": { + "name": "audience_member", + "schema": "", + "columns": { + "audience_id": { + "name": "audience_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "contact_id": { + "name": "contact_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "audience_member_contact_idx": { + "name": "audience_member_contact_idx", + "columns": [ + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "audience_member_audience_fk": { + "name": "audience_member_audience_fk", + "tableFrom": "audience_member", + "tableTo": "audience", + "columnsFrom": [ + "audience_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "audience_member_contact_fk": { + "name": "audience_member_contact_fk", + "tableFrom": "audience_member", + "tableTo": "contact", + "columnsFrom": [ + "contact_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "audience_member_audience_id_contact_id_pk": { + "name": "audience_member_audience_id_contact_id_pk", + "columns": [ + "audience_id", + "contact_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.auth_email": { + "name": "auth_email", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "auth_email_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "to": { + "name": "to", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "auth_email_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "auth_email_next_attempt_idx": { + "name": "auth_email_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"auth_email\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.broadcast": { + "name": "broadcast", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_owner_id": { + "name": "api_key_owner_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "broadcast_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "audience_id": { + "name": "audience_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "segment_id": { + "name": "segment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "topic": { + "name": "topic", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "from": { + "name": "from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reply_to": { + "name": "reply_to", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "preview_text": { + "name": "preview_text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "html": { + "name": "html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "track_opens": { + "name": "track_opens", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "track_clicks": { + "name": "track_clicks", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "rate_per_second": { + "name": "rate_per_second", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "started_at": { + "name": "started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "canceled_at": { + "name": "canceled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "contact_upper_bound": { + "name": "contact_upper_bound", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cursor": { + "name": "cursor", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "recipients_estimated": { + "name": "recipients_estimated", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "materialized": { + "name": "materialized", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "screening_status": { + "name": "screening_status", + "type": "broadcast_screening_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "screening_held_at": { + "name": "screening_held_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_run_at": { + "name": "next_run_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "pause_reason": { + "name": "pause_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "broadcast_environment_created_at_idx": { + "name": "broadcast_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "broadcast_due_idx": { + "name": "broadcast_due_idx", + "columns": [ + { + "expression": "next_run_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"broadcast\".\"status\" in ('scheduled', 'sending')", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "broadcast_environment_fk": { + "name": "broadcast_environment_fk", + "tableFrom": "broadcast", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "broadcast_id_organization_unique": { + "name": "broadcast_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "broadcast_environment_idempotency_key_unique": { + "name": "broadcast_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": { + "broadcast_target_check": { + "name": "broadcast_target_check", + "value": "(\"broadcast\".\"audience_id\" is null) <> (\"broadcast\".\"segment_id\" is null)" + } + }, + "isRLSEnabled": false + }, + "public.broadcast_stat": { + "name": "broadcast_stat", + "schema": "", + "columns": { + "broadcast_id": { + "name": "broadcast_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "shard": { + "name": "shard", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "recipients": { + "name": "recipients", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "sent": { + "name": "sent", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "delivered": { + "name": "delivered", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "bounced": { + "name": "bounced", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "complained": { + "name": "complained", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "failed": { + "name": "failed", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "opened": { + "name": "opened", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "clicked": { + "name": "clicked", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "unsubscribed": { + "name": "unsubscribed", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": {}, + "foreignKeys": { + "broadcast_stat_broadcast_fk": { + "name": "broadcast_stat_broadcast_fk", + "tableFrom": "broadcast_stat", + "tableTo": "broadcast", + "columnsFrom": [ + "broadcast_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "broadcast_stat_broadcast_id_shard_pk": { + "name": "broadcast_stat_broadcast_id_shard_pk", + "columns": [ + "broadcast_id", + "shard" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contact": { + "name": "contact", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "contact_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "address": { + "name": "address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "first_name": { + "name": "first_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_name": { + "name": "last_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "contact_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'subscribed'" + }, + "properties": { + "name": "properties", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "source": { + "name": "source", + "type": "contact_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "subscribed_at": { + "name": "subscribed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "unsubscribed_at": { + "name": "unsubscribed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "pending_since": { + "name": "pending_since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "confirmation_sent_at": { + "name": "confirmation_sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "confirmation_count": { + "name": "confirmation_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "confirmed_at": { + "name": "confirmed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "contact_environment_sequence_idx": { + "name": "contact_environment_sequence_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "contact_environment_id_idx": { + "name": "contact_environment_id_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "contact_properties_idx": { + "name": "contact_properties_idx", + "columns": [ + { + "expression": "properties", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "jsonb_path_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + }, + "contact_pending_since_idx": { + "name": "contact_pending_since_idx", + "columns": [ + { + "expression": "pending_since", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"contact\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "contact_environment_fk": { + "name": "contact_environment_fk", + "tableFrom": "contact", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "contact_environment_address_unique": { + "name": "contact_environment_address_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "address" + ] + }, + "contact_id_organization_unique": { + "name": "contact_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contact_counter": { + "name": "contact_counter", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "contact_counter_environment_fk": { + "name": "contact_counter_environment_fk", + "tableFrom": "contact_counter", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "contact_counter_count_check": { + "name": "contact_counter_count_check", + "value": "\"contact_counter\".\"count\" >= 0" + } + }, + "isRLSEnabled": false + }, + "public.contact_property": { + "name": "contact_property", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "contact_property_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "fallback": { + "name": "fallback", + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "contact_property_environment_fk": { + "name": "contact_property_environment_fk", + "tableFrom": "contact_property", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "contact_property_environment_key_unique": { + "name": "contact_property_environment_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.contact_topic": { + "name": "contact_topic", + "schema": "", + "columns": { + "contact_id": { + "name": "contact_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "topic_id": { + "name": "topic_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "contact_topic_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "contact_source", + "typeSchema": "public", + "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": { + "contact_topic_topic_status_idx": { + "name": "contact_topic_topic_status_idx", + "columns": [ + { + "expression": "topic_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "contact_topic_contact_fk": { + "name": "contact_topic_contact_fk", + "tableFrom": "contact_topic", + "tableTo": "contact", + "columnsFrom": [ + "contact_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "contact_topic_topic_fk": { + "name": "contact_topic_topic_fk", + "tableFrom": "contact_topic", + "tableTo": "topic", + "columnsFrom": [ + "topic_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "contact_topic_contact_id_topic_id_pk": { + "name": "contact_topic_contact_id_topic_id_pk", + "columns": [ + "contact_id", + "topic_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.content_screening": { + "name": "content_screening", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "product": { + "name": "product", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject_id": { + "name": "subject_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "classifier": { + "name": "classifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "model": { + "name": "model", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "verdict": { + "name": "verdict", + "type": "content_screening_verdict", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "enforced": { + "name": "enforced", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "scores": { + "name": "scores", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "top_category": { + "name": "top_category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "top_score": { + "name": "top_score", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "input_tokens": { + "name": "input_tokens", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "latency_ms": { + "name": "latency_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "content_screening_organization_created_at_idx": { + "name": "content_screening_organization_created_at_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_screening_created_at_idx": { + "name": "content_screening_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "content_screening_subject_idx": { + "name": "content_screening_subject_idx", + "columns": [ + { + "expression": "product", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "subject_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "content_screening_environment_fk": { + "name": "content_screening_environment_fk", + "tableFrom": "content_screening", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.content_screening_counter": { + "name": "content_screening_counter", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "product": { + "name": "product", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "seen": { + "name": "seen", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "owed": { + "name": "owed", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "content_screening_counter_organization_id_organization_id_fk": { + "name": "content_screening_counter_organization_id_organization_id_fk", + "tableFrom": "content_screening_counter", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "content_screening_counter_organization_id_product_group_id_pk": { + "name": "content_screening_counter_organization_id_product_group_id_pk", + "columns": [ + "organization_id", + "product", + "group_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dedicated_ip_delivery_rollup": { + "name": "dedicated_ip_delivery_rollup", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hour": { + "name": "hour", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "sending_ip": { + "name": "sending_ip", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "delivered": { + "name": "delivered", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "dedicated_ip_delivery_rollup_hour_idx": { + "name": "dedicated_ip_delivery_rollup_hour_idx", + "columns": [ + { + "expression": "hour", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dedicated_ip_delivery_rollup_organization_id_organization_id_fk": { + "name": "dedicated_ip_delivery_rollup_organization_id_organization_id_fk", + "tableFrom": "dedicated_ip_delivery_rollup", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "dedicated_ip_delivery_rollup_organization_id_hour_sending_ip_pk": { + "name": "dedicated_ip_delivery_rollup_organization_id_hour_sending_ip_pk", + "columns": [ + "organization_id", + "hour", + "sending_ip" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dedicated_ip_pool": { + "name": "dedicated_ip_pool", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "dedicated_ip_pool_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "ips": { + "name": "ips", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "dedicated_share": { + "name": "dedicated_share", + "type": "real", + "primaryKey": false, + "notNull": false + }, + "status_message": { + "name": "status_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_checked_at": { + "name": "last_checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "provisioned_at": { + "name": "provisioned_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "ready_at": { + "name": "ready_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "release_after": { + "name": "release_after", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "release_started_at": { + "name": "release_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "tls_required_at": { + "name": "tls_required_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "marketing_configured_at": { + "name": "marketing_configured_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "dedicated_ip_pool_next_check_at_idx": { + "name": "dedicated_ip_pool_next_check_at_idx", + "columns": [ + { + "expression": "next_check_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"dedicated_ip_pool\".\"next_check_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dedicated_ip_pool_organization_id_organization_id_fk": { + "name": "dedicated_ip_pool_organization_id_organization_id_fk", + "tableFrom": "dedicated_ip_pool", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "dedicated_ip_pool_organization_unique": { + "name": "dedicated_ip_pool_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dmarc_notification": { + "name": "dmarc_notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_id": { + "name": "domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "dmarc_notification_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "policy_changed_at": { + "name": "policy_changed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "detail": { + "name": "detail", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "dmarc_notification_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "recipients": { + "name": "recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "dmarc_notification_due_idx": { + "name": "dmarc_notification_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"dmarc_notification\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_notification_created_at_idx": { + "name": "dmarc_notification_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dmarc_notification_domain_fk": { + "name": "dmarc_notification_domain_fk", + "tableFrom": "dmarc_notification", + "tableTo": "domain", + "columnsFrom": [ + "domain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "dmarc_notification_dedupe_unique": { + "name": "dmarc_notification_dedupe_unique", + "nullsNotDistinct": false, + "columns": [ + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dmarc_report": { + "name": "dmarc_report", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_id": { + "name": "domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reporter_org": { + "name": "reporter_org", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reporter_email": { + "name": "reporter_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "report_id": { + "name": "report_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_begin": { + "name": "period_begin", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "period_end": { + "name": "period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "policy_published": { + "name": "policy_published", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "message_count": { + "name": "message_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "pass_count": { + "name": "pass_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "truncated": { + "name": "truncated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "dmarc_report_domain_period_idx": { + "name": "dmarc_report_domain_period_idx", + "columns": [ + { + "expression": "domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_end", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_report_domain_id_idx": { + "name": "dmarc_report_domain_id_idx", + "columns": [ + { + "expression": "domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_report_created_at_idx": { + "name": "dmarc_report_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_report_organization_idx": { + "name": "dmarc_report_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dmarc_report_domain_fk": { + "name": "dmarc_report_domain_fk", + "tableFrom": "dmarc_report", + "tableTo": "domain", + "columnsFrom": [ + "domain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "dmarc_report_reporter_unique": { + "name": "dmarc_report_reporter_unique", + "nullsNotDistinct": false, + "columns": [ + "domain_id", + "reporter_org", + "report_id" + ] + }, + "dmarc_report_id_organization_unique": { + "name": "dmarc_report_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.dmarc_report_record": { + "name": "dmarc_report_record", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_id": { + "name": "domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dmarc_report_id": { + "name": "dmarc_report_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period_begin": { + "name": "period_begin", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "period_end": { + "name": "period_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "source_ip": { + "name": "source_ip", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "disposition": { + "name": "disposition", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dkim": { + "name": "dkim", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "spf": { + "name": "spf", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dmarc_pass": { + "name": "dmarc_pass", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "header_from": { + "name": "header_from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "envelope_from": { + "name": "envelope_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auth_results": { + "name": "auth_results", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "reasons": { + "name": "reasons", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "via_coss": { + "name": "via_coss", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "dmarc_report_record_report_idx": { + "name": "dmarc_report_record_report_idx", + "columns": [ + { + "expression": "dmarc_report_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "position", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_report_record_domain_period_idx": { + "name": "dmarc_report_record_domain_period_idx", + "columns": [ + { + "expression": "domain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "period_end", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "dmarc_report_record_organization_idx": { + "name": "dmarc_report_record_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "dmarc_report_record_report_fk": { + "name": "dmarc_report_record_report_fk", + "tableFrom": "dmarc_report_record", + "tableTo": "dmarc_report", + "columnsFrom": [ + "dmarc_report_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.domain": { + "name": "domain", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "domain_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "can_send": { + "name": "can_send", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "region": { + "name": "region", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dkim_tokens": { + "name": "dkim_tokens", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "dkim_hosted_zone": { + "name": "dkim_hosted_zone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mail_from_domain": { + "name": "mail_from_domain", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mail_from_status": { + "name": "mail_from_status", + "type": "mail_from_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "records": { + "name": "records", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "bimi": { + "name": "bimi", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "verification_started_at": { + "name": "verification_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_checked_at": { + "name": "last_checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "verified_at": { + "name": "verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "failed_at": { + "name": "failed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "dmarc_report_token": { + "name": "dmarc_report_token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dmarc_record": { + "name": "dmarc_record", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dmarc_inherited_record": { + "name": "dmarc_inherited_record", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dmarc_policy_changed_at": { + "name": "dmarc_policy_changed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subaccount_id": { + "name": "subaccount_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "shared_with_subaccounts": { + "name": "shared_with_subaccounts", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "domain_subaccount_idx": { + "name": "domain_subaccount_idx", + "columns": [ + { + "expression": "subaccount_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"domain\".\"subaccount_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "domain_name_active_unique": { + "name": "domain_name_active_unique", + "columns": [ + { + "expression": "name", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"domain\".\"status\" <> 'failed'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "domain_organization_idx": { + "name": "domain_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "domain_next_check_at_idx": { + "name": "domain_next_check_at_idx", + "columns": [ + { + "expression": "next_check_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"domain\".\"next_check_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "domain_organization_id_organization_id_fk": { + "name": "domain_organization_id_organization_id_fk", + "tableFrom": "domain", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "domain_created_by_user_id_user_id_fk": { + "name": "domain_created_by_user_id_user_id_fk", + "tableFrom": "domain", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "domain_subaccount_fk": { + "name": "domain_subaccount_fk", + "tableFrom": "domain", + "tableTo": "email_subaccount", + "columnsFrom": [ + "subaccount_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "domain_dmarc_report_token_unique": { + "name": "domain_dmarc_report_token_unique", + "nullsNotDistinct": false, + "columns": [ + "dmarc_report_token" + ] + }, + "domain_id_organization_unique": { + "name": "domain_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "domain_shared_not_subaccount": { + "name": "domain_shared_not_subaccount", + "value": "not (\"domain\".\"shared_with_subaccounts\" and \"domain\".\"subaccount_id\" is not null)" + } + }, + "isRLSEnabled": false + }, + "public.email": { + "name": "email", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_owner_id": { + "name": "api_key_owner_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "email_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "from": { + "name": "from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to": { + "name": "to", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "cc": { + "name": "cc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "bcc": { + "name": "bcc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "reply_to": { + "name": "reply_to", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "html": { + "name": "html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "discard_body": { + "name": "discard_body", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "screening_exempt": { + "name": "screening_exempt", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "store_content": { + "name": "store_content", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "content_discarded_at": { + "name": "content_discarded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "headers": { + "name": "headers", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stream": { + "name": "stream", + "type": "email_stream", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'transactional'" + }, + "track_opens": { + "name": "track_opens", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "track_clicks": { + "name": "track_clicks", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "unsubscribe": { + "name": "unsubscribe", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "tracking_token": { + "name": "tracking_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "open_count": { + "name": "open_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "first_opened_at": { + "name": "first_opened_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_opened_at": { + "name": "last_opened_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "click_count": { + "name": "click_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "first_clicked_at": { + "name": "first_clicked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_clicked_at": { + "name": "last_clicked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "batch_id": { + "name": "batch_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "batch_index": { + "name": "batch_index", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "broadcast_id": { + "name": "broadcast_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contact_id": { + "name": "contact_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "variables": { + "name": "variables", + "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()" + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "billable_recipients": { + "name": "billable_recipients", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "template_version": { + "name": "template_version", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "template_locale": { + "name": "template_locale", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dedicated_pool": { + "name": "dedicated_pool", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "require_tls": { + "name": "require_tls", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "hipaa_origin": { + "name": "hipaa_origin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "subaccount_id": { + "name": "subaccount_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subaccount_tenant": { + "name": "subaccount_tenant", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "traceparent": { + "name": "traceparent", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "email_batch_idx": { + "name": "email_batch_idx", + "columns": [ + { + "expression": "batch_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "batch_index", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email\".\"batch_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_broadcast_contact_unique": { + "name": "email_broadcast_contact_unique", + "columns": [ + { + "expression": "broadcast_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "contact_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"email\".\"broadcast_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_broadcast_status_idx": { + "name": "email_broadcast_status_idx", + "columns": [ + { + "expression": "broadcast_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email\".\"broadcast_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_environment_created_at_idx": { + "name": "email_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_organization_created_at_idx": { + "name": "email_organization_created_at_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_organization_send_time_idx": { + "name": "email_organization_send_time_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"sent_at\", \"created_at\")", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_subaccount_send_time_idx": { + "name": "email_subaccount_send_time_idx", + "columns": [ + { + "expression": "subaccount_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"sent_at\", \"created_at\")", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email\".\"subaccount_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_scheduled_due_idx": { + "name": "email_scheduled_due_idx", + "columns": [ + { + "expression": "scheduled_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email\".\"status\" = 'scheduled'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_queued_created_at_idx": { + "name": "email_queued_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email\".\"status\" = 'queued'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_created_at_idx": { + "name": "email_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_environment_fk": { + "name": "email_environment_fk", + "tableFrom": "email", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "email_batch_fk": { + "name": "email_batch_fk", + "tableFrom": "email", + "tableTo": "email_batch", + "columnsFrom": [ + "batch_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_tracking_token_unique": { + "name": "email_tracking_token_unique", + "nullsNotDistinct": false, + "columns": [ + "tracking_token" + ] + }, + "email_environment_idempotency_key_unique": { + "name": "email_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + }, + "email_id_organization_unique": { + "name": "email_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_attachment": { + "name": "email_attachment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_id": { + "name": "content_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_attachment_email_fk": { + "name": "email_attachment_email_fk", + "tableFrom": "email_attachment", + "tableTo": "email", + "columnsFrom": [ + "email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_attachment_email_position_unique": { + "name": "email_attachment_email_position_unique", + "nullsNotDistinct": false, + "columns": [ + "email_id", + "position" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_batch": { + "name": "email_batch", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_batch_environment_fk": { + "name": "email_batch_environment_fk", + "tableFrom": "email_batch", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_batch_environment_idempotency_key_unique": { + "name": "email_batch_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + }, + "email_batch_id_organization_unique": { + "name": "email_batch_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_event": { + "name": "email_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "email_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_event_type": { + "name": "provider_event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "recipient": { + "name": "recipient", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "email_event_email_occurred_at_idx": { + "name": "email_event_email_occurred_at_idx", + "columns": [ + { + "expression": "email_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_event_email_fk": { + "name": "email_event_email_fk", + "tableFrom": "email_event", + "tableTo": "email", + "columnsFrom": [ + "email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_event_email_dedupe_unique": { + "name": "email_event_email_dedupe_unique", + "nullsNotDistinct": false, + "columns": [ + "email_id", + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_link": { + "name": "email_link", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "click_count": { + "name": "click_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "first_clicked_at": { + "name": "first_clicked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_clicked_at": { + "name": "last_clicked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_link_email_fk": { + "name": "email_link_email_fk", + "tableFrom": "email_link", + "tableTo": "email", + "columnsFrom": [ + "email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_link_email_position_unique": { + "name": "email_link_email_position_unique", + "nullsNotDistinct": false, + "columns": [ + "email_id", + "position" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_recipient": { + "name": "email_recipient", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "address": { + "name": "address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "email_recipient_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "email_recipient_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "last_event_at": { + "name": "last_event_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "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": { + "email_recipient_organization_address_idx": { + "name": "email_recipient_organization_address_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "address", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_recipient_email_fk": { + "name": "email_recipient_email_fk", + "tableFrom": "email_recipient", + "tableTo": "email", + "columnsFrom": [ + "email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_recipient_email_address_unique": { + "name": "email_recipient_email_address_unique", + "nullsNotDistinct": false, + "columns": [ + "email_id", + "address" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_reputation_rollup": { + "name": "email_reputation_rollup", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bucket_start": { + "name": "bucket_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "stream": { + "name": "stream", + "type": "email_stream", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'transactional'" + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "computed_revision": { + "name": "computed_revision", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "recipients": { + "name": "recipients", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "bounces": { + "name": "bounces", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "complaints": { + "name": "complaints", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "simulator_recipients": { + "name": "simulator_recipients", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "simulator_bounces": { + "name": "simulator_bounces", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "simulator_complaints": { + "name": "simulator_complaints", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_reputation_rollup_organization_id_organization_id_fk": { + "name": "email_reputation_rollup_organization_id_organization_id_fk", + "tableFrom": "email_reputation_rollup", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "email_reputation_rollup_organization_id_bucket_start_stream_pk": { + "name": "email_reputation_rollup_organization_id_bucket_start_stream_pk", + "columns": [ + "organization_id", + "bucket_start", + "stream" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_sender_domain_block": { + "name": "email_sender_domain_block", + "schema": "", + "columns": { + "domain": { + "name": "domain", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subject_id": { + "name": "subject_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "email_sender_domain_block_organization_idx": { + "name": "email_sender_domain_block_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_storage_settings": { + "name": "email_storage_settings", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "store_content": { + "name": "store_content", + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_storage_settings_environment_fk": { + "name": "email_storage_settings_environment_fk", + "tableFrom": "email_storage_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_subaccount": { + "name": "email_subaccount", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "uid": { + "name": "uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "email_subaccount_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "daily_recipient_limit": { + "name": "daily_recipient_limit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "per_second_recipient_limit": { + "name": "per_second_recipient_limit", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "per_second_burst": { + "name": "per_second_burst", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "reputation_status": { + "name": "reputation_status", + "type": "email_subaccount_reputation", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'good'" + }, + "reputation_trigger": { + "name": "reputation_trigger", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reputation_changed_at": { + "name": "reputation_changed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "reinstated_at": { + "name": "reinstated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "metrics": { + "name": "metrics", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_evaluation_at": { + "name": "next_evaluation_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "evaluation_lease_until": { + "name": "evaluation_lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "deletion_lease_until": { + "name": "deletion_lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "deletion_attempts": { + "name": "deletion_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "email_subaccount_environment_created_at_idx": { + "name": "email_subaccount_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_subaccount_next_evaluation_idx": { + "name": "email_subaccount_next_evaluation_idx", + "columns": [ + { + "expression": "next_evaluation_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email_subaccount\".\"next_evaluation_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_subaccount_deleting_idx": { + "name": "email_subaccount_deleting_idx", + "columns": [ + { + "expression": "deletion_lease_until", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email_subaccount\".\"status\" = 'deleting'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_subaccount_environment_fk": { + "name": "email_subaccount_environment_fk", + "tableFrom": "email_subaccount", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_subaccount_environment_uid_unique": { + "name": "email_subaccount_environment_uid_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "uid" + ] + }, + "email_subaccount_id_organization_unique": { + "name": "email_subaccount_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_suppression": { + "name": "email_suppression", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "email_suppression_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "address": { + "name": "address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "email_suppression_reason", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subaccount_id": { + "name": "subaccount_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "email_suppression_subaccount_sequence_idx": { + "name": "email_suppression_subaccount_sequence_idx", + "columns": [ + { + "expression": "subaccount_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"email_suppression\".\"subaccount_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "email_suppression_environment_sequence_idx": { + "name": "email_suppression_environment_sequence_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_suppression_environment_fk": { + "name": "email_suppression_environment_fk", + "tableFrom": "email_suppression", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "email_suppression_subaccount_fk": { + "name": "email_suppression_subaccount_fk", + "tableFrom": "email_suppression", + "tableTo": "email_subaccount", + "columnsFrom": [ + "subaccount_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_suppression_environment_subaccount_address_scope_unique": { + "name": "email_suppression_environment_subaccount_address_scope_unique", + "nullsNotDistinct": true, + "columns": [ + "environment_id", + "subaccount_id", + "address", + "scope" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_template": { + "name": "email_template", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "alias": { + "name": "alias", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "published_version": { + "name": "published_version", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "published_at": { + "name": "published_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()" + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "email_template_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + } + }, + "indexes": { + "email_template_environment_created_at_idx": { + "name": "email_template_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_template_environment_fk": { + "name": "email_template_environment_fk", + "tableFrom": "email_template", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_template_environment_alias_unique": { + "name": "email_template_environment_alias_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "alias" + ] + }, + "email_template_id_organization_unique": { + "name": "email_template_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_template_content": { + "name": "email_template_content", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "version_id": { + "name": "version_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "locale": { + "name": "locale", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "html": { + "name": "html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_template_content_version_fk": { + "name": "email_template_content_version_fk", + "tableFrom": "email_template_content", + "tableTo": "email_template_version", + "columnsFrom": [ + "version_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_template_content_version_locale_unique": { + "name": "email_template_content_version_locale_unique", + "nullsNotDistinct": false, + "columns": [ + "version_id", + "locale" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_template_version": { + "name": "email_template_version", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "default_locale": { + "name": "default_locale", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "variables": { + "name": "variables", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "sample_variables": { + "name": "sample_variables", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "has_unpublished_changes": { + "name": "has_unpublished_changes", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "published_at": { + "name": "published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "email_template_version_draft_unique": { + "name": "email_template_version_draft_unique", + "columns": [ + { + "expression": "template_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"email_template_version\".\"version\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "email_template_version_template_fk": { + "name": "email_template_version_template_fk", + "tableFrom": "email_template_version", + "tableTo": "email_template", + "columnsFrom": [ + "template_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_template_version_template_version_unique": { + "name": "email_template_version_template_version_unique", + "nullsNotDistinct": false, + "columns": [ + "template_id", + "version" + ] + }, + "email_template_version_id_organization_unique": { + "name": "email_template_version_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_tenant": { + "name": "email_tenant", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subaccount_id": { + "name": "subaccount_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "stream": { + "name": "stream", + "type": "email_stream", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'transactional'" + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "tenant_name": { + "name": "tenant_name", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "tenant_arn": { + "name": "tenant_arn", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sending_status": { + "name": "sending_status", + "type": "tenant_sending_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'enabled'" + }, + "suppression_migrated_at": { + "name": "suppression_migrated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "status_cause": { + "name": "status_cause", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_updated_at": { + "name": "status_updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_tenant_organization_id_organization_id_fk": { + "name": "email_tenant_organization_id_organization_id_fk", + "tableFrom": "email_tenant", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "email_tenant_subaccount_fk": { + "name": "email_tenant_subaccount_fk", + "tableFrom": "email_tenant", + "tableTo": "email_subaccount", + "columnsFrom": [ + "subaccount_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_tenant_owner_stream_unique": { + "name": "email_tenant_owner_stream_unique", + "nullsNotDistinct": true, + "columns": [ + "organization_id", + "subaccount_id", + "stream" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.email_tracking_rule": { + "name": "email_tracking_rule", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "opens": { + "name": "opens", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "clicks": { + "name": "clicks", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "unsubscribe": { + "name": "unsubscribe", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "email_tracking_rule_environment_fk": { + "name": "email_tracking_rule_environment_fk", + "tableFrom": "email_tracking_rule", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "email_tracking_rule_environment_category_unique": { + "name": "email_tracking_rule_environment_category_unique", + "nullsNotDistinct": true, + "columns": [ + "environment_id", + "category" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.environment": { + "name": "environment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mode": { + "name": "mode", + "type": "environment_mode", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "personal_keys": { + "name": "personal_keys", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "environment_organization_idx": { + "name": "environment_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "environment_project_fk": { + "name": "environment_project_fk", + "tableFrom": "environment", + "tableTo": "project", + "columnsFrom": [ + "project_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "environment_project_slug_unique": { + "name": "environment_project_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "project_id", + "slug" + ] + }, + "environment_id_organization_unique": { + "name": "environment_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.environment_api_key": { + "name": "environment_api_key", + "schema": "", + "columns": { + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "access": { + "name": "access", + "type": "api_key_access", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'full'" + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "owner_user_id": { + "name": "owner_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "environment_api_key_environment_idx": { + "name": "environment_api_key_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "environment_api_key_owner_idx": { + "name": "environment_api_key_owner_idx", + "columns": [ + { + "expression": "owner_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "environment_api_key_api_key_id_apikey_id_fk": { + "name": "environment_api_key_api_key_id_apikey_id_fk", + "tableFrom": "environment_api_key", + "tableTo": "apikey", + "columnsFrom": [ + "api_key_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_api_key_environment_id_environment_id_fk": { + "name": "environment_api_key_environment_id_environment_id_fk", + "tableFrom": "environment_api_key", + "tableTo": "environment", + "columnsFrom": [ + "environment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "environment_api_key_created_by_user_id_user_id_fk": { + "name": "environment_api_key_created_by_user_id_user_id_fk", + "tableFrom": "environment_api_key", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "environment_api_key_owner_user_id_user_id_fk": { + "name": "environment_api_key_owner_user_id_user_id_fk", + "tableFrom": "environment_api_key", + "tableTo": "user", + "columnsFrom": [ + "owner_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.environment_inbound_address": { + "name": "environment_inbound_address", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "environment_inbound_address_environment_fk": { + "name": "environment_inbound_address_environment_fk", + "tableFrom": "environment_inbound_address", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "environment_inbound_address_label_unique": { + "name": "environment_inbound_address_label_unique", + "nullsNotDistinct": false, + "columns": [ + "label" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hipaa_session_activity": { + "name": "hipaa_session_activity", + "schema": "", + "columns": { + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "last_active_at": { + "name": "last_active_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "hipaa_session_activity_session_id_session_id_fk": { + "name": "hipaa_session_activity_session_id_session_id_fk", + "tableFrom": "hipaa_session_activity", + "tableTo": "session", + "columnsFrom": [ + "session_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_application": { + "name": "hook_application", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "uid": { + "name": "uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "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": { + "hook_application_environment_created_at_idx": { + "name": "hook_application_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_application_environment_fk": { + "name": "hook_application_environment_fk", + "tableFrom": "hook_application", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_application_environment_uid_unique": { + "name": "hook_application_environment_uid_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "uid" + ] + }, + "hook_application_id_organization_unique": { + "name": "hook_application_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_attempt": { + "name": "hook_attempt", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_created_at": { + "name": "message_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "delivery_id": { + "name": "delivery_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "endpoint_id": { + "name": "endpoint_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempted_at": { + "name": "attempted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "response_excerpt": { + "name": "response_excerpt", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "hook_attempt_delivery_idx": { + "name": "hook_attempt_delivery_idx", + "columns": [ + { + "expression": "delivery_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "attempted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_attempt_environment_idx": { + "name": "hook_attempt_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "message_created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "hook_attempt_pkey": { + "name": "hook_attempt_pkey", + "columns": [ + "message_created_at", + "id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_delivery": { + "name": "hook_delivery", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_created_at": { + "name": "message_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "endpoint_id": { + "name": "endpoint_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "hook_delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "lease_expires_at": { + "name": "lease_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_status_code": { + "name": "last_status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "hook_delivery_due_idx": { + "name": "hook_delivery_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"hook_delivery\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_delivery_endpoint_idx": { + "name": "hook_delivery_endpoint_idx", + "columns": [ + { + "expression": "endpoint_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "message_created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_delivery_environment_idx": { + "name": "hook_delivery_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "message_created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "hook_delivery_pkey": { + "name": "hook_delivery_pkey", + "columns": [ + "message_created_at", + "id" + ] + } + }, + "uniqueConstraints": { + "hook_delivery_message_endpoint_unique": { + "name": "hook_delivery_message_endpoint_unique", + "nullsNotDistinct": false, + "columns": [ + "message_created_at", + "message_id", + "endpoint_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_delivery_rollup": { + "name": "hook_delivery_rollup", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hour": { + "name": "hour", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "succeeded": { + "name": "succeeded", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "failed": { + "name": "failed", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + } + }, + "indexes": { + "hook_delivery_rollup_hour_idx": { + "name": "hook_delivery_rollup_hour_idx", + "columns": [ + { + "expression": "hour", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_delivery_rollup_organization_id_organization_id_fk": { + "name": "hook_delivery_rollup_organization_id_organization_id_fk", + "tableFrom": "hook_delivery_rollup", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "hook_delivery_rollup_pkey": { + "name": "hook_delivery_rollup_pkey", + "columns": [ + "organization_id", + "hour" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_endpoint": { + "name": "hook_endpoint", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filter_types": { + "name": "filter_types", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "secret_ciphertext": { + "name": "secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "previous_secret_ciphertext": { + "name": "previous_secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previous_secret_expires_at": { + "name": "previous_secret_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "rate_limit_per_second": { + "name": "rate_limit_per_second", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "disabled_reason": { + "name": "disabled_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "failing_since": { + "name": "failing_since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "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": { + "hook_endpoint_application_idx": { + "name": "hook_endpoint_application_idx", + "columns": [ + { + "expression": "application_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_endpoint_application_fk": { + "name": "hook_endpoint_application_fk", + "tableFrom": "hook_endpoint", + "tableTo": "hook_application", + "columnsFrom": [ + "application_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_endpoint_id_organization_unique": { + "name": "hook_endpoint_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "hook_endpoint_previous_secret_check": { + "name": "hook_endpoint_previous_secret_check", + "value": "(\"hook_endpoint\".\"previous_secret_ciphertext\" is null) = (\"hook_endpoint\".\"previous_secret_expires_at\" is null)" + }, + "hook_endpoint_disabled_check": { + "name": "hook_endpoint_disabled_check", + "value": "\"hook_endpoint\".\"enabled\" = (\"hook_endpoint\".\"disabled_reason\" is null) and (\"hook_endpoint\".\"disabled_reason\" is null) = (\"hook_endpoint\".\"disabled_at\" is null)" + }, + "hook_endpoint_rate_limit_check": { + "name": "hook_endpoint_rate_limit_check", + "value": "\"hook_endpoint\".\"rate_limit_per_second\" is null or \"hook_endpoint\".\"rate_limit_per_second\" > 0" + } + }, + "isRLSEnabled": false + }, + "public.hook_endpoint_recovery": { + "name": "hook_endpoint_recovery", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "endpoint_id": { + "name": "endpoint_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "since": { + "name": "since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "until": { + "name": "until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "hook_recovery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "cursor_created_at": { + "name": "cursor_created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cursor_id": { + "name": "cursor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requeued": { + "name": "requeued", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "lease_expires_at": { + "name": "lease_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "hook_endpoint_recovery_pending_idx": { + "name": "hook_endpoint_recovery_pending_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"hook_endpoint_recovery\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_endpoint_recovery_endpoint_idx": { + "name": "hook_endpoint_recovery_endpoint_idx", + "columns": [ + { + "expression": "endpoint_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_endpoint_recovery_endpoint_fk": { + "name": "hook_endpoint_recovery_endpoint_fk", + "tableFrom": "hook_endpoint_recovery", + "tableTo": "hook_endpoint", + "columnsFrom": [ + "endpoint_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_event_type": { + "name": "hook_event_type", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "schema": { + "name": "schema", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "examples": { + "name": "examples", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "hook_event_type_environment_fk": { + "name": "hook_event_type_environment_fk", + "tableFrom": "hook_event_type", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_event_type_environment_name_unique": { + "name": "hook_event_type_environment_name_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_idempotency_key": { + "name": "hook_idempotency_key", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_created_at": { + "name": "message_created_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": { + "hook_idempotency_key_created_at_idx": { + "name": "hook_idempotency_key_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_idempotency_key_environment_fk": { + "name": "hook_idempotency_key_environment_fk", + "tableFrom": "hook_idempotency_key", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_idempotency_key_environment_key_unique": { + "name": "hook_idempotency_key_environment_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_message": { + "name": "hook_message", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type": { + "name": "event_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "payload_bytes": { + "name": "payload_bytes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "only_endpoint_id": { + "name": "only_endpoint_id", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "hook_message_application_created_at_idx": { + "name": "hook_message_application_created_at_idx", + "columns": [ + { + "expression": "application_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_message_environment_created_at_idx": { + "name": "hook_message_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "hook_message_pkey": { + "name": "hook_message_pkey", + "columns": [ + "created_at", + "id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_portal_session": { + "name": "hook_portal_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "application_id": { + "name": "application_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "read_only": { + "name": "read_only", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "hook_portal_session_expires_at_idx": { + "name": "hook_portal_session_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "hook_portal_session_organization_idx": { + "name": "hook_portal_session_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "hook_portal_session_created_by_user_id_user_id_fk": { + "name": "hook_portal_session_created_by_user_id_user_id_fk", + "tableFrom": "hook_portal_session", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "hook_portal_session_application_fk": { + "name": "hook_portal_session_application_fk", + "tableFrom": "hook_portal_session", + "tableTo": "hook_application", + "columnsFrom": [ + "application_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_portal_session_token_hash_unique": { + "name": "hook_portal_session_token_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "token_hash" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.hook_portal_settings": { + "name": "hook_portal_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "allowed_origins": { + "name": "allowed_origins", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "accent_color": { + "name": "accent_color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "theme": { + "name": "theme", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'system'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "hook_portal_settings_environment_fk": { + "name": "hook_portal_settings_environment_fk", + "tableFrom": "hook_portal_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "hook_portal_settings_environment_unique": { + "name": "hook_portal_settings_environment_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.inbound_drop_counter": { + "name": "inbound_drop_counter", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "day": { + "name": "day", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "inbound_drop_counter_organization_id_organization_id_fk": { + "name": "inbound_drop_counter_organization_id_organization_id_fk", + "tableFrom": "inbound_drop_counter", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "inbound_drop_counter_pk": { + "name": "inbound_drop_counter_pk", + "columns": [ + "organization_id", + "day" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.inbound_fake_object": { + "name": "inbound_fake_object", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "inbound_fake_object_organization_idx": { + "name": "inbound_fake_object_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbound_fake_object_created_at_idx": { + "name": "inbound_fake_object_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.log_drain": { + "name": "log_drain", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sources": { + "name": "sources", + "type": "log_drain_source[]", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'{}'::log_drain_source[]" + }, + "secret_ciphertext": { + "name": "secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "format": { + "name": "format", + "type": "log_drain_format", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'ndjson'" + }, + "auth_header_name": { + "name": "auth_header_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auth_header_ciphertext": { + "name": "auth_header_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "disabled_reason": { + "name": "disabled_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "log_drain_environment_idx": { + "name": "log_drain_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_drain\".\"enabled\"", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "log_drain_created_by_user_id_user_id_fk": { + "name": "log_drain_created_by_user_id_user_id_fk", + "tableFrom": "log_drain", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "log_drain_environment_fk": { + "name": "log_drain_environment_fk", + "tableFrom": "log_drain", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "log_drain_id_organization_unique": { + "name": "log_drain_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "log_drain_auth_header_check": { + "name": "log_drain_auth_header_check", + "value": "(\"log_drain\".\"auth_header_name\" is null) = (\"log_drain\".\"auth_header_ciphertext\" is null)" + } + }, + "isRLSEnabled": false + }, + "public.log_drain_attempt": { + "name": "log_drain_attempt", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "batch_id": { + "name": "batch_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempted_at": { + "name": "attempted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "response_excerpt": { + "name": "response_excerpt", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "log_drain_attempt_batch_idx": { + "name": "log_drain_attempt_batch_idx", + "columns": [ + { + "expression": "batch_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "attempted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "log_drain_attempt_batch_fk": { + "name": "log_drain_attempt_batch_fk", + "tableFrom": "log_drain_attempt", + "tableTo": "log_drain_batch", + "columnsFrom": [ + "batch_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.log_drain_batch": { + "name": "log_drain_batch", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "drain_id": { + "name": "drain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "log_drain_batch_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "record_count": { + "name": "record_count", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "lease_expires_at": { + "name": "lease_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_status_code": { + "name": "last_status_code", + "type": "integer", + "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()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "log_drain_batch_pending_unique": { + "name": "log_drain_batch_pending_unique", + "columns": [ + { + "expression": "drain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"log_drain_batch\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_drain_batch_due_idx": { + "name": "log_drain_batch_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_drain_batch\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_drain_batch_drain_created_at_idx": { + "name": "log_drain_batch_drain_created_at_idx", + "columns": [ + { + "expression": "drain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_drain_batch_updated_at_idx": { + "name": "log_drain_batch_updated_at_idx", + "columns": [ + { + "expression": "updated_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_drain_batch\".\"status\" <> 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "log_drain_batch_drain_fk": { + "name": "log_drain_batch_drain_fk", + "tableFrom": "log_drain_batch", + "tableTo": "log_drain", + "columnsFrom": [ + "drain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "log_drain_batch_id_organization_unique": { + "name": "log_drain_batch_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.log_drain_record": { + "name": "log_drain_record", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "drain_id": { + "name": "drain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "batch_id": { + "name": "batch_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source": { + "name": "source", + "type": "log_drain_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "source_id": { + "name": "source_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "line": { + "name": "line", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "byte_size": { + "name": "byte_size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "log_drain_record_queued_idx": { + "name": "log_drain_record_queued_idx", + "columns": [ + { + "expression": "drain_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_drain_record\".\"batch_id\" is null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_drain_record_batch_idx": { + "name": "log_drain_record_batch_idx", + "columns": [ + { + "expression": "batch_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "log_drain_record_drain_fk": { + "name": "log_drain_record_drain_fk", + "tableFrom": "log_drain_record", + "tableTo": "log_drain", + "columnsFrom": [ + "drain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "log_drain_record_batch_fk": { + "name": "log_drain_record_batch_fk", + "tableFrom": "log_drain_record", + "tableTo": "log_drain_batch", + "columnsFrom": [ + "batch_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "log_drain_record_drain_source_unique": { + "name": "log_drain_record_drain_source_unique", + "nullsNotDistinct": false, + "columns": [ + "drain_id", + "source_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.log_entry": { + "name": "log_entry", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "log_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "level": { + "name": "level", + "type": "log_level", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "method": { + "name": "method", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "route": { + "name": "route", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "client_ip": { + "name": "client_ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "resource_type": { + "name": "resource_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "resource_id": { + "name": "resource_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "recipient": { + "name": "recipient", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attributes": { + "name": "attributes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "search_text": { + "name": "search_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + } + }, + "indexes": { + "log_entry_environment_occurred_at_idx": { + "name": "log_entry_environment_occurred_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_entry_environment_request_idx": { + "name": "log_entry_environment_request_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_entry\".\"request_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_entry_environment_resource_idx": { + "name": "log_entry_environment_resource_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "resource_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"log_entry\".\"resource_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "log_entry_search_text_idx": { + "name": "log_entry_search_text_idx", + "columns": [ + { + "expression": "search_text", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "gin_trgm_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + } + }, + "foreignKeys": { + "log_entry_environment_fk": { + "name": "log_entry_environment_fk", + "tableFrom": "log_entry", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "log_entry_pkey": { + "name": "log_entry_pkey", + "columns": [ + "occurred_at", + "id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.marketing_settings": { + "name": "marketing_settings", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "mailing_address": { + "name": "mailing_address", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_from": { + "name": "confirmation_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_subject": { + "name": "confirmation_subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_html": { + "name": "confirmation_html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_text": { + "name": "confirmation_text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmed_redirect_url": { + "name": "confirmed_redirect_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "double_opt_in_default": { + "name": "double_opt_in_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "marketing_settings_environment_fk": { + "name": "marketing_settings_environment_fk", + "tableFrom": "marketing_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.migration": { + "name": "migration", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "migration_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "migration_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'inspecting'" + }, + "credentials_ciphertext": { + "name": "credentials_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "credential_hint": { + "name": "credential_hint", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "inventory": { + "name": "inventory", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "selection": { + "name": "selection", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "phase": { + "name": "phase", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "cursor": { + "name": "cursor", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "progress": { + "name": "progress", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_run_at": { + "name": "next_run_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "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 + }, + "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": { + "migration_environment_created_at_idx": { + "name": "migration_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "migration_due_idx": { + "name": "migration_due_idx", + "columns": [ + { + "expression": "next_run_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"migration\".\"status\" in ('inspecting', 'queued', 'running')", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "migration_created_by_user_id_user_id_fk": { + "name": "migration_created_by_user_id_user_id_fk", + "tableFrom": "migration", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "migration_environment_fk": { + "name": "migration_environment_fk", + "tableFrom": "migration", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "migration_id_organization_unique": { + "name": "migration_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.migration_item": { + "name": "migration_item", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "migration_id": { + "name": "migration_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "migration_item_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "source_id": { + "name": "source_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "source_name": { + "name": "source_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_id": { + "name": "target_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target_name": { + "name": "target_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "outcome": { + "name": "outcome", + "type": "migration_item_outcome", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "needs_review": { + "name": "needs_review", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "warnings": { + "name": "warnings", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "migration_item_migration_fk": { + "name": "migration_item_migration_fk", + "tableFrom": "migration_item", + "tableTo": "migration", + "columnsFrom": [ + "migration_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "migration_item_source_unique": { + "name": "migration_item_source_unique", + "nullsNotDistinct": false, + "columns": [ + "migration_id", + "kind", + "source_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.org_audit_event": { + "name": "org_audit_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "org_audit_event_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_type": { + "name": "actor_type", + "type": "org_audit_actor_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor_label": { + "name": "actor_label", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "target_type": { + "name": "target_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target_id": { + "name": "target_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "target_label": { + "name": "target_label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "client_ip": { + "name": "client_ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "org_audit_event_organization_idx": { + "name": "org_audit_event_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "org_audit_event_organization_action_idx": { + "name": "org_audit_event_organization_action_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "action", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "org_audit_event_organization_id_organization_id_fk": { + "name": "org_audit_event_organization_id_organization_id_fk", + "tableFrom": "org_audit_event", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_api_version": { + "name": "organization_api_version", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "api_version": { + "name": "api_version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "updated_by_user_id": { + "name": "updated_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "organization_api_version_organization_id_organization_id_fk": { + "name": "organization_api_version_organization_id_organization_id_fk", + "tableFrom": "organization_api_version", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "organization_api_version_updated_by_user_id_user_id_fk": { + "name": "organization_api_version_updated_by_user_id_user_id_fk", + "tableFrom": "organization_api_version", + "tableTo": "user", + "columnsFrom": [ + "updated_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_deletion": { + "name": "organization_deletion", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_name": { + "name": "organization_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_slug": { + "name": "organization_slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "requested_by_user_id": { + "name": "requested_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requested_by_email": { + "name": "requested_by_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "by_platform_admin": { + "name": "by_platform_admin", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "status": { + "name": "status", + "type": "organization_deletion_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false, + "default": "now()" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "organization_deletion_next_attempt_idx": { + "name": "organization_deletion_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"organization_deletion\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "organization_deletion_org_unique": { + "name": "organization_deletion_org_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_hipaa_mode": { + "name": "organization_hipaa_mode", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "baa_signed_at": { + "name": "baa_signed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "baa_reference": { + "name": "baa_reference", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled_by_user_id": { + "name": "enabled_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "organization_hipaa_mode_organization_id_organization_id_fk": { + "name": "organization_hipaa_mode_organization_id_organization_id_fk", + "tableFrom": "organization_hipaa_mode", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "organization_hipaa_mode_enabled_by_user_id_user_id_fk": { + "name": "organization_hipaa_mode_enabled_by_user_id_user_id_fk", + "tableFrom": "organization_hipaa_mode", + "tableTo": "user", + "columnsFrom": [ + "enabled_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_logo": { + "name": "organization_logo", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "status": { + "name": "status", + "type": "organization_logo_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "source_url": { + "name": "source_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "image": { + "name": "image", + "type": "bytea", + "primaryKey": false, + "notNull": false + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "failures": { + "name": "failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "checked_at": { + "name": "checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "organization_logo_organization_id_organization_id_fk": { + "name": "organization_logo_organization_id_organization_id_fk", + "tableFrom": "organization_logo", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.organization_suspension": { + "name": "organization_suspension", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "suspended_by_user_id": { + "name": "suspended_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "organization_suspension_organization_id_organization_id_fk": { + "name": "organization_suspension_organization_id_organization_id_fk", + "tableFrom": "organization_suspension", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "organization_suspension_suspended_by_user_id_user_id_fk": { + "name": "organization_suspension_suspended_by_user_id_user_id_fk", + "tableFrom": "organization_suspension", + "tableTo": "user", + "columnsFrom": [ + "suspended_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.product_preference": { + "name": "product_preference", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "product": { + "name": "product", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "pinned": { + "name": "pinned", + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "product_preference_organization_id_organization_id_fk": { + "name": "product_preference_organization_id_organization_id_fk", + "tableFrom": "product_preference", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "product_preference_user_id_user_id_fk": { + "name": "product_preference_user_id_user_id_fk", + "tableFrom": "product_preference", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "product_preference_member_unique": { + "name": "product_preference_member_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "user_id", + "product" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.project": { + "name": "project", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "slug": { + "name": "slug", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "project_organization_id_organization_id_fk": { + "name": "project_organization_id_organization_id_fk", + "tableFrom": "project", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "project_organization_slug_unique": { + "name": "project_organization_slug_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "slug" + ] + }, + "project_id_organization_unique": { + "name": "project_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.rate_limit_override": { + "name": "rate_limit_override", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "bucket": { + "name": "bucket", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "limit": { + "name": "limit", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "period_ms": { + "name": "period_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "burst": { + "name": "burst", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "rate_limit_override_organization_id_organization_id_fk": { + "name": "rate_limit_override_organization_id_organization_id_fk", + "tableFrom": "rate_limit_override", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "rate_limit_override_organization_bucket_unique": { + "name": "rate_limit_override_organization_bucket_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "bucket" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.received_email": { + "name": "received_email", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "received_email_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "blocked_reason": { + "name": "blocked_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "mail_from": { + "name": "mail_from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "recipients": { + "name": "recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "from": { + "name": "from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "to": { + "name": "to", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "cc": { + "name": "cc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "reply_to": { + "name": "reply_to", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "in_reply_to": { + "name": "in_reply_to", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "references": { + "name": "references", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "headers": { + "name": "headers", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "text": { + "name": "text", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "html": { + "name": "html", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "truncated": { + "name": "truncated", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "spam_verdict": { + "name": "spam_verdict", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "virus_verdict": { + "name": "virus_verdict", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "spf_verdict": { + "name": "spf_verdict", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dkim_verdict": { + "name": "dkim_verdict", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dmarc_verdict": { + "name": "dmarc_verdict", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "dmarc_policy": { + "name": "dmarc_policy", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "raw_key": { + "name": "raw_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "received_at": { + "name": "received_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": { + "received_email_environment_id_idx": { + "name": "received_email_environment_id_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "received_email_created_at_idx": { + "name": "received_email_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "received_email_organization_idx": { + "name": "received_email_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "received_email_environment_fk": { + "name": "received_email_environment_fk", + "tableFrom": "received_email", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "received_email_provider_message_unique": { + "name": "received_email_provider_message_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "provider", + "provider_message_id" + ] + }, + "received_email_id_organization_unique": { + "name": "received_email_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.received_email_attachment": { + "name": "received_email_attachment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "received_email_id": { + "name": "received_email_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_id": { + "name": "content_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "disposition": { + "name": "disposition", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_key": { + "name": "content_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "received_email_attachment_email_fk": { + "name": "received_email_attachment_email_fk", + "tableFrom": "received_email_attachment", + "tableTo": "received_email", + "columnsFrom": [ + "received_email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "received_email_attachment_position_unique": { + "name": "received_email_attachment_position_unique", + "nullsNotDistinct": false, + "columns": [ + "received_email_id", + "position" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.receiving_domain": { + "name": "receiving_domain", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_id": { + "name": "domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "record": { + "name": "record", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "last_checked_at": { + "name": "last_checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "receiving_domain_environment_idx": { + "name": "receiving_domain_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "receiving_domain_next_check_at_idx": { + "name": "receiving_domain_next_check_at_idx", + "columns": [ + { + "expression": "next_check_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"receiving_domain\".\"next_check_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "receiving_domain_domain_fk": { + "name": "receiving_domain_domain_fk", + "tableFrom": "receiving_domain", + "tableTo": "domain", + "columnsFrom": [ + "domain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "receiving_domain_environment_fk": { + "name": "receiving_domain_environment_fk", + "tableFrom": "receiving_domain", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "receiving_domain_domain_unique": { + "name": "receiving_domain_domain_unique", + "nullsNotDistinct": false, + "columns": [ + "domain_id" + ] + }, + "receiving_domain_hostname_unique": { + "name": "receiving_domain_hostname_unique", + "nullsNotDistinct": false, + "columns": [ + "hostname" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reputation_event": { + "name": "reputation_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "reputation_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "trigger": { + "name": "trigger", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor": { + "name": "actor", + "type": "reputation_actor", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "actor_user_id": { + "name": "actor_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "metrics": { + "name": "metrics", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "reputation_event_organization_created_at_idx": { + "name": "reputation_event_organization_created_at_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "reputation_event_organization_id_organization_id_fk": { + "name": "reputation_event_organization_id_organization_id_fk", + "tableFrom": "reputation_event", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "reputation_event_actor_user_id_user_id_fk": { + "name": "reputation_event_actor_user_id_user_id_fk", + "tableFrom": "reputation_event", + "tableTo": "user", + "columnsFrom": [ + "actor_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "reputation_event_id_organization_unique": { + "name": "reputation_event_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reputation_notification": { + "name": "reputation_notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reputation_event_id": { + "name": "reputation_event_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "reputation_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "reputation_notification_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "recipients": { + "name": "recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "reputation_notification_event_idx": { + "name": "reputation_notification_event_idx", + "columns": [ + { + "expression": "reputation_event_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "reputation_notification_next_attempt_idx": { + "name": "reputation_notification_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"reputation_notification\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "reputation_notification_organization_id_organization_id_fk": { + "name": "reputation_notification_organization_id_organization_id_fk", + "tableFrom": "reputation_notification", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "reputation_notification_event_fk": { + "name": "reputation_notification_event_fk", + "tableFrom": "reputation_notification", + "tableTo": "reputation_event", + "columnsFrom": [ + "reputation_event_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.reputation_standing": { + "name": "reputation_standing", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "status": { + "name": "status", + "type": "reputation_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'good'" + }, + "reason": { + "name": "reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status_changed_at": { + "name": "status_changed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "reinstated_at": { + "name": "reinstated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "marketing_paused_at": { + "name": "marketing_paused_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "marketing_reason": { + "name": "marketing_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "marketing_reinstated_at": { + "name": "marketing_reinstated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "policy_overrides": { + "name": "policy_overrides", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "metrics": { + "name": "metrics", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "last_evaluated_at": { + "name": "last_evaluated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "revision": { + "name": "revision", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "evaluation_lease_until": { + "name": "evaluation_lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_evaluation_at": { + "name": "next_evaluation_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "reputation_standing_next_evaluation_idx": { + "name": "reputation_standing_next_evaluation_idx", + "columns": [ + { + "expression": "next_evaluation_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"reputation_standing\".\"next_evaluation_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "reputation_standing_organization_id_organization_id_fk": { + "name": "reputation_standing_organization_id_organization_id_fk", + "tableFrom": "reputation_standing", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_assessment": { + "name": "risk_assessment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "risk_assessment_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event": { + "name": "event", + "type": "risk_event", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "event_name": { + "name": "event_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip": { + "name": "ip", + "type": "inet", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_hash": { + "name": "email_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip_hash": { + "name": "ip_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subnet_hash": { + "name": "subnet_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "card_hash": { + "name": "card_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "device_hash": { + "name": "device_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "decision": { + "name": "decision", + "type": "risk_decision", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "score": { + "name": "score", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "reasons": { + "name": "reasons", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "signals": { + "name": "signals", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "degraded": { + "name": "degraded", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "outcome": { + "name": "outcome", + "type": "risk_outcome", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "outcome_at": { + "name": "outcome_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "review_status": { + "name": "review_status", + "type": "risk_review_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "personal_data_purged_at": { + "name": "personal_data_purged_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": { + "risk_assessment_environment_sequence_idx": { + "name": "risk_assessment_environment_sequence_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_assessment_environment_user_idx": { + "name": "risk_assessment_environment_user_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"risk_assessment\".\"user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_assessment_open_review_idx": { + "name": "risk_assessment_open_review_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"risk_assessment\".\"review_status\" = 'open'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_assessment_created_at_idx": { + "name": "risk_assessment_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_assessment_personal_data_idx": { + "name": "risk_assessment_personal_data_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"risk_assessment\".\"personal_data_purged_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_assessment_environment_fk": { + "name": "risk_assessment_environment_fk", + "tableFrom": "risk_assessment", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_assessment_id_organization_unique": { + "name": "risk_assessment_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "risk_assessment_environment_idempotency_key_unique": { + "name": "risk_assessment_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_assessment_preparation": { + "name": "risk_assessment_preparation", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "content": { + "name": "content", + "type": "jsonb", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "risk_assessment_preparation_created_idx": { + "name": "risk_assessment_preparation_created_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_assessment_preparation_environment_id_environment_id_fk": { + "name": "risk_assessment_preparation_environment_id_environment_id_fk", + "tableFrom": "risk_assessment_preparation", + "tableTo": "environment", + "columnsFrom": [ + "environment_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "risk_assessment_preparation_environment_id_idempotency_key_pk": { + "name": "risk_assessment_preparation_environment_id_idempotency_key_pk", + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_dataset": { + "name": "risk_dataset", + "schema": "", + "columns": { + "name": { + "name": "name", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "entries": { + "name": "entries", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "checked_at": { + "name": "checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_domain_age": { + "name": "risk_domain_age", + "schema": "", + "columns": { + "domain": { + "name": "domain", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "registered_at": { + "name": "registered_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "checked_at": { + "name": "checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_feedback": { + "name": "risk_feedback", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "assessment_id": { + "name": "assessment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "outcome": { + "name": "outcome", + "type": "risk_outcome", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "source": { + "name": "source", + "type": "risk_feedback_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "actor_id": { + "name": "actor_id", + "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()" + } + }, + "indexes": { + "risk_feedback_assessment_idx": { + "name": "risk_feedback_assessment_idx", + "columns": [ + { + "expression": "assessment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_feedback_assessment_fk": { + "name": "risk_feedback_assessment_fk", + "tableFrom": "risk_feedback", + "tableTo": "risk_assessment", + "columnsFrom": [ + "assessment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_identity": { + "name": "risk_identity", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "risk_identity_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "value_hash": { + "name": "value_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "assessment_id": { + "name": "assessment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "first_seen_at": { + "name": "first_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "risk_identity_environment_user_idx": { + "name": "risk_identity_environment_user_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"risk_identity\".\"user_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_identity_last_seen_idx": { + "name": "risk_identity_last_seen_idx", + "columns": [ + { + "expression": "last_seen_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_identity_environment_fk": { + "name": "risk_identity_environment_fk", + "tableFrom": "risk_identity", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_identity_value_user_unique": { + "name": "risk_identity_value_user_unique", + "nullsNotDistinct": true, + "columns": [ + "environment_id", + "kind", + "value_hash", + "user_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_limit_bucket": { + "name": "risk_limit_bucket", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "limit": { + "name": "limit", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "period_ms": { + "name": "period_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "burst": { + "name": "burst", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "on_failure": { + "name": "on_failure", + "type": "risk_limit_failure_mode", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'allow'" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "risk_limit_bucket_environment_fk": { + "name": "risk_limit_bucket_environment_fk", + "tableFrom": "risk_limit_bucket", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_limit_bucket_name_unique": { + "name": "risk_limit_bucket_name_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "name" + ] + } + }, + "policies": {}, + "checkConstraints": { + "risk_limit_bucket_values_check": { + "name": "risk_limit_bucket_values_check", + "value": "\"risk_limit_bucket\".\"limit\" > 0 and \"risk_limit_bucket\".\"period_ms\" > 0 and \"risk_limit_bucket\".\"burst\" > 0" + } + }, + "isRLSEnabled": false + }, + "public.risk_list_entry": { + "name": "risk_list_entry", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "risk_list_entry_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "list": { + "name": "list", + "type": "risk_list", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "risk_list_entry_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "network": { + "name": "network", + "type": "cidr", + "primaryKey": false, + "notNull": false + }, + "note": { + "name": "note", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_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": { + "risk_list_entry_environment_sequence_idx": { + "name": "risk_list_entry_environment_sequence_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_list_entry_network_idx": { + "name": "risk_list_entry_network_idx", + "columns": [ + { + "expression": "network", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "inet_ops" + } + ], + "isUnique": false, + "where": "\"risk_list_entry\".\"network\" is not null", + "concurrently": false, + "method": "gist", + "with": {} + } + }, + "foreignKeys": { + "risk_list_entry_environment_fk": { + "name": "risk_list_entry_environment_fk", + "tableFrom": "risk_list_entry", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_list_entry_value_unique": { + "name": "risk_list_entry_value_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "list", + "type", + "value" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_report": { + "name": "risk_report", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "risk_report_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "value_hash": { + "name": "value_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "assessment_id": { + "name": "assessment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reported_at": { + "name": "reported_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "risk_report_assessment_idx": { + "name": "risk_report_assessment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "assessment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "risk_report_reported_at_idx": { + "name": "risk_report_reported_at_idx", + "columns": [ + { + "expression": "reported_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_report_environment_fk": { + "name": "risk_report_environment_fk", + "tableFrom": "risk_report", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_report_value_unique": { + "name": "risk_report_value_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "kind", + "value_hash", + "assessment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_rule": { + "name": "risk_rule", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "events": { + "name": "events", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "match": { + "name": "match", + "type": "risk_rule_match", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'all'" + }, + "conditions": { + "name": "conditions", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "action": { + "name": "action", + "type": "risk_decision", + "typeSchema": "public", + "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": { + "risk_rule_environment_position_idx": { + "name": "risk_rule_environment_position_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "position", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_rule_environment_fk": { + "name": "risk_rule_environment_fk", + "tableFrom": "risk_rule", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.risk_settings": { + "name": "risk_settings", + "schema": "", + "columns": { + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "review_threshold": { + "name": "review_threshold", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "block_threshold": { + "name": "block_threshold", + "type": "real", + "primaryKey": false, + "notNull": true + }, + "disabled_reasons": { + "name": "disabled_reasons", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "captcha_provider": { + "name": "captcha_provider", + "type": "risk_captcha_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "captcha_secret_ciphertext": { + "name": "captcha_secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "captcha_required": { + "name": "captcha_required", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "content_thresholds": { + "name": "content_thresholds", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "reason_weights": { + "name": "reason_weights", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "risk_settings_environment_fk": { + "name": "risk_settings_environment_fk", + "tableFrom": "risk_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "risk_settings_thresholds_check": { + "name": "risk_settings_thresholds_check", + "value": "\"risk_settings\".\"review_threshold\" > 0 and \"risk_settings\".\"review_threshold\" <= \"risk_settings\".\"block_threshold\" and \"risk_settings\".\"block_threshold\" <= 1" + }, + "risk_settings_captcha_check": { + "name": "risk_settings_captcha_check", + "value": "(\"risk_settings\".\"captcha_provider\" is null) = (\"risk_settings\".\"captcha_secret_ciphertext\" is null)" + } + }, + "isRLSEnabled": false + }, + "public.risk_user_network": { + "name": "risk_user_network", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_hash": { + "name": "user_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "risk_user_network_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "first_seen_at": { + "name": "first_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_seen_at": { + "name": "last_seen_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "risk_user_network_last_seen_idx": { + "name": "risk_user_network_last_seen_idx", + "columns": [ + { + "expression": "last_seen_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "risk_user_network_environment_fk": { + "name": "risk_user_network_environment_fk", + "tableFrom": "risk_user_network", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "risk_user_network_value_unique": { + "name": "risk_user_network_value_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "user_hash", + "kind", + "value" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scim_group_role": { + "name": "scim_group_role", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "group_name": { + "name": "group_name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "scim_group_role_organization_id_organization_id_fk": { + "name": "scim_group_role_organization_id_organization_id_fk", + "tableFrom": "scim_group_role", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scim_group_role_organization_group_unique": { + "name": "scim_group_role_organization_group_unique", + "nullsNotDistinct": false, + "columns": [ + "organization_id", + "group_name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.segment": { + "name": "segment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "filter": { + "name": "filter", + "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()" + } + }, + "indexes": {}, + "foreignKeys": { + "segment_environment_fk": { + "name": "segment_environment_fk", + "tableFrom": "segment", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "segment_environment_name_unique": { + "name": "segment_environment_name_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "name" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.topic": { + "name": "topic", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "key": { + "name": "key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "default_subscription": { + "name": "default_subscription", + "type": "topic_default_subscription", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "visibility": { + "name": "visibility", + "type": "topic_visibility", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'public'" + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "topic_environment_fk": { + "name": "topic_environment_fk", + "tableFrom": "topic", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "topic_environment_key_unique": { + "name": "topic_environment_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "key" + ] + }, + "topic_id_organization_unique": { + "name": "topic_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.tracking_domain": { + "name": "tracking_domain", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain_id": { + "name": "domain_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "hostname": { + "name": "hostname", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "tracking_domain_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_hostname_id": { + "name": "provider_hostname_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "record": { + "name": "record", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "provider_message": { + "name": "provider_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "verification_started_at": { + "name": "verification_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "last_checked_at": { + "name": "last_checked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "activated_at": { + "name": "activated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "failed_at": { + "name": "failed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "tracking_domain_hostname_active_unique": { + "name": "tracking_domain_hostname_active_unique", + "columns": [ + { + "expression": "hostname", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"tracking_domain\".\"status\" <> 'failed'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "tracking_domain_next_check_at_idx": { + "name": "tracking_domain_next_check_at_idx", + "columns": [ + { + "expression": "next_check_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"tracking_domain\".\"next_check_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "tracking_domain_domain_fk": { + "name": "tracking_domain_domain_fk", + "tableFrom": "tracking_domain", + "tableTo": "domain", + "columnsFrom": [ + "domain_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "tracking_domain_domain_unique": { + "name": "tracking_domain_domain_unique", + "nullsNotDistinct": false, + "columns": [ + "domain_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_attempt": { + "name": "webhook_attempt", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "delivery_id": { + "name": "delivery_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempted_at": { + "name": "attempted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "response_excerpt": { + "name": "response_excerpt", + "type": "text", + "primaryKey": false, + "notNull": false + } + }, + "indexes": { + "webhook_attempt_delivery_idx": { + "name": "webhook_attempt_delivery_idx", + "columns": [ + { + "expression": "delivery_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "attempted_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_attempt_delivery_fk": { + "name": "webhook_attempt_delivery_fk", + "tableFrom": "webhook_attempt", + "tableTo": "webhook_delivery", + "columnsFrom": [ + "delivery_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_delivery": { + "name": "webhook_delivery", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "endpoint_id": { + "name": "endpoint_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "webhook_delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "lease_expires_at": { + "name": "lease_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_status_code": { + "name": "last_status_code", + "type": "integer", + "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()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "webhook_delivery_due_idx": { + "name": "webhook_delivery_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"webhook_delivery\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "webhook_delivery_endpoint_created_at_idx": { + "name": "webhook_delivery_endpoint_created_at_idx", + "columns": [ + { + "expression": "endpoint_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_delivery_message_fk": { + "name": "webhook_delivery_message_fk", + "tableFrom": "webhook_delivery", + "tableTo": "webhook_message", + "columnsFrom": [ + "message_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "webhook_delivery_endpoint_fk": { + "name": "webhook_delivery_endpoint_fk", + "tableFrom": "webhook_delivery", + "tableTo": "webhook_endpoint", + "columnsFrom": [ + "endpoint_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhook_delivery_message_endpoint_unique": { + "name": "webhook_delivery_message_endpoint_unique", + "nullsNotDistinct": false, + "columns": [ + "message_id", + "endpoint_id" + ] + }, + "webhook_delivery_id_organization_unique": { + "name": "webhook_delivery_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_endpoint": { + "name": "webhook_endpoint", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_version": { + "name": "api_version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_types": { + "name": "event_types", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "secret_ciphertext": { + "name": "secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "previous_secret_ciphertext": { + "name": "previous_secret_ciphertext", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "previous_secret_expires_at": { + "name": "previous_secret_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "disabled_reason": { + "name": "disabled_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "disabled_at": { + "name": "disabled_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_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "webhook_endpoint_environment_idx": { + "name": "webhook_endpoint_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_endpoint_created_by_user_id_user_id_fk": { + "name": "webhook_endpoint_created_by_user_id_user_id_fk", + "tableFrom": "webhook_endpoint", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "webhook_endpoint_environment_fk": { + "name": "webhook_endpoint_environment_fk", + "tableFrom": "webhook_endpoint", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhook_endpoint_id_organization_unique": { + "name": "webhook_endpoint_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "webhook_endpoint_previous_secret_check": { + "name": "webhook_endpoint_previous_secret_check", + "value": "(\"webhook_endpoint\".\"previous_secret_ciphertext\" is null) = (\"webhook_endpoint\".\"previous_secret_expires_at\" is null)" + } + }, + "isRLSEnabled": false + }, + "public.webhook_listener": { + "name": "webhook_listener", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_version": { + "name": "api_version", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_types": { + "name": "event_types", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "description": { + "name": "description", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_api_key_id": { + "name": "created_by_api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_polled_at": { + "name": "last_polled_at", + "type": "timestamp with time zone", + "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": { + "webhook_listener_environment_expires_idx": { + "name": "webhook_listener_environment_expires_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "webhook_listener_expires_at_idx": { + "name": "webhook_listener_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_listener_environment_fk": { + "name": "webhook_listener_environment_fk", + "tableFrom": "webhook_listener", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhook_listener_id_organization_unique": { + "name": "webhook_listener_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_listener_delivery": { + "name": "webhook_listener_delivery", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "listener_id": { + "name": "listener_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "webhook_delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "handed_out_count": { + "name": "handed_out_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "lease_expires_at": { + "name": "lease_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "status_code": { + "name": "status_code", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "duration_ms": { + "name": "duration_ms", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "error": { + "name": "error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "forwarded_at": { + "name": "forwarded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "webhook_listener_delivery_pending_idx": { + "name": "webhook_listener_delivery_pending_idx", + "columns": [ + { + "expression": "listener_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, + "where": "\"webhook_listener_delivery\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "webhook_listener_delivery_listener_idx": { + "name": "webhook_listener_delivery_listener_idx", + "columns": [ + { + "expression": "listener_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_listener_delivery_listener_fk": { + "name": "webhook_listener_delivery_listener_fk", + "tableFrom": "webhook_listener_delivery", + "tableTo": "webhook_listener", + "columnsFrom": [ + "listener_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "webhook_listener_delivery_message_fk": { + "name": "webhook_listener_delivery_message_fk", + "tableFrom": "webhook_listener_delivery", + "tableTo": "webhook_message", + "columnsFrom": [ + "message_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhook_listener_delivery_message_listener_unique": { + "name": "webhook_listener_delivery_message_listener_unique", + "nullsNotDistinct": false, + "columns": [ + "message_id", + "listener_id" + ] + }, + "webhook_listener_delivery_id_organization_unique": { + "name": "webhook_listener_delivery_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.webhook_message": { + "name": "webhook_message", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "json", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "webhook_message_environment_idx": { + "name": "webhook_message_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "webhook_message_created_at_idx": { + "name": "webhook_message_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "webhook_message_environment_fk": { + "name": "webhook_message_environment_fk", + "tableFrom": "webhook_message", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "webhook_message_id_organization_unique": { + "name": "webhook_message_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form": { + "name": "form", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "enabled": { + "name": "enabled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "fields": { + "name": "fields", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "strict_fields": { + "name": "strict_fields", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "allowed_origins": { + "name": "allowed_origins", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "redirect_url": { + "name": "redirect_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "honeypot_field": { + "name": "honeypot_field", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'_gotcha'" + }, + "captcha": { + "name": "captcha", + "type": "form_captcha", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'off'" + }, + "captcha_site_key": { + "name": "captcha_site_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "on_review": { + "name": "on_review", + "type": "form_on_review", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'hold'" + }, + "content_threshold": { + "name": "content_threshold", + "type": "double precision", + "primaryKey": false, + "notNull": false, + "default": 0.9 + }, + "email_field": { + "name": "email_field", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'email'" + }, + "verify_submitter": { + "name": "verify_submitter", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "notify_recipients": { + "name": "notify_recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "notification_from": { + "name": "notification_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_from": { + "name": "confirmation_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "contacts": { + "name": "contacts", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "files": { + "name": "files", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "hosted": { + "name": "hosted", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "hosted_published_at": { + "name": "hosted_published_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "disabled_by_admin_at": { + "name": "disabled_by_admin_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_environment_created_at_idx": { + "name": "form_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "form_environment_fk": { + "name": "form_environment_fk", + "tableFrom": "form", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "form_id_organization_unique": { + "name": "form_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_delivery": { + "name": "form_delivery", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "submission_id": { + "name": "submission_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "form_delivery_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "form_delivery_state", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "delivered_at": { + "name": "delivered_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_delivery_due_idx": { + "name": "form_delivery_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"form_delivery\".\"state\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "form_delivery_submission_fk": { + "name": "form_delivery_submission_fk", + "tableFrom": "form_delivery", + "tableTo": "form_submission", + "columnsFrom": [ + "submission_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "form_delivery_submission_kind_unique": { + "name": "form_delivery_submission_kind_unique", + "nullsNotDistinct": false, + "columns": [ + "submission_id", + "kind" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_fake_object": { + "name": "form_fake_object", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_fake_object_organization_idx": { + "name": "form_fake_object_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_store_cleanup": { + "name": "form_store_cleanup", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_store_cleanup_next_attempt_at_idx": { + "name": "form_store_cleanup_next_attempt_at_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "form_store_cleanup_organization_idx": { + "name": "form_store_cleanup_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_submission": { + "name": "form_submission", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "form_id": { + "name": "form_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "form_submission_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "data": { + "name": "data", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "submitter_email": { + "name": "submitter_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ip": { + "name": "ip", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "user_agent": { + "name": "user_agent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "origin": { + "name": "origin", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "referrer": { + "name": "referrer", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "risk_assessment_id": { + "name": "risk_assessment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "risk_decision": { + "name": "risk_decision", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "risk_score": { + "name": "risk_score", + "type": "double precision", + "primaryKey": false, + "notNull": false + }, + "spam_reason": { + "name": "spam_reason", + "type": "form_spam_reason", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "confirmation_token_hash": { + "name": "confirmation_token_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "confirmation_expires_at": { + "name": "confirmation_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "confirmed_at": { + "name": "confirmed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "accepted_at": { + "name": "accepted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "released_at": { + "name": "released_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "released_by": { + "name": "released_by", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_submission_form_created_at_idx": { + "name": "form_submission_form_created_at_idx", + "columns": [ + { + "expression": "form_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "form_submission_created_at_idx": { + "name": "form_submission_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "form_submission_environment_idx": { + "name": "form_submission_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "form_submission_form_fk": { + "name": "form_submission_form_fk", + "tableFrom": "form_submission", + "tableTo": "form", + "columnsFrom": [ + "form_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "form_submission_confirmation_token_unique": { + "name": "form_submission_confirmation_token_unique", + "nullsNotDistinct": false, + "columns": [ + "confirmation_token_hash" + ] + }, + "form_submission_id_organization_unique": { + "name": "form_submission_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.form_submission_file": { + "name": "form_submission_file", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "submission_id": { + "name": "submission_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "field": { + "name": "field", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "store_key": { + "name": "store_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "form_submission_file_submission_idx": { + "name": "form_submission_file_submission_idx", + "columns": [ + { + "expression": "submission_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "form_submission_file_submission_fk": { + "name": "form_submission_file_submission_fk", + "tableFrom": "form_submission_file", + "tableTo": "form_submission", + "columnsFrom": [ + "submission_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.inbox": { + "name": "inbox", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "inbox_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "domain": { + "name": "domain", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "address": { + "name": "address", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "client_id": { + "name": "client_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "next_fee_at": { + "name": "next_fee_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "inbox_environment_id_idx": { + "name": "inbox_environment_id_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_organization_idx": { + "name": "inbox_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_next_fee_at_idx": { + "name": "inbox_next_fee_at_idx", + "columns": [ + { + "expression": "next_fee_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"inbox\".\"next_fee_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "inbox_environment_fk": { + "name": "inbox_environment_fk", + "tableFrom": "inbox", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "inbox_environment_address_unique": { + "name": "inbox_environment_address_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "address" + ] + }, + "inbox_environment_client_id_unique": { + "name": "inbox_environment_client_id_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "client_id" + ] + }, + "inbox_id_organization_unique": { + "name": "inbox_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.inbox_message": { + "name": "inbox_message", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "inbox_id": { + "name": "inbox_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "thread_id": { + "name": "thread_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "direction": { + "name": "direction", + "type": "inbox_message_direction", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "received_email_id": { + "name": "received_email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rfc_message_id": { + "name": "rfc_message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "inbox_message_thread_idx": { + "name": "inbox_message_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, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_message_inbox_id_idx": { + "name": "inbox_message_inbox_id_idx", + "columns": [ + { + "expression": "inbox_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_message_inbox_rfc_message_id_idx": { + "name": "inbox_message_inbox_rfc_message_id_idx", + "columns": [ + { + "expression": "inbox_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "rfc_message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"inbox_message\".\"rfc_message_id\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_message_received_email_idx": { + "name": "inbox_message_received_email_idx", + "columns": [ + { + "expression": "received_email_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_message_organization_idx": { + "name": "inbox_message_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "inbox_message_thread_fk": { + "name": "inbox_message_thread_fk", + "tableFrom": "inbox_message", + "tableTo": "inbox_thread", + "columnsFrom": [ + "thread_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "inbox_message_received_email_fk": { + "name": "inbox_message_received_email_fk", + "tableFrom": "inbox_message", + "tableTo": "received_email", + "columnsFrom": [ + "received_email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "inbox_message_email_fk": { + "name": "inbox_message_email_fk", + "tableFrom": "inbox_message", + "tableTo": "email", + "columnsFrom": [ + "email_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "inbox_message_inbox_received_email_unique": { + "name": "inbox_message_inbox_received_email_unique", + "nullsNotDistinct": false, + "columns": [ + "inbox_id", + "received_email_id" + ] + }, + "inbox_message_email_unique": { + "name": "inbox_message_email_unique", + "nullsNotDistinct": false, + "columns": [ + "email_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "inbox_message_source_check": { + "name": "inbox_message_source_check", + "value": "(\"inbox_message\".\"direction\" = 'inbound' and \"inbox_message\".\"received_email_id\" is not null and \"inbox_message\".\"email_id\" is null) or (\"inbox_message\".\"direction\" = 'outbound' and \"inbox_message\".\"email_id\" is not null and \"inbox_message\".\"received_email_id\" is null)" + } + }, + "isRLSEnabled": false + }, + "public.inbox_thread": { + "name": "inbox_thread", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "inbox_id": { + "name": "inbox_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subject_key": { + "name": "subject_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "participants": { + "name": "participants", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_message_at": { + "name": "last_message_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": { + "inbox_thread_inbox_last_message_idx": { + "name": "inbox_thread_inbox_last_message_idx", + "columns": [ + { + "expression": "inbox_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "last_message_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_thread_inbox_subject_idx": { + "name": "inbox_thread_inbox_subject_idx", + "columns": [ + { + "expression": "inbox_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "subject_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_thread_last_message_at_idx": { + "name": "inbox_thread_last_message_at_idx", + "columns": [ + { + "expression": "last_message_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "inbox_thread_organization_idx": { + "name": "inbox_thread_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "inbox_thread_inbox_fk": { + "name": "inbox_thread_inbox_fk", + "tableFrom": "inbox_thread", + "tableTo": "inbox", + "columnsFrom": [ + "inbox_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "inbox_thread_id_organization_unique": { + "name": "inbox_thread_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.notification": { + "name": "notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "payload": { + "name": "payload", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "notification_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "recipients": { + "name": "recipients", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "notification_dedupe_unique": { + "name": "notification_dedupe_unique", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "dedupe_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_next_attempt_idx": { + "name": "notification_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"notification\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "notification_created_at_idx": { + "name": "notification_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "notification_organization_id_organization_id_fk": { + "name": "notification_organization_id_organization_id_fk", + "tableFrom": "notification", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.push_device": { + "name": "push_device", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "session_id": { + "name": "session_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "token": { + "name": "token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "apns_environment": { + "name": "apns_environment", + "type": "apns_environment", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "categories": { + "name": "categories", + "type": "text[]", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "push_device_session_idx": { + "name": "push_device_session_idx", + "columns": [ + { + "expression": "session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_device_token_idx": { + "name": "push_device_token_idx", + "columns": [ + { + "expression": "token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_device_user_idx": { + "name": "push_device_user_idx", + "columns": [ + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "push_device_user_id_user_id_fk": { + "name": "push_device_user_id_user_id_fk", + "tableFrom": "push_device", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "push_device_session_id_session_id_fk": { + "name": "push_device_session_id_session_id_fk", + "tableFrom": "push_device", + "tableTo": "session", + "columnsFrom": [ + "session_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.push_notification": { + "name": "push_notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "push_notification_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "subject_id": { + "name": "subject_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "collapse_key": { + "name": "collapse_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "count": { + "name": "count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "status": { + "name": "status", + "type": "push_notification_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "attempt_count": { + "name": "attempt_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "delivered_device_ids": { + "name": "delivered_device_ids", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "push_notification_pending_collapse_idx": { + "name": "push_notification_pending_collapse_idx", + "columns": [ + { + "expression": "collapse_key", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"push_notification\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_notification_collapse_sent_idx": { + "name": "push_notification_collapse_sent_idx", + "columns": [ + { + "expression": "collapse_key", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "sent_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"push_notification\".\"collapse_key\" IS NOT NULL AND \"push_notification\".\"sent_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_notification_next_attempt_idx": { + "name": "push_notification_next_attempt_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"push_notification\".\"next_attempt_at\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_notification_created_at_idx": { + "name": "push_notification_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "push_notification_organization_idx": { + "name": "push_notification_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "push_notification_organization_id_organization_id_fk": { + "name": "push_notification_organization_id_organization_id_fk", + "tableFrom": "push_notification", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "push_notification_environment_fk": { + "name": "push_notification_environment_fk", + "tableFrom": "push_notification", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_attendee": { + "name": "scheduling_attendee", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "uid": { + "name": "uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_contact": { + "name": "encrypted_contact", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_hmac": { + "name": "email_hmac", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_answers": { + "name": "encrypted_answers", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "time_zone": { + "name": "time_zone", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "locale": { + "name": "locale", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "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": { + "scheduling_attendee_booking_idx": { + "name": "scheduling_attendee_booking_idx", + "columns": [ + { + "expression": "booking_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_attendee_environment_uid_idx": { + "name": "scheduling_attendee_environment_uid_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "uid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_attendee_environment_email_idx": { + "name": "scheduling_attendee_environment_email_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "email_hmac", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_attendee_booking_fk": { + "name": "scheduling_attendee_booking_fk", + "tableFrom": "scheduling_attendee", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_booking": { + "name": "scheduling_booking", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "scheduling_booking_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "start_at": { + "name": "start_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_at": { + "name": "end_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "buffer_before_minutes": { + "name": "buffer_before_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "buffer_after_minutes": { + "name": "buffer_after_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "location": { + "name": "location", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "hold_expires_at": { + "name": "hold_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "approval_expires_at": { + "name": "approval_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "series_id": { + "name": "series_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "series_index": { + "name": "series_index", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "group_session_id": { + "name": "group_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "version": { + "name": "version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "encrypted_attributes": { + "name": "encrypted_attributes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "calendar_unverified": { + "name": "calendar_unverified", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "external_conflict_at": { + "name": "external_conflict_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "no_show_at": { + "name": "no_show_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "cancelled_at": { + "name": "cancelled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "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()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_booking_environment_start_idx": { + "name": "scheduling_booking_environment_start_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_event_type_start_idx": { + "name": "scheduling_booking_event_type_start_idx", + "columns": [ + { + "expression": "event_type_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_series_idx": { + "name": "scheduling_booking_series_idx", + "columns": [ + { + "expression": "series_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "series_index", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_group_session_idx": { + "name": "scheduling_booking_group_session_idx", + "columns": [ + { + "expression": "group_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_end_idx": { + "name": "scheduling_booking_end_idx", + "columns": [ + { + "expression": "end_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_unredacted_end_idx": { + "name": "scheduling_booking_unredacted_end_idx", + "columns": [ + { + "expression": "end_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_booking\".\"redacted_at\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_hold_expiry_idx": { + "name": "scheduling_booking_hold_expiry_idx", + "columns": [ + { + "expression": "hold_expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_booking\".\"status\" = 'held'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_booking_approval_expiry_idx": { + "name": "scheduling_booking_approval_expiry_idx", + "columns": [ + { + "expression": "approval_expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_booking\".\"status\" = 'pending_approval'", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_booking_environment_fk": { + "name": "scheduling_booking_environment_fk", + "tableFrom": "scheduling_booking", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_booking_event_type_fk": { + "name": "scheduling_booking_event_type_fk", + "tableFrom": "scheduling_booking", + "tableTo": "scheduling_event_type", + "columnsFrom": [ + "event_type_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_booking_series_fk": { + "name": "scheduling_booking_series_fk", + "tableFrom": "scheduling_booking", + "tableTo": "scheduling_series", + "columnsFrom": [ + "series_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "scheduling_booking_group_session_fk": { + "name": "scheduling_booking_group_session_fk", + "tableFrom": "scheduling_booking", + "tableTo": "scheduling_group_session", + "columnsFrom": [ + "group_session_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_booking_id_organization_unique": { + "name": "scheduling_booking_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "scheduling_booking_environment_idempotency_unique": { + "name": "scheduling_booking_environment_idempotency_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": { + "scheduling_booking_time_order": { + "name": "scheduling_booking_time_order", + "value": "\"scheduling_booking\".\"start_at\" < \"scheduling_booking\".\"end_at\"" + }, + "scheduling_booking_hold_has_expiry": { + "name": "scheduling_booking_hold_has_expiry", + "value": "\"scheduling_booking\".\"status\" <> 'held' OR \"scheduling_booking\".\"hold_expires_at\" IS NOT NULL" + }, + "scheduling_booking_approval_has_expiry": { + "name": "scheduling_booking_approval_has_expiry", + "value": "\"scheduling_booking\".\"status\" <> 'pending_approval' OR \"scheduling_booking\".\"approval_expires_at\" IS NOT NULL" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_booking_event": { + "name": "scheduling_booking_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "actor": { + "name": "actor", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "scheduling_booking_event_booking_fk": { + "name": "scheduling_booking_event_booking_fk", + "tableFrom": "scheduling_booking_event", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_booking_event_sequence_unique": { + "name": "scheduling_booking_event_sequence_unique", + "nullsNotDistinct": false, + "columns": [ + "booking_id", + "sequence" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_booking_host": { + "name": "scheduling_booking_host", + "schema": "", + "columns": { + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "scheduling_host_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'member'" + } + }, + "indexes": { + "scheduling_booking_host_host_idx": { + "name": "scheduling_booking_host_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_booking_host_booking_fk": { + "name": "scheduling_booking_host_booking_fk", + "tableFrom": "scheduling_booking_host", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_booking_host_host_fk": { + "name": "scheduling_booking_host_host_fk", + "tableFrom": "scheduling_booking_host", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "scheduling_booking_host_booking_id_host_id_pk": { + "name": "scheduling_booking_host_booking_id_host_id_pk", + "columns": [ + "booking_id", + "host_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_busy_interval": { + "name": "scheduling_busy_interval", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "bigserial", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "calendar_id": { + "name": "calendar_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start_at": { + "name": "start_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_at": { + "name": "end_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scheduling_busy_interval_host_idx": { + "name": "scheduling_busy_interval_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "end_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "start_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_busy_interval_calendar_idx": { + "name": "scheduling_busy_interval_calendar_idx", + "columns": [ + { + "expression": "calendar_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_busy_interval_calendar_fk": { + "name": "scheduling_busy_interval_calendar_fk", + "tableFrom": "scheduling_busy_interval", + "tableTo": "scheduling_calendar", + "columnsFrom": [ + "calendar_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_calendar": { + "name": "scheduling_calendar", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "connection_id": { + "name": "connection_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "external_id": { + "name": "external_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "read_busy": { + "name": "read_busy", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "write_target": { + "name": "write_target", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "verified_at": { + "name": "verified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "covered_until": { + "name": "covered_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "dirty_at": { + "name": "dirty_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_fetch_started_at": { + "name": "last_fetch_started_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_sync_at": { + "name": "next_sync_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sync_failures": { + "name": "sync_failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "channel_id": { + "name": "channel_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "channel_resource_id": { + "name": "channel_resource_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "channel_token_hash": { + "name": "channel_token_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "channel_expires_at": { + "name": "channel_expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_calendar_host_write_target_unique": { + "name": "scheduling_calendar_host_write_target_unique", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"scheduling_calendar\".\"write_target\"", + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_calendar_host_idx": { + "name": "scheduling_calendar_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_calendar_channel_idx": { + "name": "scheduling_calendar_channel_idx", + "columns": [ + { + "expression": "channel_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_calendar_next_sync_idx": { + "name": "scheduling_calendar_next_sync_idx", + "columns": [ + { + "expression": "next_sync_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_calendar_connection_fk": { + "name": "scheduling_calendar_connection_fk", + "tableFrom": "scheduling_calendar", + "tableTo": "scheduling_calendar_connection", + "columnsFrom": [ + "connection_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_calendar_id_organization_unique": { + "name": "scheduling_calendar_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "scheduling_calendar_connection_external_unique": { + "name": "scheduling_calendar_connection_external_unique", + "nullsNotDistinct": false, + "columns": [ + "connection_id", + "external_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_calendar_connection": { + "name": "scheduling_calendar_connection", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "scheduling_calendar_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "account_id": { + "name": "account_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "encrypted_credentials": { + "name": "encrypted_credentials", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "scheduling_connection_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "last_error_code": { + "name": "last_error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_error_at": { + "name": "last_error_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "scheduling_calendar_connection_host_fk": { + "name": "scheduling_calendar_connection_host_fk", + "tableFrom": "scheduling_calendar_connection", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_calendar_connection_id_organization_unique": { + "name": "scheduling_calendar_connection_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "scheduling_calendar_connection_account_unique": { + "name": "scheduling_calendar_connection_account_unique", + "nullsNotDistinct": false, + "columns": [ + "host_id", + "provider", + "account_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_calendar_event": { + "name": "scheduling_calendar_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "group_session_id": { + "name": "group_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "calendar_id": { + "name": "calendar_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "desired_start": { + "name": "desired_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "desired_end": { + "name": "desired_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "desired_state": { + "name": "desired_state", + "type": "scheduling_calendar_event_state", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'present'" + }, + "desired_version": { + "name": "desired_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1 + }, + "applied_version": { + "name": "applied_version", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "provider_event_id": { + "name": "provider_event_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "key_generation": { + "name": "key_generation", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "external_state": { + "name": "external_state", + "type": "scheduling_external_state", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'in_sync'" + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_error_code": { + "name": "last_error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_calendar_event_host_idx": { + "name": "scheduling_calendar_event_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "desired_end", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "desired_start", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_calendar_event_due_idx": { + "name": "scheduling_calendar_event_due_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_calendar_event\".\"applied_version\" < \"scheduling_calendar_event\".\"desired_version\"", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_calendar_event_booking_fk": { + "name": "scheduling_calendar_event_booking_fk", + "tableFrom": "scheduling_calendar_event", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_calendar_event_group_session_fk": { + "name": "scheduling_calendar_event_group_session_fk", + "tableFrom": "scheduling_calendar_event", + "tableTo": "scheduling_group_session", + "columnsFrom": [ + "group_session_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_calendar_event_calendar_fk": { + "name": "scheduling_calendar_event_calendar_fk", + "tableFrom": "scheduling_calendar_event", + "tableTo": "scheduling_calendar", + "columnsFrom": [ + "calendar_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_calendar_event_target_unique": { + "name": "scheduling_calendar_event_target_unique", + "nullsNotDistinct": false, + "columns": [ + "booking_id", + "host_id", + "calendar_id" + ] + }, + "scheduling_calendar_event_session_target_unique": { + "name": "scheduling_calendar_event_session_target_unique", + "nullsNotDistinct": false, + "columns": [ + "group_session_id", + "host_id", + "calendar_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "scheduling_calendar_event_one_owner": { + "name": "scheduling_calendar_event_one_owner", + "value": "(\"scheduling_calendar_event\".\"booking_id\" IS NULL) <> (\"scheduling_calendar_event\".\"group_session_id\" IS NULL)" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_claim": { + "name": "scheduling_claim", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "group_session_id": { + "name": "group_session_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "occupied_start": { + "name": "occupied_start", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "occupied_end": { + "name": "occupied_end", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "live_from": { + "name": "live_from", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "live_until": { + "name": "live_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "limit_day": { + "name": "limit_day", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "limit_week": { + "name": "limit_week", + "type": "date", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "scheduling_claim_booking_idx": { + "name": "scheduling_claim_booking_idx", + "columns": [ + { + "expression": "booking_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_claim_group_session_idx": { + "name": "scheduling_claim_group_session_idx", + "columns": [ + { + "expression": "group_session_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_claim_host_day_idx": { + "name": "scheduling_claim_host_day_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "limit_day", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_claim_host_week_idx": { + "name": "scheduling_claim_host_week_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "limit_week", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_claim_occupied_end_idx": { + "name": "scheduling_claim_occupied_end_idx", + "columns": [ + { + "expression": "occupied_end", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_claim_live_until_idx": { + "name": "scheduling_claim_live_until_idx", + "columns": [ + { + "expression": "live_until", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_claim\".\"live_until\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_claim_host_fk": { + "name": "scheduling_claim_host_fk", + "tableFrom": "scheduling_claim", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_claim_booking_fk": { + "name": "scheduling_claim_booking_fk", + "tableFrom": "scheduling_claim", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_claim_group_session_fk": { + "name": "scheduling_claim_group_session_fk", + "tableFrom": "scheduling_claim", + "tableTo": "scheduling_group_session", + "columnsFrom": [ + "group_session_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "scheduling_claim_occupied_order": { + "name": "scheduling_claim_occupied_order", + "value": "\"scheduling_claim\".\"occupied_start\" < \"scheduling_claim\".\"occupied_end\"" + }, + "scheduling_claim_live_order": { + "name": "scheduling_claim_live_order", + "value": "\"scheduling_claim\".\"live_until\" IS NULL OR \"scheduling_claim\".\"live_from\" < \"scheduling_claim\".\"live_until\"" + }, + "scheduling_claim_one_owner": { + "name": "scheduling_claim_one_owner", + "value": "(\"scheduling_claim\".\"booking_id\" IS NULL) <> (\"scheduling_claim\".\"group_session_id\" IS NULL)" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_event_type": { + "name": "scheduling_event_type", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "uid": { + "name": "uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "scheduling_event_type_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'one_on_one'" + }, + "status": { + "name": "status", + "type": "scheduling_event_type_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "duration_minutes": { + "name": "duration_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "duration_options": { + "name": "duration_options", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "step_minutes": { + "name": "step_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "grid_time_zone": { + "name": "grid_time_zone", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "buffer_before_minutes": { + "name": "buffer_before_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "buffer_after_minutes": { + "name": "buffer_after_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "min_notice_minutes": { + "name": "min_notice_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "booking_window": { + "name": "booking_window", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "limits": { + "name": "limits", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "capacity": { + "name": "capacity", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "requires_approval": { + "name": "requires_approval", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "approval_ttl_minutes": { + "name": "approval_ttl_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 1440 + }, + "hold_ttl_seconds": { + "name": "hold_ttl_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 600 + }, + "cancel_notice_minutes": { + "name": "cancel_notice_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "reschedule_notice_minutes": { + "name": "reschedule_notice_minutes", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "questions": { + "name": "questions", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "locations": { + "name": "locations", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "host_filter": { + "name": "host_filter", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "notifications": { + "name": "notifications", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "screened_at": { + "name": "screened_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_event_type_environment_created_at_idx": { + "name": "scheduling_event_type_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_event_type_environment_fk": { + "name": "scheduling_event_type_environment_fk", + "tableFrom": "scheduling_event_type", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_event_type_environment_uid_unique": { + "name": "scheduling_event_type_environment_uid_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "uid" + ] + }, + "scheduling_event_type_id_organization_unique": { + "name": "scheduling_event_type_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": { + "scheduling_event_type_duration_positive": { + "name": "scheduling_event_type_duration_positive", + "value": "\"scheduling_event_type\".\"duration_minutes\" > 0" + }, + "scheduling_event_type_step_positive": { + "name": "scheduling_event_type_step_positive", + "value": "\"scheduling_event_type\".\"step_minutes\" > 0" + }, + "scheduling_event_type_capacity": { + "name": "scheduling_event_type_capacity", + "value": "\"scheduling_event_type\".\"capacity\" IS NULL OR (\"scheduling_event_type\".\"kind\" = 'group' AND \"scheduling_event_type\".\"capacity\" > 0)" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_event_type_host": { + "name": "scheduling_event_type_host", + "schema": "", + "columns": { + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "scheduling_host_role", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'member'" + }, + "weight": { + "name": "weight", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 100 + }, + "assigned": { + "name": "assigned", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "fair_units": { + "name": "fair_units", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_assigned_at": { + "name": "last_assigned_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "schedule_id": { + "name": "schedule_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "removed_at": { + "name": "removed_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": { + "scheduling_event_type_host_host_idx": { + "name": "scheduling_event_type_host_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_event_type_host_event_type_fk": { + "name": "scheduling_event_type_host_event_type_fk", + "tableFrom": "scheduling_event_type_host", + "tableTo": "scheduling_event_type", + "columnsFrom": [ + "event_type_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_event_type_host_host_fk": { + "name": "scheduling_event_type_host_host_fk", + "tableFrom": "scheduling_event_type_host", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "scheduling_event_type_host_event_type_id_host_id_pk": { + "name": "scheduling_event_type_host_event_type_id_host_id_pk", + "columns": [ + "event_type_id", + "host_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": { + "scheduling_event_type_host_weight_positive": { + "name": "scheduling_event_type_host_weight_positive", + "value": "\"scheduling_event_type_host\".\"weight\" > 0" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_group_session": { + "name": "scheduling_group_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "start_at": { + "name": "start_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "end_at": { + "name": "end_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "capacity": { + "name": "capacity", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "location": { + "name": "location", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "meeting_url": { + "name": "meeting_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_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": { + "scheduling_group_session_end_at_idx": { + "name": "scheduling_group_session_end_at_idx", + "columns": [ + { + "expression": "end_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_group_session_event_type_fk": { + "name": "scheduling_group_session_event_type_fk", + "tableFrom": "scheduling_group_session", + "tableTo": "scheduling_event_type", + "columnsFrom": [ + "event_type_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_group_session_host_fk": { + "name": "scheduling_group_session_host_fk", + "tableFrom": "scheduling_group_session", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_group_session_id_organization_unique": { + "name": "scheduling_group_session_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "scheduling_group_session_slot_unique": { + "name": "scheduling_group_session_slot_unique", + "nullsNotDistinct": false, + "columns": [ + "event_type_id", + "host_id", + "start_at" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_host": { + "name": "scheduling_host", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "uid": { + "name": "uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "time_zone": { + "name": "time_zone", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attributes": { + "name": "attributes", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "status": { + "name": "status", + "type": "scheduling_host_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "screened_at": { + "name": "screened_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_host_environment_created_at_idx": { + "name": "scheduling_host_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_host_attributes_idx": { + "name": "scheduling_host_attributes_idx", + "columns": [ + { + "expression": "attributes", + "isExpression": false, + "asc": true, + "nulls": "last", + "opclass": "jsonb_path_ops" + } + ], + "isUnique": false, + "concurrently": false, + "method": "gin", + "with": {} + } + }, + "foreignKeys": { + "scheduling_host_environment_fk": { + "name": "scheduling_host_environment_fk", + "tableFrom": "scheduling_host", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_host_environment_uid_unique": { + "name": "scheduling_host_environment_uid_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "uid" + ] + }, + "scheduling_host_id_organization_unique": { + "name": "scheduling_host_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_limit_bucket": { + "name": "scheduling_limit_bucket", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope": { + "name": "scope", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "scope_id": { + "name": "scope_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "period": { + "name": "period", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_limit_bucket_organization_idx": { + "name": "scheduling_limit_bucket_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_limit_bucket_created_at_idx": { + "name": "scheduling_limit_bucket_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": { + "scheduling_limit_bucket_scope_scope_id_period_pk": { + "name": "scheduling_limit_bucket_scope_scope_id_period_pk", + "columns": [ + "scope", + "scope_id", + "period" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_logo": { + "name": "scheduling_logo", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "image": { + "name": "image", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "scheduling_logo_environment_fk": { + "name": "scheduling_logo_environment_fk", + "tableFrom": "scheduling_logo", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_logo_environment_unique": { + "name": "scheduling_logo_environment_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_notification": { + "name": "scheduling_notification", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "kind": { + "name": "kind", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "channel": { + "name": "channel", + "type": "scheduling_notification_channel", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "recipient": { + "name": "recipient", + "type": "scheduling_notification_recipient", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "booking_version": { + "name": "booking_version", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "due_at": { + "name": "due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "lease_until": { + "name": "lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "finished_at": { + "name": "finished_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "outcome": { + "name": "outcome", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_notification_due_idx": { + "name": "scheduling_notification_due_idx", + "columns": [ + { + "expression": "due_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_notification\".\"finished_at\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_notification_booking_idx": { + "name": "scheduling_notification_booking_idx", + "columns": [ + { + "expression": "booking_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_notification_environment_fk": { + "name": "scheduling_notification_environment_fk", + "tableFrom": "scheduling_notification", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_notification_booking_fk": { + "name": "scheduling_notification_booking_fk", + "tableFrom": "scheduling_notification", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_notification_dedupe_unique": { + "name": "scheduling_notification_dedupe_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_oauth_state": { + "name": "scheduling_oauth_state", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "scheduling_calendar_provider", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "state_hash": { + "name": "state_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "encrypted_code_verifier": { + "name": "encrypted_code_verifier", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "return_url": { + "name": "return_url", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_oauth_state_expires_at_idx": { + "name": "scheduling_oauth_state_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_oauth_state_host_fk": { + "name": "scheduling_oauth_state_host_fk", + "tableFrom": "scheduling_oauth_state", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_oauth_state_hash_unique": { + "name": "scheduling_oauth_state_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "state_hash" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_schedule": { + "name": "scheduling_schedule", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "time_zone": { + "name": "time_zone", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "rules": { + "name": "rules", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "is_default": { + "name": "is_default", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_schedule_host_default_unique": { + "name": "scheduling_schedule_host_default_unique", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"scheduling_schedule\".\"is_default\"", + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_schedule_host_idx": { + "name": "scheduling_schedule_host_idx", + "columns": [ + { + "expression": "host_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_schedule_host_fk": { + "name": "scheduling_schedule_host_fk", + "tableFrom": "scheduling_schedule", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_schedule_id_organization_unique": { + "name": "scheduling_schedule_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_schedule_override": { + "name": "scheduling_schedule_override", + "schema": "", + "columns": { + "schedule_id": { + "name": "schedule_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "date": { + "name": "date", + "type": "date", + "primaryKey": false, + "notNull": true + }, + "ranges": { + "name": "ranges", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + } + }, + "indexes": {}, + "foreignKeys": { + "scheduling_schedule_override_schedule_fk": { + "name": "scheduling_schedule_override_schedule_fk", + "tableFrom": "scheduling_schedule_override", + "tableTo": "scheduling_schedule", + "columnsFrom": [ + "schedule_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "scheduling_schedule_override_schedule_id_date_pk": { + "name": "scheduling_schedule_override_schedule_id_date_pk", + "columns": [ + "schedule_id", + "date" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_series": { + "name": "scheduling_series", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "rule": { + "name": "rule", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "anchor_time_zone": { + "name": "anchor_time_zone", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_series_environment_idx": { + "name": "scheduling_series_environment_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_series_created_at_idx": { + "name": "scheduling_series_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_series_event_type_fk": { + "name": "scheduling_series_event_type_fk", + "tableFrom": "scheduling_series", + "tableTo": "scheduling_event_type", + "columnsFrom": [ + "event_type_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_series_id_organization_unique": { + "name": "scheduling_series_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "scheduling_series_environment_idempotency_unique": { + "name": "scheduling_series_environment_idempotency_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.scheduling_session": { + "name": "scheduling_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "scheduling_session_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "token_hash": { + "name": "token_hash", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "host_id": { + "name": "host_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "event_type_id": { + "name": "event_type_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "booking_id": { + "name": "booking_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_attendee": { + "name": "encrypted_attendee", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "encrypted_attributes": { + "name": "encrypted_attributes", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attendee_uid": { + "name": "attendee_uid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "read_only": { + "name": "read_only", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "revoked_at": { + "name": "revoked_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "scheduling_session_expires_at_idx": { + "name": "scheduling_session_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_session_booking_idx": { + "name": "scheduling_session_booking_idx", + "columns": [ + { + "expression": "booking_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "scheduling_session_attendee_uid_idx": { + "name": "scheduling_session_attendee_uid_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "attendee_uid", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"scheduling_session\".\"attendee_uid\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "scheduling_session_environment_fk": { + "name": "scheduling_session_environment_fk", + "tableFrom": "scheduling_session", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_session_host_fk": { + "name": "scheduling_session_host_fk", + "tableFrom": "scheduling_session", + "tableTo": "scheduling_host", + "columnsFrom": [ + "host_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_session_event_type_fk": { + "name": "scheduling_session_event_type_fk", + "tableFrom": "scheduling_session", + "tableTo": "scheduling_event_type", + "columnsFrom": [ + "event_type_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "scheduling_session_booking_fk": { + "name": "scheduling_session_booking_fk", + "tableFrom": "scheduling_session", + "tableTo": "scheduling_booking", + "columnsFrom": [ + "booking_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_session_token_hash_unique": { + "name": "scheduling_session_token_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "token_hash" + ] + } + }, + "policies": {}, + "checkConstraints": { + "scheduling_session_scope": { + "name": "scheduling_session_scope", + "value": "(\"scheduling_session\".\"kind\" = 'host' AND \"scheduling_session\".\"host_id\" IS NOT NULL)\n OR (\"scheduling_session\".\"kind\" = 'booker' AND (\"scheduling_session\".\"event_type_id\" IS NOT NULL OR \"scheduling_session\".\"host_id\" IS NOT NULL))\n OR (\"scheduling_session\".\"kind\" = 'manage' AND \"scheduling_session\".\"booking_id\" IS NOT NULL)" + } + }, + "isRLSEnabled": false + }, + "public.scheduling_settings": { + "name": "scheduling_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "allowed_origins": { + "name": "allowed_origins", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "brand_name": { + "name": "brand_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "accent_color": { + "name": "accent_color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_from": { + "name": "email_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sms_from": { + "name": "sms_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notifications": { + "name": "notifications", + "type": "jsonb", + "primaryKey": false, + "notNull": false + }, + "calendar_failure_mode": { + "name": "calendar_failure_mode", + "type": "scheduling_calendar_failure_mode", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'hide'" + }, + "screened_at": { + "name": "screened_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "scheduling_settings_environment_fk": { + "name": "scheduling_settings_environment_fk", + "tableFrom": "scheduling_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "scheduling_settings_environment_unique": { + "name": "scheduling_settings_environment_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_builder_session": { + "name": "sign_builder_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "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 + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_builder_session_expires_at_idx": { + "name": "sign_builder_session_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_builder_session_template_fk": { + "name": "sign_builder_session_template_fk", + "tableFrom": "sign_builder_session", + "tableTo": "sign_template", + "columnsFrom": [ + "template_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_builder_session_token_hash_unique": { + "name": "sign_builder_session_token_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "token_hash" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_document": { + "name": "sign_document", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "store_key": { + "name": "store_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sha256": { + "name": "sha256", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "pages": { + "name": "pages", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "anchors": { + "name": "anchors", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_document_environment_created_at_idx": { + "name": "sign_document_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_document_created_at_idx": { + "name": "sign_document_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_document_environment_fk": { + "name": "sign_document_environment_fk", + "tableFrom": "sign_document", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_document_id_organization_unique": { + "name": "sign_document_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_event": { + "name": "sign_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "sign_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "signer_id": { + "name": "signer_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "actor": { + "name": "actor", + "type": "text", + "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 + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "previous_hash": { + "name": "previous_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "hash": { + "name": "hash", + "type": "text", + "primaryKey": false, + "notNull": true + } + }, + "indexes": {}, + "foreignKeys": { + "sign_event_request_fk": { + "name": "sign_event_request_fk", + "tableFrom": "sign_event", + "tableTo": "sign_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_event_request_sequence_unique": { + "name": "sign_event_request_sequence_unique", + "nullsNotDistinct": false, + "columns": [ + "request_id", + "sequence" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_fake_object": { + "name": "sign_fake_object", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_fake_object_organization_idx": { + "name": "sign_fake_object_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_field": { + "name": "sign_field", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "signer_id": { + "name": "signer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "document_id": { + "name": "document_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "sign_field_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "page": { + "name": "page", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "x": { + "name": "x", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "y": { + "name": "y", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "width": { + "name": "width", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "required": { + "name": "required", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "anchor": { + "name": "anchor", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "value": { + "name": "value", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "prefilled": { + "name": "prefilled", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_field_request_idx": { + "name": "sign_field_request_idx", + "columns": [ + { + "expression": "request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_field_signer_idx": { + "name": "sign_field_signer_idx", + "columns": [ + { + "expression": "signer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_field_signer_fk": { + "name": "sign_field_signer_fk", + "tableFrom": "sign_field", + "tableTo": "sign_signer", + "columnsFrom": [ + "signer_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "sign_field_request_fk": { + "name": "sign_field_request_fk", + "tableFrom": "sign_field", + "tableTo": "sign_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_request": { + "name": "sign_request", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "sign_request_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signing_order": { + "name": "signing_order", + "type": "sign_signing_order", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'parallel'" + }, + "metadata": { + "name": "metadata", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "completed_at": { + "name": "completed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "canceled_at": { + "name": "canceled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "declined_at": { + "name": "declined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "signed_document_key": { + "name": "signed_document_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signed_document_sha256": { + "name": "signed_document_sha256", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sealed_at": { + "name": "sealed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "seal_lease_until": { + "name": "seal_lease_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "seal_attempts": { + "name": "seal_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "seal_next_attempt_at": { + "name": "seal_next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "seal_error": { + "name": "seal_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reminder_interval_days": { + "name": "reminder_interval_days", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "expired_at": { + "name": "expired_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_request_environment_created_at_idx": { + "name": "sign_request_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_request_expires_at_idx": { + "name": "sign_request_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sign_request\".\"status\" = 'sent'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_request_created_at_idx": { + "name": "sign_request_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_request_unsealed_idx": { + "name": "sign_request_unsealed_idx", + "columns": [ + { + "expression": "completed_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sign_request\".\"status\" = 'completed' and \"sign_request\".\"sealed_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_request_environment_fk": { + "name": "sign_request_environment_fk", + "tableFrom": "sign_request", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_request_environment_idempotency_key_unique": { + "name": "sign_request_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + }, + "sign_request_id_organization_unique": { + "name": "sign_request_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_request_document": { + "name": "sign_request_document", + "schema": "", + "columns": { + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "document_id": { + "name": "document_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "sign_request_document_document_idx": { + "name": "sign_request_document_document_idx", + "columns": [ + { + "expression": "document_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_request_document_request_fk": { + "name": "sign_request_document_request_fk", + "tableFrom": "sign_request_document", + "tableTo": "sign_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "sign_request_document_document_fk": { + "name": "sign_request_document_document_fk", + "tableFrom": "sign_request_document", + "tableTo": "sign_document", + "columnsFrom": [ + "document_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "sign_request_document_request_id_position_pk": { + "name": "sign_request_document_request_id_position_pk", + "columns": [ + "request_id", + "position" + ] + } + }, + "uniqueConstraints": { + "sign_request_document_unique": { + "name": "sign_request_document_unique", + "nullsNotDistinct": false, + "columns": [ + "request_id", + "document_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_session": { + "name": "sign_session", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "signer_id": { + "name": "signer_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "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 + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "last_used_at": { + "name": "last_used_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_session_expires_at_idx": { + "name": "sign_session_expires_at_idx", + "columns": [ + { + "expression": "expires_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_session_signer_idx": { + "name": "sign_session_signer_idx", + "columns": [ + { + "expression": "signer_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_session_signer_fk": { + "name": "sign_session_signer_fk", + "tableFrom": "sign_session", + "tableTo": "sign_signer", + "columnsFrom": [ + "signer_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_session_token_hash_unique": { + "name": "sign_session_token_hash_unique", + "nullsNotDistinct": false, + "columns": [ + "token_hash" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_settings": { + "name": "sign_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "allowed_origins": { + "name": "allowed_origins", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "display_name": { + "name": "display_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "accent_color": { + "name": "accent_color", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "theme": { + "name": "theme", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'system'" + }, + "disclosure": { + "name": "disclosure", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_from": { + "name": "email_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "reminder_interval_days": { + "name": "reminder_interval_days", + "type": "integer", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "sign_settings_environment_fk": { + "name": "sign_settings_environment_fk", + "tableFrom": "sign_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_settings_environment_unique": { + "name": "sign_settings_environment_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_signer": { + "name": "sign_signer", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "email": { + "name": "email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "delivery": { + "name": "delivery", + "type": "sign_delivery", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "authentication": { + "name": "authentication", + "type": "sign_authentication", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "sign_signer_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "client_ref": { + "name": "client_ref", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "viewed_at": { + "name": "viewed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "consented_at": { + "name": "consented_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "signed_at": { + "name": "signed_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "declined_at": { + "name": "declined_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "decline_reason": { + "name": "decline_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signature_key": { + "name": "signature_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signature_sha256": { + "name": "signature_sha256", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "initials_key": { + "name": "initials_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "initials_sha256": { + "name": "initials_sha256", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "notified_at": { + "name": "notified_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "reminder_count": { + "name": "reminder_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "last_reminded_at": { + "name": "last_reminded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_reminder_at": { + "name": "next_reminder_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "remind_requested_at": { + "name": "remind_requested_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "copy_sent_at": { + "name": "copy_sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "email_failures": { + "name": "email_failures", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "email_retry_at": { + "name": "email_retry_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_signer_request_idx": { + "name": "sign_signer_request_idx", + "columns": [ + { + "expression": "request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "position", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_signer_email_due_idx": { + "name": "sign_signer_email_due_idx", + "columns": [ + { + "expression": "request_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sign_signer\".\"delivery\" = 'email' and (\"sign_signer\".\"notified_at\" is null or \"sign_signer\".\"next_reminder_at\" is not null or \"sign_signer\".\"remind_requested_at\" is not null or (\"sign_signer\".\"status\" = 'signed' and \"sign_signer\".\"copy_sent_at\" is null))", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_signer_request_fk": { + "name": "sign_signer_request_fk", + "tableFrom": "sign_signer", + "tableTo": "sign_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_signer_id_organization_unique": { + "name": "sign_signer_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + }, + "sign_signer_request_email_unique": { + "name": "sign_signer_request_email_unique", + "nullsNotDistinct": false, + "columns": [ + "request_id", + "email" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_store_cleanup": { + "name": "sign_store_cleanup", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_store_cleanup_next_attempt_at_idx": { + "name": "sign_store_cleanup_next_attempt_at_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sign_store_cleanup_organization_idx": { + "name": "sign_store_cleanup_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_template": { + "name": "sign_template", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message": { + "name": "message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "signing_order": { + "name": "signing_order", + "type": "sign_signing_order", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'parallel'" + }, + "roles": { + "name": "roles", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "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": { + "sign_template_environment_created_at_idx": { + "name": "sign_template_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_template_environment_fk": { + "name": "sign_template_environment_fk", + "tableFrom": "sign_template", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sign_template_id_organization_unique": { + "name": "sign_template_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_template_document": { + "name": "sign_template_document", + "schema": "", + "columns": { + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "document_id": { + "name": "document_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "position": { + "name": "position", + "type": "integer", + "primaryKey": false, + "notNull": true + } + }, + "indexes": { + "sign_template_document_document_idx": { + "name": "sign_template_document_document_idx", + "columns": [ + { + "expression": "document_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_template_document_template_fk": { + "name": "sign_template_document_template_fk", + "tableFrom": "sign_template_document", + "tableTo": "sign_template", + "columnsFrom": [ + "template_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "sign_template_document_document_fk": { + "name": "sign_template_document_document_fk", + "tableFrom": "sign_template_document", + "tableTo": "sign_document", + "columnsFrom": [ + "document_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "restrict", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "sign_template_document_template_id_position_pk": { + "name": "sign_template_document_template_id_position_pk", + "columns": [ + "template_id", + "position" + ] + } + }, + "uniqueConstraints": { + "sign_template_document_unique": { + "name": "sign_template_document_unique", + "nullsNotDistinct": false, + "columns": [ + "template_id", + "document_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sign_template_field": { + "name": "sign_template_field", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "template_id": { + "name": "template_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "document": { + "name": "document", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "sign_field_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "page": { + "name": "page", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "x": { + "name": "x", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "y": { + "name": "y", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "width": { + "name": "width", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "height": { + "name": "height", + "type": "double precision", + "primaryKey": false, + "notNull": true + }, + "required": { + "name": "required", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": true + }, + "label": { + "name": "label", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "merge_key": { + "name": "merge_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sign_template_field_template_idx": { + "name": "sign_template_field_template_idx", + "columns": [ + { + "expression": "template_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sign_template_field_template_fk": { + "name": "sign_template_field_template_fk", + "tableFrom": "sign_template_field", + "tableTo": "sign_template", + "columnsFrom": [ + "template_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_account": { + "name": "sms_account", + "schema": "", + "columns": { + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "subaccount_sid": { + "name": "subaccount_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "auth_token": { + "name": "auth_token", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "sms_account_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'active'" + }, + "allowed_countries": { + "name": "allowed_countries", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{US,CA}'::text[]" + }, + "unlocked_countries": { + "name": "unlocked_countries", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "sms_account_organization_id_organization_id_fk": { + "name": "sms_account_organization_id_organization_id_fk", + "tableFrom": "sms_account", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_account_subaccount_sid_unique": { + "name": "sms_account_subaccount_sid_unique", + "nullsNotDistinct": false, + "columns": [ + "subaccount_sid" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_event": { + "name": "sms_event", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "type": { + "name": "type", + "type": "sms_event_type", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_status": { + "name": "provider_status", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "occurred_at": { + "name": "occurred_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "dedupe_key": { + "name": "dedupe_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "details": { + "name": "details", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_event_message_occurred_at_idx": { + "name": "sms_event_message_occurred_at_idx", + "columns": [ + { + "expression": "message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "occurred_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_event_message_fk": { + "name": "sms_event_message_fk", + "tableFrom": "sms_event", + "tableTo": "sms_message", + "columnsFrom": [ + "message_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_event_message_dedupe_unique": { + "name": "sms_event_message_dedupe_unique", + "nullsNotDistinct": false, + "columns": [ + "message_id", + "dedupe_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_inbound_receipt": { + "name": "sms_inbound_receipt", + "schema": "", + "columns": { + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "from_number": { + "name": "from_number", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "keyword": { + "name": "keyword", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_inbound_receipt_created_at_idx": { + "name": "sms_inbound_receipt_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_inbound_receipt_organization_created_at_idx": { + "name": "sms_inbound_receipt_organization_created_at_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_inbound_receipt_organization_id_organization_id_fk": { + "name": "sms_inbound_receipt_organization_id_organization_id_fk", + "tableFrom": "sms_inbound_receipt", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "sms_inbound_receipt_provider_provider_message_id_pk": { + "name": "sms_inbound_receipt_provider_provider_message_id_pk", + "columns": [ + "provider", + "provider_message_id" + ] + } + }, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_message": { + "name": "sms_message", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_owner_id": { + "name": "api_key_owner_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "sms_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'queued'" + }, + "from": { + "name": "from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to": { + "name": "to", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to_country": { + "name": "to_country", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "number_id": { + "name": "number_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "discard_body": { + "name": "discard_body", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "encoding": { + "name": "encoding", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "segments": { + "name": "segments", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_code": { + "name": "error_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "error_message": { + "name": "error_message", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "scheduled_at": { + "name": "scheduled_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "sent_at": { + "name": "sent_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "delivered_at": { + "name": "delivered_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "traceparent": { + "name": "traceparent", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_message_environment_created_at_idx": { + "name": "sms_message_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_message_organization_send_time_idx": { + "name": "sms_message_organization_send_time_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "coalesce(\"sent_at\", \"created_at\")", + "asc": true, + "isExpression": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_message_scheduled_due_idx": { + "name": "sms_message_scheduled_due_idx", + "columns": [ + { + "expression": "scheduled_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sms_message\".\"status\" = 'scheduled'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_message_queued_created_at_idx": { + "name": "sms_message_queued_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sms_message\".\"status\" = 'queued'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_message_created_at_idx": { + "name": "sms_message_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_message_environment_fk": { + "name": "sms_message_environment_fk", + "tableFrom": "sms_message", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_message_environment_idempotency_key_unique": { + "name": "sms_message_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + }, + "sms_message_id_organization_unique": { + "name": "sms_message_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_number": { + "name": "sms_number", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "phone_number": { + "name": "phone_number", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "sms_number_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_sid": { + "name": "provider_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "sms_number_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "registration_id": { + "name": "registration_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "receiving_environment_id": { + "name": "receiving_environment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "next_fee_at": { + "name": "next_fee_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_number_organization_idx": { + "name": "sms_number_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_number_next_fee_idx": { + "name": "sms_number_next_fee_idx", + "columns": [ + { + "expression": "next_fee_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sms_number\".\"next_fee_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_number_organization_id_organization_id_fk": { + "name": "sms_number_organization_id_organization_id_fk", + "tableFrom": "sms_number", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_number_phone_number_unique": { + "name": "sms_number_phone_number_unique", + "nullsNotDistinct": false, + "columns": [ + "phone_number" + ] + }, + "sms_number_id_organization_unique": { + "name": "sms_number_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_received": { + "name": "sms_received", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "number_id": { + "name": "number_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "from": { + "name": "from", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to": { + "name": "to", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "segments": { + "name": "segments", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "keyword": { + "name": "keyword", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "provider": { + "name": "provider", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "provider_message_id": { + "name": "provider_message_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "usage_recorded_at": { + "name": "usage_recorded_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": { + "sms_received_environment_created_at_idx": { + "name": "sms_received_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_received_created_at_idx": { + "name": "sms_received_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_received_environment_fk": { + "name": "sms_received_environment_fk", + "tableFrom": "sms_received", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_received_provider_message_unique": { + "name": "sms_received_provider_message_unique", + "nullsNotDistinct": false, + "columns": [ + "provider", + "provider_message_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_registration": { + "name": "sms_registration", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "sms_registration_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "status": { + "name": "status", + "type": "sms_registration_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'draft'" + }, + "step": { + "name": "step", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "brand_type": { + "name": "brand_type", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "profile": { + "name": "profile", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "campaign": { + "name": "campaign", + "type": "jsonb", + "primaryKey": false, + "notNull": true + }, + "customer_profile_sid": { + "name": "customer_profile_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "trust_product_sid": { + "name": "trust_product_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "brand_sid": { + "name": "brand_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "messaging_service_sid": { + "name": "messaging_service_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "campaign_sid": { + "name": "campaign_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "toll_free_verification_sid": { + "name": "toll_free_verification_sid", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "number_id": { + "name": "number_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rejection_reason": { + "name": "rejection_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "next_check_at": { + "name": "next_check_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "next_fee_at": { + "name": "next_fee_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "submitted_at": { + "name": "submitted_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "approved_at": { + "name": "approved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_registration_organization_idx": { + "name": "sms_registration_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "sms_registration_next_check_idx": { + "name": "sms_registration_next_check_idx", + "columns": [ + { + "expression": "next_check_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"sms_registration\".\"next_check_at\" is not null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_registration_organization_id_organization_id_fk": { + "name": "sms_registration_organization_id_organization_id_fk", + "tableFrom": "sms_registration", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_registration_id_organization_unique": { + "name": "sms_registration_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.sms_suppression": { + "name": "sms_suppression", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "bigint", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "sms_suppression_sequence_seq", + "schema": "public", + "increment": "1", + "startWith": "1", + "minValue": "1", + "maxValue": "9223372036854775807", + "cache": "1", + "cycle": false + } + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "phone_number": { + "name": "phone_number", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "reason": { + "name": "reason", + "type": "sms_suppression_reason", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "sms_suppression_environment_sequence_idx": { + "name": "sms_suppression_environment_sequence_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + }, + { + "expression": "sequence", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "sms_suppression_environment_fk": { + "name": "sms_suppression_environment_fk", + "tableFrom": "sms_suppression", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "sms_suppression_environment_phone_unique": { + "name": "sms_suppression_environment_phone_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "phone_number" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_attachment": { + "name": "support_attachment", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "ticket_id": { + "name": "ticket_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message_id": { + "name": "message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "uploaded_by_user_id": { + "name": "uploaded_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "filename": { + "name": "filename", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "size": { + "name": "size", + "type": "bigint", + "primaryKey": false, + "notNull": true + }, + "state": { + "name": "state", + "type": "support_attachment_state", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "source_key": { + "name": "source_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "store_key": { + "name": "store_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_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": { + "support_attachment_message_idx": { + "name": "support_attachment_message_idx", + "columns": [ + { + "expression": "message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_attachment_ticket_idx": { + "name": "support_attachment_ticket_idx", + "columns": [ + { + "expression": "ticket_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_attachment_copy_idx": { + "name": "support_attachment_copy_idx", + "columns": [ + { + "expression": "next_attempt_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_attachment\".\"state\" = 'pending_copy'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_attachment_unclaimed_idx": { + "name": "support_attachment_unclaimed_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_attachment\".\"message_id\" IS NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "support_attachment_ticket_id_support_ticket_id_fk": { + "name": "support_attachment_ticket_id_support_ticket_id_fk", + "tableFrom": "support_attachment", + "tableTo": "support_ticket", + "columnsFrom": [ + "ticket_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "support_attachment_message_id_support_message_id_fk": { + "name": "support_attachment_message_id_support_message_id_fk", + "tableFrom": "support_attachment", + "tableTo": "support_message", + "columnsFrom": [ + "message_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "support_attachment_uploaded_by_user_id_user_id_fk": { + "name": "support_attachment_uploaded_by_user_id_user_id_fk", + "tableFrom": "support_attachment", + "tableTo": "user", + "columnsFrom": [ + "uploaded_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_fake_object": { + "name": "support_fake_object", + "schema": "", + "columns": { + "key": { + "name": "key", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "content_type": { + "name": "content_type", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "content": { + "name": "content", + "type": "bytea", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_intake": { + "name": "support_intake", + "schema": "", + "columns": { + "received_email_id": { + "name": "received_email_id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "outcome": { + "name": "outcome", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "ticket_id": { + "name": "ticket_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_attempt_at": { + "name": "next_attempt_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_error": { + "name": "last_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "settled_at": { + "name": "settled_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": { + "support_intake_created_idx": { + "name": "support_intake_created_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_message": { + "name": "support_message", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "ticket_id": { + "name": "ticket_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "kind": { + "name": "kind", + "type": "support_message_kind", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "event": { + "name": "event", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "event_data": { + "name": "event_data", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "author_user_id": { + "name": "author_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "author_name": { + "name": "author_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "author_email": { + "name": "author_email", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "visible_text": { + "name": "visible_text", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "''" + }, + "sender_auth": { + "name": "sender_auth", + "type": "support_sender_auth", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "customer_visible": { + "name": "customer_visible", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "low_signal": { + "name": "low_signal", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "rfc_message_id": { + "name": "rfc_message_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "received_email_id": { + "name": "received_email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "delivery_status": { + "name": "delivery_status", + "type": "support_delivery_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "delivery_attempts": { + "name": "delivery_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "next_delivery_at": { + "name": "next_delivery_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "delivery_error": { + "name": "delivery_error", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "rep_alert_pending": { + "name": "rep_alert_pending", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "support_message_ticket_idx": { + "name": "support_message_ticket_idx", + "columns": [ + { + "expression": "ticket_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_message_rfc_unique": { + "name": "support_message_rfc_unique", + "columns": [ + { + "expression": "ticket_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "rfc_message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "where": "\"support_message\".\"rfc_message_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_message_rfc_idx": { + "name": "support_message_rfc_idx", + "columns": [ + { + "expression": "rfc_message_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_message\".\"rfc_message_id\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_message_delivery_idx": { + "name": "support_message_delivery_idx", + "columns": [ + { + "expression": "next_delivery_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_message\".\"delivery_status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_message_accepted_idx": { + "name": "support_message_accepted_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_message\".\"delivery_status\" = 'accepted'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_message_alert_idx": { + "name": "support_message_alert_idx", + "columns": [ + { + "expression": "id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_message\".\"rep_alert_pending\"", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "support_message_ticket_id_support_ticket_id_fk": { + "name": "support_message_ticket_id_support_ticket_id_fk", + "tableFrom": "support_message", + "tableTo": "support_ticket", + "columnsFrom": [ + "ticket_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "support_message_author_user_id_user_id_fk": { + "name": "support_message_author_user_id_user_id_fk", + "tableFrom": "support_message", + "tableTo": "user", + "columnsFrom": [ + "author_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_saved_reply": { + "name": "support_saved_reply", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "body": { + "name": "body", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "created_by_user_id": { + "name": "created_by_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "support_saved_reply_title_unique": { + "name": "support_saved_reply_title_unique", + "columns": [ + { + "expression": "title", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "support_saved_reply_created_by_user_id_user_id_fk": { + "name": "support_saved_reply_created_by_user_id_user_id_fk", + "tableFrom": "support_saved_reply", + "tableTo": "user", + "columnsFrom": [ + "created_by_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_ticket": { + "name": "support_ticket", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "number": { + "name": "number", + "type": "integer", + "primaryKey": false, + "notNull": true, + "identity": { + "type": "always", + "name": "support_ticket_number_seq", + "schema": "public", + "increment": "1", + "startWith": "1001", + "minValue": "1", + "maxValue": "2147483647", + "cache": "1", + "cycle": false + } + }, + "reply_token": { + "name": "reply_token", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "subject": { + "name": "subject", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "category": { + "name": "category", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'other'" + }, + "severity": { + "name": "severity", + "type": "support_severity", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'normal'" + }, + "status": { + "name": "status", + "type": "support_ticket_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'open'" + }, + "source": { + "name": "source", + "type": "support_ticket_source", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "filter_reason": { + "name": "filter_reason", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "organization_name": { + "name": "organization_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "org_match": { + "name": "org_match", + "type": "support_org_match", + "typeSchema": "public", + "primaryKey": false, + "notNull": false + }, + "suggested_organization_id": { + "name": "suggested_organization_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requester_user_id": { + "name": "requester_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "requester_email": { + "name": "requester_email", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "requester_name": { + "name": "requester_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "sender_auth": { + "name": "sender_auth", + "type": "support_sender_auth", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "cc": { + "name": "cc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "suggested_cc": { + "name": "suggested_cc", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{}'::text[]" + }, + "assignee_user_id": { + "name": "assignee_user_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "plan": { + "name": "plan", + "type": "text", + "primaryKey": false, + "notNull": true, + "default": "'free'" + }, + "all_hours": { + "name": "all_hours", + "type": "boolean", + "primaryKey": false, + "notNull": true, + "default": false + }, + "awaiting_since": { + "name": "awaiting_since", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "response_due_at": { + "name": "response_due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "first_responded_at": { + "name": "first_responded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "breached_at": { + "name": "breached_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "risk_alerted_due_at": { + "name": "risk_alerted_due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "breach_alerted_due_at": { + "name": "breach_alerted_due_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "snoozed_until": { + "name": "snoozed_until", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "resolved_at": { + "name": "resolved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_customer_message_at": { + "name": "last_customer_message_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_agent_message_at": { + "name": "last_agent_message_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "last_message_at": { + "name": "last_message_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "context": { + "name": "context", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'{}'::jsonb" + }, + "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": { + "support_ticket_number_unique": { + "name": "support_ticket_number_unique", + "columns": [ + { + "expression": "number", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_reply_token_unique": { + "name": "support_ticket_reply_token_unique", + "columns": [ + { + "expression": "reply_token", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_queue_idx": { + "name": "support_ticket_queue_idx", + "columns": [ + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "response_due_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_organization_idx": { + "name": "support_ticket_organization_idx", + "columns": [ + { + "expression": "organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "last_message_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_suggested_idx": { + "name": "support_ticket_suggested_idx", + "columns": [ + { + "expression": "suggested_organization_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_requester_idx": { + "name": "support_ticket_requester_idx", + "columns": [ + { + "expression": "requester_email", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_requester_user_idx": { + "name": "support_ticket_requester_user_idx", + "columns": [ + { + "expression": "requester_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_assignee_idx": { + "name": "support_ticket_assignee_idx", + "columns": [ + { + "expression": "assignee_user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "status", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "support_ticket_snoozed_idx": { + "name": "support_ticket_snoozed_idx", + "columns": [ + { + "expression": "snoozed_until", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"support_ticket\".\"snoozed_until\" IS NOT NULL", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "support_ticket_organization_id_organization_id_fk": { + "name": "support_ticket_organization_id_organization_id_fk", + "tableFrom": "support_ticket", + "tableTo": "organization", + "columnsFrom": [ + "organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "support_ticket_suggested_organization_id_organization_id_fk": { + "name": "support_ticket_suggested_organization_id_organization_id_fk", + "tableFrom": "support_ticket", + "tableTo": "organization", + "columnsFrom": [ + "suggested_organization_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "support_ticket_requester_user_id_user_id_fk": { + "name": "support_ticket_requester_user_id_user_id_fk", + "tableFrom": "support_ticket", + "tableTo": "user", + "columnsFrom": [ + "requester_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + }, + "support_ticket_assignee_user_id_user_id_fk": { + "name": "support_ticket_assignee_user_id_user_id_fk", + "tableFrom": "support_ticket", + "tableTo": "user", + "columnsFrom": [ + "assignee_user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.support_ticket_read": { + "name": "support_ticket_read", + "schema": "", + "columns": { + "ticket_id": { + "name": "ticket_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "read_at": { + "name": "read_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "support_ticket_read_unique": { + "name": "support_ticket_read_unique", + "columns": [ + { + "expression": "ticket_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "user_id", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": true, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "support_ticket_read_ticket_id_support_ticket_id_fk": { + "name": "support_ticket_read_ticket_id_support_ticket_id_fk", + "tableFrom": "support_ticket_read", + "tableTo": "support_ticket", + "columnsFrom": [ + "ticket_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "support_ticket_read_user_id_user_id_fk": { + "name": "support_ticket_read_user_id_user_id_fk", + "tableFrom": "support_ticket_read", + "tableTo": "user", + "columnsFrom": [ + "user_id" + ], + "columnsTo": [ + "id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verify_check": { + "name": "verify_check", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "valid": { + "name": "valid", + "type": "boolean", + "primaryKey": false, + "notNull": true + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "verify_check_request_fk": { + "name": "verify_check_request_fk", + "tableFrom": "verify_check", + "tableTo": "verify_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "verify_check_request_idempotency_key_unique": { + "name": "verify_check_request_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "request_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verify_request": { + "name": "verify_request", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_owner_id": { + "name": "api_key_owner_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "channel": { + "name": "channel", + "type": "verify_channel", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "to": { + "name": "to", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "to_country": { + "name": "to_country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "status": { + "name": "status", + "type": "verify_status", + "typeSchema": "public", + "primaryKey": false, + "notNull": true, + "default": "'pending'" + }, + "failure_code": { + "name": "failure_code", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "risk_reasons": { + "name": "risk_reasons", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "code_hash": { + "name": "code_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "code_length": { + "name": "code_length", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "attempts": { + "name": "attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "sends": { + "name": "sends", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 0 + }, + "expires_at": { + "name": "expires_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true + }, + "approved_at": { + "name": "approved_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "tags": { + "name": "tags", + "type": "jsonb", + "primaryKey": false, + "notNull": true, + "default": "'[]'::jsonb" + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "verify_request_environment_created_at_idx": { + "name": "verify_request_environment_created_at_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "created_at", + "isExpression": false, + "asc": false, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + }, + "verify_request_pending_to_idx": { + "name": "verify_request_pending_to_idx", + "columns": [ + { + "expression": "environment_id", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "to", + "isExpression": false, + "asc": true, + "nulls": "last" + }, + { + "expression": "channel", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"verify_request\".\"status\" = 'pending'", + "concurrently": false, + "method": "btree", + "with": {} + }, + "verify_request_created_at_idx": { + "name": "verify_request_created_at_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "verify_request_environment_fk": { + "name": "verify_request_environment_fk", + "tableFrom": "verify_request", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "verify_request_environment_idempotency_key_unique": { + "name": "verify_request_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + }, + "verify_request_id_organization_unique": { + "name": "verify_request_id_organization_unique", + "nullsNotDistinct": false, + "columns": [ + "id", + "organization_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verify_send": { + "name": "verify_send", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "request_id": { + "name": "request_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "sequence": { + "name": "sequence", + "type": "integer", + "primaryKey": false, + "notNull": true + }, + "channel": { + "name": "channel", + "type": "verify_channel", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "route": { + "name": "route", + "type": "verify_send_route", + "typeSchema": "public", + "primaryKey": false, + "notNull": true + }, + "sms_id": { + "name": "sms_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_id": { + "name": "email_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "message_environment_id": { + "name": "message_environment_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_id": { + "name": "api_key_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "api_key_owner_id": { + "name": "api_key_owner_id", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "country": { + "name": "country", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "usage_recorded_at": { + "name": "usage_recorded_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": false + }, + "idempotency_key": { + "name": "idempotency_key", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "request_hash": { + "name": "request_hash", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": { + "verify_send_unmetered_idx": { + "name": "verify_send_unmetered_idx", + "columns": [ + { + "expression": "created_at", + "isExpression": false, + "asc": true, + "nulls": "last" + } + ], + "isUnique": false, + "where": "\"verify_send\".\"route\" = 'shared_number' and \"verify_send\".\"usage_recorded_at\" is null", + "concurrently": false, + "method": "btree", + "with": {} + } + }, + "foreignKeys": { + "verify_send_request_fk": { + "name": "verify_send_request_fk", + "tableFrom": "verify_send", + "tableTo": "verify_request", + "columnsFrom": [ + "request_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "verify_send_request_sequence_unique": { + "name": "verify_send_request_sequence_unique", + "nullsNotDistinct": false, + "columns": [ + "request_id", + "sequence" + ] + }, + "verify_send_environment_idempotency_key_unique": { + "name": "verify_send_environment_idempotency_key_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id", + "idempotency_key" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + }, + "public.verify_settings": { + "name": "verify_settings", + "schema": "", + "columns": { + "id": { + "name": "id", + "type": "text", + "primaryKey": true, + "notNull": true + }, + "organization_id": { + "name": "organization_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "project_id": { + "name": "project_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "environment_id": { + "name": "environment_id", + "type": "text", + "primaryKey": false, + "notNull": true + }, + "app_name": { + "name": "app_name", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "code_length": { + "name": "code_length", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 6 + }, + "ttl_seconds": { + "name": "ttl_seconds", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 600 + }, + "max_attempts": { + "name": "max_attempts", + "type": "integer", + "primaryKey": false, + "notNull": true, + "default": 5 + }, + "sms_from": { + "name": "sms_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "email_from": { + "name": "email_from", + "type": "text", + "primaryKey": false, + "notNull": false + }, + "allowed_countries": { + "name": "allowed_countries", + "type": "text[]", + "primaryKey": false, + "notNull": true, + "default": "'{US,CA}'::text[]" + }, + "created_at": { + "name": "created_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + }, + "updated_at": { + "name": "updated_at", + "type": "timestamp with time zone", + "primaryKey": false, + "notNull": true, + "default": "now()" + } + }, + "indexes": {}, + "foreignKeys": { + "verify_settings_environment_fk": { + "name": "verify_settings_environment_fk", + "tableFrom": "verify_settings", + "tableTo": "environment", + "columnsFrom": [ + "environment_id", + "organization_id" + ], + "columnsTo": [ + "id", + "organization_id" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": { + "verify_settings_environment_unique": { + "name": "verify_settings_environment_unique", + "nullsNotDistinct": false, + "columns": [ + "environment_id" + ] + } + }, + "policies": {}, + "checkConstraints": {}, + "isRLSEnabled": false + } + }, + "enums": { + "public.billing_account_status": { + "name": "billing_account_status", + "schema": "public", + "values": [ + "active", + "past_due", + "delinquent" + ] + }, + "public.billing_budget_scope": { + "name": "billing_budget_scope", + "schema": "public", + "values": [ + "member_default", + "user", + "project", + "api_key" + ] + }, + "public.billing_collection_method": { + "name": "billing_collection_method", + "schema": "public", + "values": [ + "charge_automatically", + "send_invoice" + ] + }, + "public.billing_contract_kind": { + "name": "billing_contract_kind", + "schema": "public", + "values": [ + "self_serve", + "sales", + "internal" + ] + }, + "public.billing_contract_status": { + "name": "billing_contract_status", + "schema": "public", + "values": [ + "pending", + "confirmed", + "canceled" + ] + }, + "public.billing_credit_entry_kind": { + "name": "billing_credit_entry_kind", + "schema": "public", + "values": [ + "applied", + "reversed", + "voided", + "rolled_over" + ] + }, + "public.billing_credit_note_status": { + "name": "billing_credit_note_status", + "schema": "public", + "values": [ + "pending", + "issued", + "failed" + ] + }, + "public.billing_grant_applies_to": { + "name": "billing_grant_applies_to", + "schema": "public", + "values": [ + "usage", + "any" + ] + }, + "public.billing_grant_kind": { + "name": "billing_grant_kind", + "schema": "public", + "values": [ + "amount", + "units" + ] + }, + "public.billing_grant_source": { + "name": "billing_grant_source", + "schema": "public", + "values": [ + "fee", + "commitment", + "support", + "promotion", + "refund", + "sla" + ] + }, + "public.billing_hold_reason": { + "name": "billing_hold_reason", + "schema": "public", + "values": [ + "delinquent", + "spend_limit", + "admin" + ] + }, + "public.billing_invoice_kind": { + "name": "billing_invoice_kind", + "schema": "public", + "values": [ + "period", + "plan_change", + "one_off", + "final" + ] + }, + "public.billing_invoice_status": { + "name": "billing_invoice_status", + "schema": "public", + "values": [ + "draft", + "open", + "paid", + "void", + "uncollectible" + ] + }, + "public.billing_line_kind": { + "name": "billing_line_kind", + "schema": "public", + "values": [ + "plan_fee", + "proration", + "usage", + "credit", + "discount", + "commitment_fee", + "commitment_shortfall", + "add_on", + "adjustment", + "write_off" + ] + }, + "public.billing_notification_status": { + "name": "billing_notification_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.billing_provider": { + "name": "billing_provider", + "schema": "public", + "values": [ + "fake", + "stripe", + "manual" + ] + }, + "public.billing_provider_event_status": { + "name": "billing_provider_event_status", + "schema": "public", + "values": [ + "pending", + "processed", + "ignored", + "failed" + ] + }, + "public.billing_sync_action": { + "name": "billing_sync_action", + "schema": "public", + "values": [ + "push", + "collect", + "void", + "mark_uncollectible" + ] + }, + "public.billing_tax_mode": { + "name": "billing_tax_mode", + "schema": "public", + "values": [ + "none", + "stripe_automatic" + ] + }, + "public.api_key_access": { + "name": "api_key_access", + "schema": "public", + "values": [ + "full", + "restricted" + ] + }, + "public.auth_email_kind": { + "name": "auth_email_kind", + "schema": "public", + "values": [ + "verify_email", + "reset_password", + "invitation" + ] + }, + "public.auth_email_status": { + "name": "auth_email_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.broadcast_screening_status": { + "name": "broadcast_screening_status", + "schema": "public", + "values": [ + "pending", + "passed", + "held", + "blocked" + ] + }, + "public.broadcast_status": { + "name": "broadcast_status", + "schema": "public", + "values": [ + "draft", + "scheduled", + "sending", + "paused", + "sent", + "canceled", + "failed" + ] + }, + "public.contact_property_type": { + "name": "contact_property_type", + "schema": "public", + "values": [ + "string", + "number", + "boolean", + "date" + ] + }, + "public.contact_source": { + "name": "contact_source", + "schema": "public", + "values": [ + "api", + "dashboard", + "import", + "preference_center", + "form" + ] + }, + "public.contact_status": { + "name": "contact_status", + "schema": "public", + "values": [ + "subscribed", + "unsubscribed", + "pending" + ] + }, + "public.contact_topic_status": { + "name": "contact_topic_status", + "schema": "public", + "values": [ + "opted_in", + "opted_out" + ] + }, + "public.content_screening_verdict": { + "name": "content_screening_verdict", + "schema": "public", + "values": [ + "clean", + "flagged", + "blocked", + "error" + ] + }, + "public.dedicated_ip_pool_status": { + "name": "dedicated_ip_pool_status", + "schema": "public", + "values": [ + "waiting", + "provisioning", + "warming", + "ready", + "releasing" + ] + }, + "public.dmarc_notification_kind": { + "name": "dmarc_notification_kind", + "schema": "public", + "values": [ + "ready_quarantine", + "ready_reject", + "pass_rate_dropped" + ] + }, + "public.dmarc_notification_status": { + "name": "dmarc_notification_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.domain_status": { + "name": "domain_status", + "schema": "public", + "values": [ + "pending", + "verified", + "temporary_failure", + "failed", + "deleting" + ] + }, + "public.email_event_type": { + "name": "email_event_type", + "schema": "public", + "values": [ + "email.sent", + "email.delivered", + "email.delivery_delayed", + "email.bounced", + "email.complained", + "email.failed", + "email.suppressed", + "email.scheduled", + "email.canceled", + "email.opened", + "email.clicked", + "email.rescheduled", + "email.unsubscribed" + ] + }, + "public.email_recipient_kind": { + "name": "email_recipient_kind", + "schema": "public", + "values": [ + "to", + "cc", + "bcc" + ] + }, + "public.email_recipient_status": { + "name": "email_recipient_status", + "schema": "public", + "values": [ + "queued", + "sent", + "delivery_delayed", + "delivered", + "bounced", + "suppressed", + "complained", + "failed", + "canceled" + ] + }, + "public.email_status": { + "name": "email_status", + "schema": "public", + "values": [ + "queued", + "sent", + "failed", + "scheduled", + "canceled" + ] + }, + "public.email_stream": { + "name": "email_stream", + "schema": "public", + "values": [ + "transactional", + "marketing" + ] + }, + "public.email_subaccount_reputation": { + "name": "email_subaccount_reputation", + "schema": "public", + "values": [ + "good", + "warning", + "paused" + ] + }, + "public.email_subaccount_status": { + "name": "email_subaccount_status", + "schema": "public", + "values": [ + "active", + "disabled", + "deleting" + ] + }, + "public.email_suppression_reason": { + "name": "email_suppression_reason", + "schema": "public", + "values": [ + "bounce", + "complaint", + "manual", + "import", + "unsubscribe" + ] + }, + "public.environment_mode": { + "name": "environment_mode", + "schema": "public", + "values": [ + "live", + "sandbox" + ] + }, + "public.hook_delivery_status": { + "name": "hook_delivery_status", + "schema": "public", + "values": [ + "pending", + "succeeded", + "failed" + ] + }, + "public.hook_recovery_status": { + "name": "hook_recovery_status", + "schema": "public", + "values": [ + "pending", + "completed" + ] + }, + "public.log_drain_batch_status": { + "name": "log_drain_batch_status", + "schema": "public", + "values": [ + "pending", + "succeeded", + "failed" + ] + }, + "public.log_drain_format": { + "name": "log_drain_format", + "schema": "public", + "values": [ + "ndjson", + "loki", + "datadog", + "otlp" + ] + }, + "public.log_drain_source": { + "name": "log_drain_source", + "schema": "public", + "values": [ + "api", + "email", + "webhook", + "risk", + "audit", + "smtp", + "sms", + "sign", + "verify", + "forms", + "scheduling" + ] + }, + "public.log_level": { + "name": "log_level", + "schema": "public", + "values": [ + "info", + "warning", + "error" + ] + }, + "public.log_source": { + "name": "log_source", + "schema": "public", + "values": [ + "api", + "email", + "webhook", + "risk", + "smtp", + "sms", + "sign", + "verify", + "forms", + "scheduling" + ] + }, + "public.mail_from_status": { + "name": "mail_from_status", + "schema": "public", + "values": [ + "pending", + "success", + "temporary_failure", + "failed" + ] + }, + "public.migration_item_kind": { + "name": "migration_item_kind", + "schema": "public", + "values": [ + "domain", + "property", + "topic", + "audience", + "template", + "webhook_endpoint" + ] + }, + "public.migration_item_outcome": { + "name": "migration_item_outcome", + "schema": "public", + "values": [ + "pending", + "created", + "existing", + "skipped", + "failed" + ] + }, + "public.migration_provider": { + "name": "migration_provider", + "schema": "public", + "values": [ + "resend", + "sendgrid", + "postmark" + ] + }, + "public.migration_status": { + "name": "migration_status", + "schema": "public", + "values": [ + "inspecting", + "ready", + "queued", + "running", + "completed", + "failed", + "canceled" + ] + }, + "public.org_audit_actor_type": { + "name": "org_audit_actor_type", + "schema": "public", + "values": [ + "user", + "api_key", + "system" + ] + }, + "public.organization_deletion_status": { + "name": "organization_deletion_status", + "schema": "public", + "values": [ + "pending", + "completed" + ] + }, + "public.organization_logo_status": { + "name": "organization_logo_status", + "schema": "public", + "values": [ + "found", + "not_found", + "hidden" + ] + }, + "public.received_email_status": { + "name": "received_email_status", + "schema": "public", + "values": [ + "received", + "blocked" + ] + }, + "public.reputation_actor": { + "name": "reputation_actor", + "schema": "public", + "values": [ + "system", + "admin" + ] + }, + "public.reputation_event_type": { + "name": "reputation_event_type", + "schema": "public", + "values": [ + "warning_raised", + "warning_cleared", + "suspended", + "reinstated", + "policy_updated", + "marketing_paused", + "marketing_reinstated" + ] + }, + "public.reputation_notification_status": { + "name": "reputation_notification_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.reputation_status": { + "name": "reputation_status", + "schema": "public", + "values": [ + "good", + "warning", + "suspended" + ] + }, + "public.risk_captcha_provider": { + "name": "risk_captcha_provider", + "schema": "public", + "values": [ + "turnstile", + "hcaptcha" + ] + }, + "public.risk_decision": { + "name": "risk_decision", + "schema": "public", + "values": [ + "allow", + "review", + "block" + ] + }, + "public.risk_event": { + "name": "risk_event", + "schema": "public", + "values": [ + "signup", + "login", + "message", + "checkout", + "custom" + ] + }, + "public.risk_feedback_source": { + "name": "risk_feedback_source", + "schema": "public", + "values": [ + "api", + "dashboard" + ] + }, + "public.risk_identity_kind": { + "name": "risk_identity_kind", + "schema": "public", + "values": [ + "mailbox", + "device" + ] + }, + "public.risk_limit_failure_mode": { + "name": "risk_limit_failure_mode", + "schema": "public", + "values": [ + "allow", + "deny" + ] + }, + "public.risk_list": { + "name": "risk_list", + "schema": "public", + "values": [ + "allow", + "block" + ] + }, + "public.risk_list_entry_type": { + "name": "risk_list_entry_type", + "schema": "public", + "values": [ + "email", + "domain", + "ip", + "asn", + "country", + "user" + ] + }, + "public.risk_outcome": { + "name": "risk_outcome", + "schema": "public", + "values": [ + "legitimate", + "fraud", + "abuse" + ] + }, + "public.risk_report_kind": { + "name": "risk_report_kind", + "schema": "public", + "values": [ + "mailbox", + "ip", + "subnet", + "user", + "card", + "device" + ] + }, + "public.risk_review_status": { + "name": "risk_review_status", + "schema": "public", + "values": [ + "open", + "resolved" + ] + }, + "public.risk_rule_match": { + "name": "risk_rule_match", + "schema": "public", + "values": [ + "all", + "any" + ] + }, + "public.risk_user_network_kind": { + "name": "risk_user_network_kind", + "schema": "public", + "values": [ + "country", + "asn" + ] + }, + "public.tenant_sending_status": { + "name": "tenant_sending_status", + "schema": "public", + "values": [ + "enabled", + "disabled", + "reinstated" + ] + }, + "public.topic_default_subscription": { + "name": "topic_default_subscription", + "schema": "public", + "values": [ + "opt_in", + "opt_out" + ] + }, + "public.topic_visibility": { + "name": "topic_visibility", + "schema": "public", + "values": [ + "public", + "private" + ] + }, + "public.tracking_domain_status": { + "name": "tracking_domain_status", + "schema": "public", + "values": [ + "pending", + "active", + "temporary_failure", + "failed", + "deleting" + ] + }, + "public.webhook_delivery_status": { + "name": "webhook_delivery_status", + "schema": "public", + "values": [ + "pending", + "succeeded", + "failed" + ] + }, + "public.form_captcha": { + "name": "form_captcha", + "schema": "public", + "values": [ + "off", + "required" + ] + }, + "public.form_delivery_kind": { + "name": "form_delivery_kind", + "schema": "public", + "values": [ + "notification", + "contact", + "verification" + ] + }, + "public.form_delivery_state": { + "name": "form_delivery_state", + "schema": "public", + "values": [ + "pending", + "delivered", + "failed", + "skipped" + ] + }, + "public.form_on_review": { + "name": "form_on_review", + "schema": "public", + "values": [ + "deliver", + "hold" + ] + }, + "public.form_spam_reason": { + "name": "form_spam_reason", + "schema": "public", + "values": [ + "honeypot", + "risk_block", + "risk_review", + "content" + ] + }, + "public.form_submission_status": { + "name": "form_submission_status", + "schema": "public", + "values": [ + "pending_confirmation", + "accepted", + "held", + "spam" + ] + }, + "public.inbox_kind": { + "name": "inbox_kind", + "schema": "public", + "values": [ + "managed", + "domain" + ] + }, + "public.inbox_message_direction": { + "name": "inbox_message_direction", + "schema": "public", + "values": [ + "inbound", + "outbound" + ] + }, + "public.notification_status": { + "name": "notification_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.apns_environment": { + "name": "apns_environment", + "schema": "public", + "values": [ + "production", + "sandbox" + ] + }, + "public.push_notification_kind": { + "name": "push_notification_kind", + "schema": "public", + "values": [ + "reputation_warning", + "reputation_suspended", + "billing_payment_failed", + "billing_hold_placed", + "billing_budget_paused", + "webhook_endpoint_disabled", + "hook_endpoint_disabled", + "log_drain_disabled", + "risk_review" + ] + }, + "public.push_notification_status": { + "name": "push_notification_status", + "schema": "public", + "values": [ + "pending", + "sent", + "skipped", + "failed" + ] + }, + "public.scheduling_booking_status": { + "name": "scheduling_booking_status", + "schema": "public", + "values": [ + "held", + "pending_approval", + "confirmed", + "cancelled", + "declined" + ] + }, + "public.scheduling_calendar_event_state": { + "name": "scheduling_calendar_event_state", + "schema": "public", + "values": [ + "present", + "absent" + ] + }, + "public.scheduling_calendar_failure_mode": { + "name": "scheduling_calendar_failure_mode", + "schema": "public", + "values": [ + "hide", + "last_known" + ] + }, + "public.scheduling_calendar_provider": { + "name": "scheduling_calendar_provider", + "schema": "public", + "values": [ + "google", + "microsoft", + "caldav", + "simulated", + "zoom" + ] + }, + "public.scheduling_connection_status": { + "name": "scheduling_connection_status", + "schema": "public", + "values": [ + "active", + "needs_reauth" + ] + }, + "public.scheduling_event_type_kind": { + "name": "scheduling_event_type_kind", + "schema": "public", + "values": [ + "one_on_one", + "pool", + "collective", + "group" + ] + }, + "public.scheduling_event_type_status": { + "name": "scheduling_event_type_status", + "schema": "public", + "values": [ + "active", + "archived" + ] + }, + "public.scheduling_external_state": { + "name": "scheduling_external_state", + "schema": "public", + "values": [ + "in_sync", + "moved", + "deleted" + ] + }, + "public.scheduling_host_role": { + "name": "scheduling_host_role", + "schema": "public", + "values": [ + "required", + "member" + ] + }, + "public.scheduling_host_status": { + "name": "scheduling_host_status", + "schema": "public", + "values": [ + "active", + "disabled" + ] + }, + "public.scheduling_notification_channel": { + "name": "scheduling_notification_channel", + "schema": "public", + "values": [ + "email", + "sms" + ] + }, + "public.scheduling_notification_recipient": { + "name": "scheduling_notification_recipient", + "schema": "public", + "values": [ + "attendee", + "host" + ] + }, + "public.scheduling_session_kind": { + "name": "scheduling_session_kind", + "schema": "public", + "values": [ + "host", + "booker", + "manage" + ] + }, + "public.sign_authentication": { + "name": "sign_authentication", + "schema": "public", + "values": [ + "email_link", + "customer_asserted" + ] + }, + "public.sign_delivery": { + "name": "sign_delivery", + "schema": "public", + "values": [ + "embedded", + "email" + ] + }, + "public.sign_event_type": { + "name": "sign_event_type", + "schema": "public", + "values": [ + "created", + "sent", + "notified", + "viewed", + "consented", + "signed", + "declined", + "reminded", + "canceled", + "expired", + "completed", + "sealed" + ] + }, + "public.sign_field_type": { + "name": "sign_field_type", + "schema": "public", + "values": [ + "signature", + "initials", + "date_signed", + "name", + "email", + "text", + "checkbox" + ] + }, + "public.sign_request_status": { + "name": "sign_request_status", + "schema": "public", + "values": [ + "draft", + "sent", + "completed", + "declined", + "canceled", + "expired" + ] + }, + "public.sign_signer_status": { + "name": "sign_signer_status", + "schema": "public", + "values": [ + "pending", + "notified", + "viewed", + "signed", + "declined" + ] + }, + "public.sign_signing_order": { + "name": "sign_signing_order", + "schema": "public", + "values": [ + "parallel", + "sequential" + ] + }, + "public.sms_account_status": { + "name": "sms_account_status", + "schema": "public", + "values": [ + "active", + "closing", + "closed" + ] + }, + "public.sms_event_type": { + "name": "sms_event_type", + "schema": "public", + "values": [ + "sms.scheduled", + "sms.sent", + "sms.delivered", + "sms.undelivered", + "sms.failed", + "sms.suppressed", + "sms.canceled" + ] + }, + "public.sms_number_kind": { + "name": "sms_number_kind", + "schema": "public", + "values": [ + "local", + "toll_free" + ] + }, + "public.sms_number_status": { + "name": "sms_number_status", + "schema": "public", + "values": [ + "pending", + "active", + "releasing" + ] + }, + "public.sms_registration_kind": { + "name": "sms_registration_kind", + "schema": "public", + "values": [ + "us_10dlc", + "toll_free" + ] + }, + "public.sms_registration_status": { + "name": "sms_registration_status", + "schema": "public", + "values": [ + "draft", + "submitted", + "in_review", + "approved", + "rejected", + "failed" + ] + }, + "public.sms_status": { + "name": "sms_status", + "schema": "public", + "values": [ + "queued", + "scheduled", + "sent", + "delivered", + "undelivered", + "failed", + "canceled" + ] + }, + "public.sms_suppression_reason": { + "name": "sms_suppression_reason", + "schema": "public", + "values": [ + "opt_out", + "manual", + "invalid_number" + ] + }, + "public.support_attachment_state": { + "name": "support_attachment_state", + "schema": "public", + "values": [ + "uploaded", + "pending_copy", + "stored", + "failed" + ] + }, + "public.support_delivery_status": { + "name": "support_delivery_status", + "schema": "public", + "values": [ + "pending", + "accepted", + "delivered", + "bounced", + "failed" + ] + }, + "public.support_message_kind": { + "name": "support_message_kind", + "schema": "public", + "values": [ + "customer", + "agent", + "note", + "event" + ] + }, + "public.support_org_match": { + "name": "support_org_match", + "schema": "public", + "values": [ + "session", + "email", + "manual" + ] + }, + "public.support_sender_auth": { + "name": "support_sender_auth", + "schema": "public", + "values": [ + "session", + "dmarc_pass", + "unverified" + ] + }, + "public.support_severity": { + "name": "support_severity", + "schema": "public", + "values": [ + "normal", + "urgent" + ] + }, + "public.support_ticket_source": { + "name": "support_ticket_source", + "schema": "public", + "values": [ + "email", + "dashboard" + ] + }, + "public.support_ticket_status": { + "name": "support_ticket_status", + "schema": "public", + "values": [ + "open", + "pending", + "snoozed", + "resolved", + "spam" + ] + }, + "public.verify_channel": { + "name": "verify_channel", + "schema": "public", + "values": [ + "sms", + "email" + ] + }, + "public.verify_send_route": { + "name": "verify_send_route", + "schema": "public", + "values": [ + "own_number", + "shared_number", + "email", + "coss_email" + ] + }, + "public.verify_status": { + "name": "verify_status", + "schema": "public", + "values": [ + "pending", + "approved", + "expired", + "canceled", + "failed", + "blocked" + ] + } + }, + "schemas": {}, + "sequences": {}, + "roles": {}, + "policies": {}, + "views": {}, + "_meta": { + "columns": {}, + "schemas": {}, + "tables": {} + } +} \ No newline at end of file diff --git a/packages/db/migrations/meta/_journal.json b/packages/db/migrations/meta/_journal.json index 01e12b5f1..4e172ad47 100644 --- a/packages/db/migrations/meta/_journal.json +++ b/packages/db/migrations/meta/_journal.json @@ -890,6 +890,13 @@ "when": 1793813887482, "tag": "0126_tidy_marauders", "breakpoints": true + }, + { + "idx": 127, + "version": "7", + "when": 1793814158502, + "tag": "0127_careful_ultron", + "breakpoints": true } ] } \ No newline at end of file diff --git a/packages/db/src/schema/scheduling.ts b/packages/db/src/schema/scheduling.ts index e76a58743..c0d86fe29 100644 --- a/packages/db/src/schema/scheduling.ts +++ b/packages/db/src/schema/scheduling.ts @@ -524,6 +524,9 @@ export const schedulingBooking = pgTable( // Bumped by every change; notifications and calendar writes compare against it. version: integer("version").notNull().default(1), metadata: jsonb("metadata").$type>().notNull().default({}), + // What it was routed with, for choosing another host. `{}` encrypted when nothing narrowed it; + // null when booked before this existed, or erased, so the routing can't be known. + encryptedAttributes: text("encrypted_attributes"), idempotencyKey: text("idempotency_key"), requestHash: text("request_hash"), usageRecordedAt: instant("usage_recorded_at"), diff --git a/packages/scheduling/AGENTS.md b/packages/scheduling/AGENTS.md index f21f58f7a..391477835 100644 --- a/packages/scheduling/AGENTS.md +++ b/packages/scheduling/AGENTS.md @@ -132,6 +132,9 @@ attendee sees times, never other hosts. - Attendee contact details and answers, and a booker session's fixed attendee, are encrypted with `SCHEDULING_DATA_KEYS`. Only `email_hmac` is searchable. A new column on this ring goes in `SCHEDULING_DATA_KEY_COLUMNS` and `reencryptSchedulingData` (a test compares the list with the database). +- `scheduling_booking.encrypted_attributes` keeps what a booking was routed with, for choosing another host later. Null + means that can't be known (booked before it existed, or erased or redacted), never "nothing narrowed it", which is + an encrypted `{}`. It goes with the attendee's details: on redaction and on `eraseAttendee`. - Answers come back only from `getBooking`: never lists, webhooks, logs, emails or calendars. The dashboard's iOS routes map bookings to name or uid only (`scheduling/wire.ts` under `apps/web/src/app/api/mobile/v1`). - Webhooks and log lines carry ids, times and statuses. `request-log.ts` keeps no bodies of these routes. diff --git a/packages/scheduling/src/attendees.ts b/packages/scheduling/src/attendees.ts index 122625f1f..9d9e75f51 100644 --- a/packages/scheduling/src/attendees.ts +++ b/packages/scheduling/src/attendees.ts @@ -11,6 +11,7 @@ export type AttendeeContact = { }; export type BookingAnswers = Record; +export type RoutingAttributes = Record; type Keys = Pick; export function emailLookup(email: string, keys: Pick): string { @@ -45,6 +46,23 @@ export function encryptAnswers(answers: BookingAnswers | undefined, keys: Keys): return encryptSecret(JSON.stringify(answers), keys.dataKeys); } +/** Always stored, even empty: null means the routing can't be known, which is a different answer. */ +export function encryptRouting( + attributes: RoutingAttributes | undefined, + keys: Pick, +): string { + return encryptSecret(JSON.stringify(attributes ?? {}), keys.dataKeys); +} + +/** Null when a booking can't say what it was routed with, so nobody may guess that it was nothing. */ +export function decryptRouting( + stored: string | null, + keys: Pick, +): RoutingAttributes | null { + if (!stored) return null; + return JSON.parse(decryptSecret(stored, keys.dataKeys)) as RoutingAttributes; +} + export function decryptAnswers( stored: string | null, keys: Pick, diff --git a/packages/scheduling/src/bookings.ts b/packages/scheduling/src/bookings.ts index ee5fd313b..c44321b1f 100644 --- a/packages/scheduling/src/bookings.ts +++ b/packages/scheduling/src/bookings.ts @@ -34,6 +34,7 @@ import { emailLookup, encryptAnswers, encryptContact, + encryptRouting, } from "./attendees.ts"; import { type Candidates, @@ -872,6 +873,7 @@ async function insertBookingRow( seriesId: values.seriesId ?? null, seriesIndex: values.seriesIndex ?? null, metadata: request.metadata ?? {}, + encryptedAttributes: encryptRouting(request.attributes, context.deps), idempotencyKey: values.idempotencyKey, requestHash: values.hash, }) diff --git a/packages/scheduling/src/reencrypt.ts b/packages/scheduling/src/reencrypt.ts index 0c739c148..47993907b 100644 --- a/packages/scheduling/src/reencrypt.ts +++ b/packages/scheduling/src/reencrypt.ts @@ -4,12 +4,13 @@ import type { SecretsKeyRing } from "@coss/webhooks"; import { decryptSecret, encryptSecret, isEncryptedWithPrimary } from "@coss/webhooks"; import { and, asc, eq, gt, inArray, isNotNull, isNull, or } from "drizzle-orm"; -const { schedulingAttendee, schedulingSession } = schema; +const { schedulingAttendee, schedulingBooking, schedulingSession } = schema; /** A test compares this with the database's columns. */ export const SCHEDULING_DATA_KEY_COLUMNS = [ "scheduling_attendee.encrypted_contact", "scheduling_attendee.encrypted_answers", + "scheduling_booking.encrypted_attributes", "scheduling_session.encrypted_attendee", "scheduling_session.encrypted_attributes", ] as const; @@ -161,6 +162,63 @@ async function reencryptAttendees(opts: Options, result: SchedulingReencryptResu } } +async function reencryptBookings(opts: Options, result: SchedulingReencryptResult): Promise { + const batchSize = opts.batchSize ?? 200; + let after = ""; + for (;;) { + const rows = await db + .select({ + id: schedulingBooking.id, + organizationId: schedulingBooking.organizationId, + attributes: schedulingBooking.encryptedAttributes, + }) + .from(schedulingBooking) + .where( + and( + gt(schedulingBooking.id, after), + isNotNull(schedulingBooking.encryptedAttributes), + opts.scope + ? inArray(schedulingBooking.organizationId, [...opts.scope.organizationIds]) + : undefined, + ), + ) + .orderBy(asc(schedulingBooking.id)) + .limit(batchSize); + for (const row of rows) { + result.checked++; + const next = rewritten( + row, + [["scheduling_booking.encrypted_attributes", row.attributes]], + opts, + result, + ); + if (!next) continue; + if (opts.dryRun) { + result.reencrypted++; + continue; + } + await opts.beforeWrite?.(row.id); + // The compare-and-set is what keeps a booking erased meanwhile erased. + const [updated] = await db + .update(schedulingBooking) + .set({ encryptedAttributes: next.get("scheduling_booking.encrypted_attributes") ?? null }) + .where( + and( + eq(schedulingBooking.id, row.id), + eq(schedulingBooking.organizationId, row.organizationId), + eq(schedulingBooking.encryptedAttributes, row.attributes as string), + ), + ) + .returning({ id: schedulingBooking.id }); + if (updated) result.reencrypted++; + else result.conflicts++; + } + const last = rows.at(-1); + if (!last || rows.length < batchSize) break; + after = last.id; + } +} + // Expired sessions count too: they still hold someone's details. async function reencryptSessions(opts: Options, result: SchedulingReencryptResult): Promise { const batchSize = opts.batchSize ?? 200; @@ -243,6 +301,7 @@ export async function reencryptSchedulingData(opts: Options): Promise 0) { + await tx + .update(schedulingBooking) + .set({ encryptedAttributes: null }) + .where( + and( + eq(schedulingBooking.organizationId, scope.organizationId), + eq(schedulingBooking.environmentId, scope.environmentId), + inArray( + schedulingBooking.id, + erased.map((row) => row.bookingId), + ), + ), + ); + } await tx .update(schedulingSession) .set({ diff --git a/packages/scheduling/test/host-changes.test.ts b/packages/scheduling/test/host-changes.test.ts index acd792c64..b34025ead 100644 --- a/packages/scheduling/test/host-changes.test.ts +++ b/packages/scheduling/test/host-changes.test.ts @@ -4,7 +4,7 @@ import { createHash } from "node:crypto"; import { db, schema } from "@coss/db"; import { uniqueSuffix } from "@coss/db/testing"; import { createTestTenant } from "@coss/tenancy/testing"; -import { secretsKeyRing } from "@coss/webhooks"; +import { isEncryptedWithPrimary, secretsKeyRing } from "@coss/webhooks"; import { and, eq } from "drizzle-orm"; import { type CalendarDeps, @@ -14,8 +14,12 @@ import { createEventType, createHost, createSchedule, + decryptRouting, + eraseAttendee, getBooking, listBookingSlots, + redactExpiredBookings, + reencryptSchedulingData, rescheduleBooking, runDueCalendarSyncs, runDueCalendarWrites, @@ -505,3 +509,80 @@ describe("slots for moving a booking", () => { expect(await listBookingSlots(env, { bookingId: booking.id, ...window })).toEqual([]); }); }); + +describe("what a booking was routed with", () => { + async function routed(attributes?: Record) { + const env = await environment(); + await hostWithHours(env, "Dermatologist", { attributes: { specialty: "dermatology" } }); + const pool = await createEventType(env, { + title: "Filtered", + kind: "pool", + duration_minutes: 30, + hosts: [], + host_filter: { specialty: "dermatology" }, + } as never); + const { booking } = await createBooking( + env, + { eventType: pool.id, startMs: at("09:00"), attendee, attributes }, + plain, + actor, + ); + return { env, booking }; + } + + const stored = async (id: string) => { + const [row] = await db + .select({ value: schema.schedulingBooking.encryptedAttributes }) + .from(schema.schedulingBooking) + .where(eq(schema.schedulingBooking.id, id)); + return row?.value ?? null; + }; + + test("is kept encrypted", async () => { + const { booking } = await routed({ specialty: "dermatology" }); + const value = await stored(booking.id); + expect(value).not.toContain("dermatology"); + expect(decryptRouting(value, plain)).toEqual({ specialty: "dermatology" }); + }); + + test("says nothing narrowed it, which isn't the same as not knowing", async () => { + const { booking } = await routed(); + expect(await stored(booking.id)).not.toBeNull(); + expect(decryptRouting(await stored(booking.id), plain)).toEqual({}); + expect(decryptRouting(null, plain)).toBeNull(); + }); + + test("never appears on the booking's wire object", async () => { + const { env, booking } = await routed({ specialty: "dermatology" }); + expect(JSON.stringify(await getBooking(env, booking.id, plain))).not.toContain("dermatology"); + }); + + test("goes when the attendee is erased", async () => { + const { env, booking } = await routed({ specialty: "dermatology" }); + expect(await stored(booking.id)).not.toBeNull(); + await eraseAttendee(env, { uid: "p" }); + expect(await stored(booking.id)).toBeNull(); + }); + + test("goes when the booking is redacted", async () => { + const { env, booking } = await routed({ specialty: "dermatology" }); + await redactExpiredBookings({ + now: new Date(at("09:00") + 200 * 86_400_000), + scope: scope(env), + }); + expect(await stored(booking.id)).toBeNull(); + }); + + test("is re-encrypted when the key rotates", async () => { + const { env, booking } = await routed({ specialty: "dermatology" }); + const next = secretsKeyRing([ + createHash("sha256").update("next data key").digest(), + ...plain.dataKeys.keys.map((key) => key.key), + ]); + const result = await reencryptSchedulingData({ keys: next, scope: scope(env) }); + expect(result.unreadableCount).toBe(0); + const value = (await stored(booking.id)) as string; + expect(isEncryptedWithPrimary(value, next)).toBe(true); + expect(decryptRouting(value, { dataKeys: next })).toEqual({ specialty: "dermatology" }); + }); +}); diff --git a/packages/scheduling/test/reencrypt.test.ts b/packages/scheduling/test/reencrypt.test.ts index e27f15304..1c0a96bee 100644 --- a/packages/scheduling/test/reencrypt.test.ts +++ b/packages/scheduling/test/reencrypt.test.ts @@ -143,9 +143,10 @@ describe("reencryptSchedulingData", () => { const currentRow = await attendeeRow(current.id); const oldSessionRow = await sessionRow(oldSession.id); + // Two each of attendees, bookings and sessions, one of each on the old key. const planned = { - checked: 4, - reencrypted: 2, + checked: 6, + reencrypted: 3, unreadableCount: 0, unreadable: [], conflicts: 0, @@ -212,9 +213,10 @@ describe("reencryptSchedulingData", () => { const erased = await book(fixture, 11, before, "patient_erased"); await eraseAttendee(env, { uid: "patient_erased" }); + // One attendee and its booking: erasing took what the other booking was routed with too. expect(await reencryptSchedulingData({ keys: during, scope })).toMatchObject({ - checked: 1, - reencrypted: 1, + checked: 2, + reencrypted: 2, }); const row = await attendeeRow(booking.id); expect(row.encryptedAnswers).toBeNull(); @@ -232,7 +234,8 @@ describe("reencryptSchedulingData", () => { const lostSession = await bookerSession(fixture, unknown); const result = await reencryptSchedulingData({ keys: during, scope }); - expect(result).toMatchObject({ checked: 3, reencrypted: 1, unreadableCount: 3, conflicts: 0 }); + // The fine attendee and booking move. The lost attendee's two columns, booking and session don't. + expect(result).toMatchObject({ checked: 5, reencrypted: 2, unreadableCount: 4, conflicts: 0 }); expect(result.unreadable).toEqual( expect.arrayContaining([ { @@ -268,7 +271,8 @@ describe("reencryptSchedulingData", () => { .where(eq(schedulingAttendee.id, row.id)); const result = await reencryptSchedulingData({ keys: during, scope }); - expect(result).toMatchObject({ reencrypted: 0, unreadableCount: 1 }); + // Only the booking, whose one column can be read. + expect(result).toMatchObject({ reencrypted: 1, unreadableCount: 1 }); expect((await attendeeRow(booking.id)).encryptedContact).toBe(row.encryptedContact); }); @@ -403,7 +407,7 @@ describe("reencryptSchedulingData", () => { for (const hour of [1, 3, 5, 7, 9]) await book(fixture, hour, before); await book(fixture, 11, secretsKeyRing([OTHER_KEY])); const result = await reencryptSchedulingData({ keys: during, scope, batchSize: 2 }); - expect(result).toMatchObject({ checked: 6, reencrypted: 5, unreadableCount: 2 }); + expect(result).toMatchObject({ checked: 12, reencrypted: 10, unreadableCount: 3 }); const reported = JSON.stringify(result); for (const secret of [ From 152e25ee320b6f010400ec19661956ef5fa0ab48 Mon Sep 17 00:00:00 2001 From: Bailey Pumfleet Date: Wed, 4 Nov 2026 12:07:53 -0600 Subject: [PATCH 03/30] Scheduling: out of office Hosts can be marked as away, for part of a day or whole dates, one at a time, as a list or by attributes. They aren't offered during it, joining a running group session included, and a pool passes over them. Existing bookings are never touched: they're listed as conflicts, and the host's told how many. Bookers see when the host's back and any message they left. Reasons can say someone's on medical leave, so they stay out of webhooks, logs, calendars and anything a booker sees, and notes are encrypted. An entry puts a private event on the host's calendar, through the same ledger as bookings, which is why deleting one is soft: the row that removes the event belongs to it. put by your own id lets an HR tool sync without keeping ours, and webhooks say when time away is created, changed, starts and ends. Hosts get a Time off tab, and the dashboard an Out of office page. --- .changeset/scheduling-out-of-office.md | 5 + AGENTS.md | 6 +- apps/api/openapi.json | 14126 ++++--- apps/api/src/routes/scheduling-client.ts | 113 +- apps/api/src/routes/scheduling.ts | 248 + apps/api/src/webhook-events.ts | 2 + apps/api/test/app.test.ts | 4 + apps/api/test/contract-types.ts | 31 +- apps/api/test/scheduling.test.ts | 145 + apps/api/test/sdk-contract.test.ts | 88 + .../src/app/h/[sessionId]/host-portal.tsx | 5 + .../src/app/h/[sessionId]/time-off.tsx | 340 + .../scheduling/src/components/slot-picker.tsx | 17 +- .../site/content/docs/(platform)/webhooks.mdx | 5 + .../site/content/docs/api-reference/meta.json | 1 + apps/site/content/docs/scheduling/meta.json | 1 + .../content/docs/scheduling/out-of-office.mdx | 126 + apps/site/src/lib/sdk-samples.ts | 28 + .../[envSlug]/scheduling/actions.ts | 54 + .../scheduling/out-of-office/page.tsx | 148 + .../scheduling/scheduling-actions.tsx | 170 +- apps/web/src/lib/navigation.ts | 1 + apps/worker/scripts/scheduling-load.ts | 17 + apps/worker/src/jobs.ts | 10 + apps/worker/src/retention.ts | 4 + packages/dashboard-routes/src/index.ts | 1 + .../db/migrations/0128_fantastic_catseye.sql | 42 + .../db/migrations/meta/0128_snapshot.json | 31441 ++++++++++++++++ packages/db/migrations/meta/_journal.json | 7 + packages/db/src/id.ts | 2 + packages/db/src/schema/scheduling.ts | 86 +- packages/email/src/test-event-schemas.ts | 3 + packages/email/src/test-events.ts | 8 + packages/retention/src/index.ts | 21 +- packages/scheduling/AGENTS.md | 24 +- packages/scheduling/scripts/seed.ts | 20 + packages/scheduling/src/availability.ts | 25 + packages/scheduling/src/bookings.ts | 24 +- packages/scheduling/src/calendar/writes.ts | 25 +- packages/scheduling/src/engine/slots.ts | 9 +- packages/scheduling/src/errors.ts | 2 + packages/scheduling/src/index.ts | 1 + packages/scheduling/src/notifications.ts | 53 +- packages/scheduling/src/out-of-office.ts | 987 + packages/scheduling/src/reencrypt.ts | 63 +- packages/scheduling/src/retention.ts | 56 + packages/scheduling/src/schemas.ts | 300 + packages/scheduling/src/settings.ts | 8 + .../scheduling/test/out-of-office.test.ts | 1149 + packages/sdk/src/core/routes.generated.ts | 4 + packages/sdk/src/index.ts | 1 + packages/sdk/src/resources/scheduling.ts | 113 + packages/sdk/src/types/scheduling.ts | 125 +- packages/sdk/src/types/webhook.ts | 4 +- packages/sdk/src/webhook-event-types.ts | 5 + tooling/sdkgen/src/methods.ts | 8 + 56 files changed, 44494 insertions(+), 5818 deletions(-) create mode 100644 .changeset/scheduling-out-of-office.md create mode 100644 apps/scheduling/src/app/h/[sessionId]/time-off.tsx create mode 100644 apps/site/content/docs/scheduling/out-of-office.mdx create mode 100644 apps/web/src/app/[orgSlug]/[projectSlug]/[envSlug]/scheduling/out-of-office/page.tsx create mode 100644 packages/db/migrations/0128_fantastic_catseye.sql create mode 100644 packages/db/migrations/meta/0128_snapshot.json create mode 100644 packages/scheduling/src/out-of-office.ts create mode 100644 packages/scheduling/test/out-of-office.test.ts diff --git a/.changeset/scheduling-out-of-office.md b/.changeset/scheduling-out-of-office.md new file mode 100644 index 000000000..404efff02 --- /dev/null +++ b/.changeset/scheduling-out-of-office.md @@ -0,0 +1,5 @@ +--- +"coss": minor +--- + +Add `coss.scheduling.outOfOffice`: mark hosts as away, for part of a day or whole dates, one at a time or many together. They stop being offered, existing bookings stay and are listed as conflicts, and `scheduling.out_of_office.*` webhooks say when it's created, changed, starts and ends. diff --git a/AGENTS.md b/AGENTS.md index b340da70d..a0640e17a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -64,7 +64,7 @@ text it shows is a gist that must match `CLA.md`: change both together, as a new | `packages/sign` | `@coss/sign` | Sign (e-signatures): uploaded PDFs (`pdf.ts`: pdf-lib + pdf.js, page sizes and text anchors), signature requests with signers and fields placed by position or anchor, the hash-chained audit trail (`events.ts`) with its webhooks and log lines (`record.ts`), signing sessions (`sessions.ts`), the signer's actions (`signing.ts`: view, consent, sign, decline), email delivery (`notifications.ts`: invitations in signing order, reminders, expiry, signed copies through an injected `SignMailer`), completion (`complete.ts`: the completed document with its certificate pages, `completed-pdf.ts`, sealed as PAdES B-LT by `seal/`: KMS, a CA's CSC API or a local key, RFC 3161 timestamps, OCSP/CRLs in a DSS), templates (`templates.ts`: roles, merge fields, requests from a template) and builder sessions (`builder.ts`), settings (`settings.ts`: embedding origins, branding, consent text), the document store (`store.ts`: `DocumentStore`, `FakeDocumentStore`); `./schemas` (zod only, also `SIGN_WEBHOOK_EVENT_TYPES`), `./env` (zod only), `./runtime` (`sealerFromEnv`), `./testing` (`buildTestPdf`, `TEST_SIGNATURE_PNG`). See `packages/sign/AGENTS.md`. | | `packages/verify` | `@coss/verify` | Verify (one-time codes): `createVerifyService` (`start`: the fraud guard — `@coss/risk`'s `checkVerificationRisk` — before anything is paid for, then a code by SMS from the environment's own number or coss.com's shared numbers, or by email through an injected sender; `check` against an HMAC, never the code; `cancel`), settings (`settings.ts`), reads, shared-number metering (`recordDueVerifySmsUsage`), purges; `./schemas` (zod only, also `VERIFY_WEBHOOK_EVENT_TYPES`), `./testing`. Never imports `@coss/email` (email imports its schemas). See `packages/verify/AGENTS.md`. | | `packages/forms` | `@coss/forms` | Forms (hosted form endpoints): forms and their settings (`forms.ts`: field definitions, origins, spam, submitter verification, notifications, contacts mapping, uploads, hosted pages), taking a submission (`submit.ts`, `parse.ts`: origin, fields, honeypot, a Risk assessment, the content check, files, then `record.ts`: usage, `form.submission.*` webhooks, log lines, deliveries), the worker's deliveries (`deliveries.ts`: notification emails, contacts, verification links through an injected `FormMailer`/`FormContactSink`), release and confirmation (`release.ts`), reads (`submissions.ts`), hosted pages and their CSP (`hosted.ts`, `pages.ts`), the file store (`store.ts`, S3 under `./runtime`, cleanup), purges; `./schemas` (zod only, also `FORM_WEBHOOK_EVENT_TYPES`), `./env` (zod only), `./runtime`, `./testing`. See `packages/forms/AGENTS.md`. | -| `packages/scheduling` | `@coss/scheduling` | Scheduling: hosts, schedules, event types (`one_on_one`, `pool`, `collective`, `group`), availability, the booking path (`claims.ts`: the only writer of `scheduling_claim`, whose exclusion constraint prevents double-booking), holds, approval, recurring series, sessions, the notification outbox with injected `SchedulingNotifier`, purges; `./engine` (pure: time zones, `isBookable`, ranking, recurrence), `calendar/` (`fetch`-based clients for Google, Microsoft and CalDAV, sync, write-back); `./schemas` (zod only, also `SCHEDULING_WEBHOOK_EVENT_TYPES`), `./env` (zod only), `./runtime`, `./testing`. See `packages/scheduling/AGENTS.md`. | +| `packages/scheduling` | `@coss/scheduling` | Scheduling: hosts, schedules, out of office (`out-of-office.ts`), event types (`one_on_one`, `pool`, `collective`, `group`), availability, the booking path (`claims.ts`: the only writer of `scheduling_claim`, whose exclusion constraint prevents double-booking), holds, approval, recurring series, sessions, the notification outbox with injected `SchedulingNotifier`, purges; `./engine` (pure: time zones, `isBookable`, ranking, recurrence), `calendar/` (`fetch`-based clients for Google, Microsoft and CalDAV, sync, write-back); `./schemas` (zod only, also `SCHEDULING_WEBHOOK_EVENT_TYPES`), `./env` (zod only), `./runtime`, `./testing`. See `packages/scheduling/AGENTS.md`. | | `packages/support` | `@coss/support` | coss.com's support desk: tickets from email (`intake.ts`, reading `received_email` of `SUPPORT_ENVIRONMENT_ID`) and the dashboard, sender matching and trust (`matching.ts`, `sender.ts`: a match never grants access by itself), the SLA clock (`sla.ts`, targets in `@coss/billing/catalog`'s `SUPPORT_TIERS`), delivery through an injected `SupportMailer` (`delivery.ts`), the worker's housekeeping and rep alerts (`sweep.ts`), attachments (`store.ts`); `./admin` (reps' queue and actions, platform-level), `./format` and `./schemas` (client-safe), `./env` (zod only), `./testing`. See `packages/support/AGENTS.md`. | | `packages/push` | `@coss/push` | Push notifications to the iOS app: devices (one per app session), the outbox products enqueue into (`enqueuePush`, in the deciding transaction), recipients (role + `orgAccess`) and content resolved at send time, the worker's send loop; `./apns` (APNs over `node:http2`, ES256 provider tokens), `./schemas` (zod only: categories, kinds, registration), `./testing` (`FakePushSender`, `createTestPushDevice`). See `packages/push/AGENTS.md`. | | `packages/notifications` | `@coss/notifications` | coss.com's notification emails to organizations: the outbox products enqueue into (`enqueueNotification`, in the deciding transaction; once per dedupe key, optionally delayed), kinds rendered at send time (stale news is skipped), the worker's `notifications` loop, owner/admin recipients, retention; `./testing` (`recordingNotifier`). See `packages/notifications/AGENTS.md`. | @@ -527,7 +527,7 @@ notification emails) and, if there is useful advice, to `ADVICE` (`packages/repu across orgs like `authorizeLiveSender`), `receiveEmail`/`routeRecipients` (receiving; from the envelope recipients), `recordSmsEvent`/`ingestSmsEvents` (from the `sms_id` of the callback URL), `receiveSms` (from the receiving number), `handleStatusCallback`/`handleInboundCallback` (from the callback's subaccount), `authorizeLiveSmsSender`, `ingestDmarcReports` (from the report address's token), `reencryptWebhookSecrets`, `reencryptSchedulingData` (operator scripts), `authenticateHookPortalSession` (from the session), `ingestSupportEmails` (one environment, across senders) and the rest of `@coss/support`'s worker functions, `submitForm`/`getHostedForm` (from the form id of `/f/:id`), `confirmFormSubmission`/`findConfirmation` (from the verification token), and the worker scans `runDueWebhookDeliveries`, `runDueLogDrainDeliveries`, `runDueHookDeliveries`, `parkHeldHookDeliveries`, `runDueHookRecoveries`, the Hooks purges, `recheckDueDomains`, `recheckDueTrackingDomains`, `recheckDueReceivingDomains`, `reconcileDedicatedIpPools`, `sweepStaleClaims`, `sweepUnclaimedEmails`, `runDueReputationEvaluations`, `runDueSubaccountEvaluations`, `runDueOrganizationDeletions`, `runDueOrganizationLogos`, `runDueSubaccountDeletions`, `runDueDmarcNotifications`, `runDueMigrations`, `EmailService.dispatchDue`, `unclaimedEmailBacklog`, `unclaimedSmsBacklog` (the `dispatch-backlog` loop: counts only), `SmsService.dispatchDue`, `sweepStaleSmsClaims`, `sweepUnclaimedSms`, `advanceDueSmsRegistrations`, `chargeDueSmsFees`, `chargeDueInboxFees`, `recordDueVerifySmsUsage` (bills each organization for its codes from coss.com's shared numbers, reading coss.com's messages), - `authenticateSchedulingSession` (from the token), `handleCalendarPush`, `completeCalendarAuthorization` (from the push's channel and the consent's state), `handleZoomDeauthorization` (from Zoom's signed event), `refreshIdleZoomConnections`, `runDueCalendarSyncs`, `runDueCalendarWrites`, `renewDueCalendarChannels`, `checkHostEditedEvents`, `runDueSchedulingNotifications`, `expireDueBookings`, + `authenticateSchedulingSession` (from the token), `handleCalendarPush`, `completeCalendarAuthorization` (from the push's channel and the consent's state), `handleZoomDeauthorization` (from Zoom's signed event), `refreshIdleZoomConnections`, `runDueCalendarSyncs`, `runDueCalendarWrites`, `renewDueCalendarChannels`, `checkHostEditedEvents`, `runDueSchedulingNotifications`, `expireDueBookings`, `announceDueOutOfOffice`, `runDueFormDeliveries`, `runDueFormStoreCleanup` (and the dispatch jobs, from the job's `organizationId`); `@coss/sms/admin` is platform-level like `@coss/email/admin`. Server actions take only slugs + target ids and derive the org from `requireOrgPermission`; every Better Auth organization call passes `organizationId` @@ -695,6 +695,8 @@ notification emails) and, if there is useful advice, to `ADVICE` (`packages/repu addresses on verified domains; hosted pages refuse fields asking for credentials and are screened when published; `/f/*` is served only on `FORMS_PUBLIC_URL`'s host in production, never coss.com's. - **Scheduling** (`packages/scheduling/AGENTS.md`): only `claims.ts` writes claims, in the fixed lock order; + out of office stops new bookings and never touches an existing one, and its reason stays out of webhooks, logs, + calendars and anything a booker sees; slots are computed only in Bun, through `isBookable`; calendars contribute busy intervals and nothing else, and an unreadable one never reads as free; answers never leave `getBooking`; coss.com never auto-cancels a booking. - **Support** (`packages/support/AGENTS.md`): `From` proves nothing, so a match never grants access by diff --git a/apps/api/openapi.json b/apps/api/openapi.json index d97301662..62a65d26f 100644 --- a/apps/api/openapi.json +++ b/apps/api/openapi.json @@ -3843,6 +3843,97 @@ } ] }, + "SchedulingOutOfOfficeWebhookEvent": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "The event id." + }, + "object": { + "type": "string", + "enum": [ + "event" + ] + }, + "api_version": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "type": { + "type": "string", + "enum": [ + "scheduling.out_of_office.created", + "scheduling.out_of_office.updated", + "scheduling.out_of_office.deleted", + "scheduling.out_of_office.started", + "scheduling.out_of_office.ended" + ] + }, + "data": { + "type": "object", + "properties": { + "out_of_office_id": { + "type": "string" + }, + "host_id": { + "type": "string" + }, + "start": { + "type": "string" + }, + "end": { + "type": "string" + }, + "group": { + "type": [ + "string", + "null" + ] + }, + "occurred_at": { + "type": "string" + } + }, + "required": [ + "out_of_office_id", + "host_id", + "start", + "end", + "group", + "occurred_at" + ] + } + }, + "required": [ + "id", + "object", + "api_version", + "created_at", + "type", + "data" + ], + "examples": [ + { + "id": "evt_01kd2m9a0b1c2d3e4f5g6h7j8m", + "object": "event", + "type": "scheduling.out_of_office.created", + "api_version": "2026-10-10", + "created_at": "2027-01-01T10:00:00.000Z", + "data": { + "out_of_office_id": "ooo_01kd2m9a0b1c2d3e4f5g6h7j8m", + "host_id": "host_01kd2m9a0b1c2d3e4f5g6h7j8m", + "start": "2027-08-02T04:00:00.000Z", + "end": "2027-08-14T04:00:00.000Z", + "group": null, + "occurred_at": "2027-01-01T10:00:00.000Z" + } + } + ] + }, "Environment": { "type": "object", "properties": { @@ -9202,10 +9293,15 @@ "scheduling.booking.location_ready", "scheduling.calendar.connected", "scheduling.calendar.needs_reauth", - "scheduling.calendar.disconnected" + "scheduling.calendar.disconnected", + "scheduling.out_of_office.created", + "scheduling.out_of_office.updated", + "scheduling.out_of_office.deleted", + "scheduling.out_of_office.started", + "scheduling.out_of_office.ended" ] }, - "maxItems": 86, + "maxItems": 91, "description": "Event types delivered to this endpoint. An empty array means every event type, including ones added later. Defaults to every event type." }, "api_version": { @@ -9517,10 +9613,15 @@ "scheduling.booking.location_ready", "scheduling.calendar.connected", "scheduling.calendar.needs_reauth", - "scheduling.calendar.disconnected" + "scheduling.calendar.disconnected", + "scheduling.out_of_office.created", + "scheduling.out_of_office.updated", + "scheduling.out_of_office.deleted", + "scheduling.out_of_office.started", + "scheduling.out_of_office.ended" ] }, - "maxItems": 86, + "maxItems": 91, "description": "Event types delivered to this endpoint. An empty array means every event type, including ones added later." }, "api_version": { @@ -10081,10 +10182,15 @@ "scheduling.booking.location_ready", "scheduling.calendar.connected", "scheduling.calendar.needs_reauth", - "scheduling.calendar.disconnected" + "scheduling.calendar.disconnected", + "scheduling.out_of_office.created", + "scheduling.out_of_office.updated", + "scheduling.out_of_office.deleted", + "scheduling.out_of_office.started", + "scheduling.out_of_office.ended" ] }, - "maxItems": 86, + "maxItems": 91, "description": "Event types to receive. Defaults to every event type." }, "api_version": { @@ -10410,6 +10516,9 @@ }, { "$ref": "#/components/schemas/SchedulingCalendarWebhookEvent" + }, + { + "$ref": "#/components/schemas/SchedulingOutOfOfficeWebhookEvent" } ], "description": "The event, as an endpoint on the request's API version receives it. Its `webhook-id` header is `event.id`." @@ -10857,7 +10966,12 @@ "scheduling.booking.location_ready", "scheduling.calendar.connected", "scheduling.calendar.needs_reauth", - "scheduling.calendar.disconnected" + "scheduling.calendar.disconnected", + "scheduling.out_of_office.created", + "scheduling.out_of_office.updated", + "scheduling.out_of_office.deleted", + "scheduling.out_of_office.started", + "scheduling.out_of_office.ended" ], "description": "The event type. `domain.*`, `account.*`, `subaccount.*` and `billing.*` events only reach live environments, so they can't be tested in a sandbox one." }, @@ -17474,13 +17588,67 @@ } ] }, - "SchedulingSchedule": { + "SchedulingOutOfOfficeList": { "type": "object", "properties": { "object": { "type": "string", "enum": [ - "scheduling.schedule" + "list" + ] + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SchedulingOutOfOffice" + } + }, + "has_more": { + "type": "boolean" + } + }, + "required": [ + "object", + "data", + "has_more" + ], + "examples": [ + { + "object": "list", + "data": [ + { + "object": "scheduling.out_of_office", + "id": "ooo_01kd2m9a0b1c2d3e4f5g6h7j8m", + "host": "host_01kd2m9a0b1c2d3e4f5g6h7j8m", + "start": "2027-08-02T04:00:00.000Z", + "end": "2027-08-14T04:00:00.000Z", + "all_day": { + "start_date": "2027-08-02", + "end_date": "2027-08-13", + "time_zone": "America/New_York" + }, + "reason": "vacation", + "notes": null, + "public_message": "Back on the 16th.", + "show_on_calendar": true, + "external_id": null, + "group": null, + "source": "api", + "created_at": "2027-01-01T10:00:00.000Z", + "updated_at": "2027-01-01T10:00:00.000Z" + } + ], + "has_more": false + } + ] + }, + "SchedulingOutOfOffice": { + "type": "object", + "properties": { + "object": { + "type": "string", + "enum": [ + "scheduling.out_of_office" ] }, "id": { @@ -17489,72 +17657,75 @@ "host": { "type": "string" }, - "name": { + "start": { "type": "string" }, - "time_zone": { + "end": { "type": "string" }, - "is_default": { + "all_day": { + "type": [ + "object", + "null" + ], + "properties": { + "start_date": { + "type": "string" + }, + "end_date": { + "type": "string" + }, + "time_zone": { + "type": "string" + } + }, + "required": [ + "start_date", + "end_date", + "time_zone" + ], + "description": "How it was given, when it was as whole dates." + }, + "reason": { + "type": "string" + }, + "notes": { + "type": [ + "string", + "null" + ] + }, + "public_message": { + "type": [ + "string", + "null" + ] + }, + "show_on_calendar": { "type": "boolean" }, - "rules": { - "type": "array", - "items": { - "type": "object", - "properties": { - "days": { - "type": "array", - "items": { - "type": "number" - } - }, - "start": { - "type": "string" - }, - "end": { - "type": "string" - } - }, - "required": [ - "days", - "start", - "end" - ] - } + "external_id": { + "type": [ + "string", + "null" + ] }, - "overrides": { - "type": "array", - "items": { - "type": "object", - "properties": { - "date": { - "type": "string" - }, - "ranges": { - "type": "array", - "items": { - "type": "object", - "properties": { - "start": { - "type": "string" - }, - "end": { - "type": "string" - } - }, - "required": [ - "start", - "end" - ] - } - } - }, - "required": [ - "date", - "ranges" - ] - } + "group": { + "type": [ + "string", + "null" + ], + "description": "Shared by the entries one request made for several hosts." + }, + "source": { + "type": "string", + "enum": [ + "api", + "host", + "manager", + "dashboard", + "holiday" + ] }, "created_at": { "type": "string" @@ -17567,255 +17738,327 @@ "object", "id", "host", - "name", - "time_zone", - "is_default", - "rules", - "overrides", + "start", + "end", + "all_day", + "reason", + "notes", + "public_message", + "show_on_calendar", + "external_id", + "group", + "source", "created_at", "updated_at" ], "examples": [ { - "object": "scheduling.schedule", - "id": "sched_01kd2m9a0b1c2d3e4f5g6h7j8m", + "object": "scheduling.out_of_office", + "id": "ooo_01kd2m9a0b1c2d3e4f5g6h7j8m", "host": "host_01kd2m9a0b1c2d3e4f5g6h7j8m", - "name": "Clinic hours", - "time_zone": "America/New_York", - "is_default": true, - "rules": [ - { - "days": [ - 1, - 2, - 3, - 4, - 5 - ], - "start": "09:00", - "end": "17:00" - } - ], - "overrides": [ - { - "date": "2027-12-24", - "ranges": [] - } - ], + "start": "2027-08-02T04:00:00.000Z", + "end": "2027-08-14T04:00:00.000Z", + "all_day": { + "start_date": "2027-08-02", + "end_date": "2027-08-13", + "time_zone": "America/New_York" + }, + "reason": "vacation", + "notes": null, + "public_message": "Back on the 16th.", + "show_on_calendar": true, + "external_id": null, + "group": null, + "source": "api", "created_at": "2027-01-01T10:00:00.000Z", "updated_at": "2027-01-01T10:00:00.000Z" } ] }, - "UpsertScheduleRequest": { + "CreateSchedulingOutOfOfficeRequest": { "type": "object", "properties": { - "name": { + "host": { "type": "string", - "minLength": 1, - "maxLength": 100 + "description": "One host, by id or uid." + }, + "hosts": { + "type": "array", + "items": { + "type": "string" + }, + "maxItems": 500, + "description": "Several hosts, by id or uid. Each gets an entry of their own." + }, + "host_filter": { + "type": "object", + "additionalProperties": { + "anyOf": [ + { + "type": "string", + "maxLength": 200 + }, + { + "type": "array", + "items": { + "type": "string", + "maxLength": 200 + }, + "maxItems": 50 + } + ] + }, + "description": "Every active host matching these attributes right now. A host added later isn't covered." + }, + "start": { + "type": "string", + "description": "An ISO 8601 instant with an offset.", + "examples": [ + "2027-01-04T15:00:00.000Z" + ] + }, + "end": { + "type": "string", + "description": "An ISO 8601 instant with an offset.", + "examples": [ + "2027-01-04T15:00:00.000Z" + ] + }, + "start_date": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "description": "The first whole day away. Use instead of `start` and `end`.", + "examples": [ + "2027-08-02" + ] + }, + "end_date": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "description": "The last whole day away, which is included.", + "examples": [ + "2027-08-13" + ] }, "time_zone": { "type": "string", "minLength": 1, "maxLength": 64, - "description": "Default: the host's.", + "description": "What the dates mean in. Default: the host's zone when this is made.", "examples": [ "America/New_York" ] }, - "is_default": { - "type": "boolean" + "reason": { + "type": "string", + "pattern": "^[a-z][a-z0-9_]{0,63}$", + "description": "One of `unspecified`, `vacation`, `travel`, `sick`, `public_holiday`, `parental_leave`, `training` and `other`, or a key from the settings' `out_of_office_reasons`. Only people who manage this host see it: never bookers, webhooks or calendars.", + "examples": [ + "vacation" + ] }, - "rules": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SchedulingWeeklyRule" - }, - "maxItems": 50 + "notes": { + "type": "string", + "maxLength": 2000, + "description": "For people who manage this host. Encrypted, and never shown to a booker." }, - "overrides": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SchedulingScheduleOverride" - }, - "maxItems": 366, - "description": "Replaces the schedule's overrides when given." + "public_message": { + "type": "string", + "maxLength": 300, + "description": "Shown to bookers while this host is away. Can't contain a link.", + "examples": [ + "Back on the 16th. Priya is seeing my patients until then." + ] + }, + "show_on_calendar": { + "type": "boolean", + "description": "Put a private \"Out of office\" event on the host's calendar. Default: true." + }, + "external_id": { + "type": "string", + "minLength": 1, + "maxLength": 255, + "description": "Your own id for this entry, unique in the environment. Needs one host." } }, - "required": [ - "rules" - ], "additionalProperties": false, "examples": [ { - "name": "Clinic hours", - "rules": [ - { - "days": [ - 1, - 2, - 3, - 4, - 5 - ], - "start": "09:00", - "end": "17:00" - } - ], - "overrides": [ - { - "date": "2027-12-24", - "ranges": [] - } - ] + "host": "doctor_482", + "start_date": "2027-08-02", + "end_date": "2027-08-13", + "reason": "vacation", + "public_message": "Back on the 16th." } ] }, - "SchedulingWeeklyRule": { + "UpdateSchedulingOutOfOfficeRequest": { "type": "object", "properties": { - "days": { - "type": "array", - "items": { - "type": "integer", - "minimum": 0, - "maximum": 6 - }, - "minItems": 1, - "maxItems": 7, - "description": "Weekdays, with Sunday as 0." - }, "start": { "type": "string", - "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$", - "description": "A local time, `HH:MM`. `24:00` is the end of the day." + "description": "An ISO 8601 instant with an offset.", + "examples": [ + "2027-01-04T15:00:00.000Z" + ] }, "end": { "type": "string", - "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$", - "description": "A local time, `HH:MM`. `24:00` is the end of the day." - } - }, - "required": [ - "days", - "start", - "end" - ], - "additionalProperties": false - }, - "SchedulingScheduleOverride": { - "type": "object", - "properties": { - "date": { + "description": "An ISO 8601 instant with an offset.", + "examples": [ + "2027-01-04T15:00:00.000Z" + ] + }, + "start_date": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "description": "A local date in the schedule's time zone.", + "description": "The first whole day away. Use instead of `start` and `end`.", "examples": [ - "2027-12-24" + "2027-08-02" ] }, - "ranges": { - "type": "array", - "items": { - "type": "object", - "properties": { - "start": { - "type": "string", - "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$", - "description": "A local time, `HH:MM`. `24:00` is the end of the day." - }, - "end": { - "type": "string", - "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$", - "description": "A local time, `HH:MM`. `24:00` is the end of the day." - } - }, - "required": [ - "start", - "end" - ], - "additionalProperties": false - }, - "maxItems": 10, - "description": "Replaces the weekly rules that day. Empty means unavailable all day." - } - }, - "required": [ - "date", - "ranges" - ], - "additionalProperties": false - }, - "SchedulingScheduleList": { - "type": "object", - "properties": { - "object": { + "end_date": { "type": "string", - "enum": [ - "list" + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "description": "The last whole day away, which is included.", + "examples": [ + "2027-08-13" ] }, - "data": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SchedulingSchedule" - } + "time_zone": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "What the dates mean in. Default: the host's zone when this is made.", + "examples": [ + "America/New_York" + ] }, - "has_more": { + "reason": { + "type": "string", + "pattern": "^[a-z][a-z0-9_]{0,63}$", + "description": "One of `unspecified`, `vacation`, `travel`, `sick`, `public_holiday`, `parental_leave`, `training` and `other`, or a key from the settings' `out_of_office_reasons`. Only people who manage this host see it: never bookers, webhooks or calendars.", + "examples": [ + "vacation" + ] + }, + "notes": { + "type": [ + "string", + "null" + ], + "maxLength": 2000 + }, + "public_message": { + "type": [ + "string", + "null" + ], + "maxLength": 300 + }, + "show_on_calendar": { "type": "boolean" } }, - "required": [ - "object", - "data", - "has_more" - ], + "additionalProperties": false, "examples": [ { - "object": "list", - "data": [ - { - "object": "scheduling.schedule", - "id": "sched_01kd2m9a0b1c2d3e4f5g6h7j8m", - "host": "host_01kd2m9a0b1c2d3e4f5g6h7j8m", - "name": "Clinic hours", - "time_zone": "America/New_York", - "is_default": true, - "rules": [ - { - "days": [ - 1, - 2, - 3, - 4, - 5 - ], - "start": "09:00", - "end": "17:00" - } - ], - "overrides": [ - { - "date": "2027-12-24", - "ranges": [] - } - ], - "created_at": "2027-01-01T10:00:00.000Z", - "updated_at": "2027-01-01T10:00:00.000Z" - } - ], - "has_more": false + "end_date": "2027-08-20" } ] }, - "DeletedSchedulingSchedule": { + "PutSchedulingOutOfOfficeRequest": { + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "The host, by id or uid." + }, + "start": { + "type": "string", + "description": "An ISO 8601 instant with an offset.", + "examples": [ + "2027-01-04T15:00:00.000Z" + ] + }, + "end": { + "type": "string", + "description": "An ISO 8601 instant with an offset.", + "examples": [ + "2027-01-04T15:00:00.000Z" + ] + }, + "start_date": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "description": "The first whole day away. Use instead of `start` and `end`.", + "examples": [ + "2027-08-02" + ] + }, + "end_date": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "description": "The last whole day away, which is included.", + "examples": [ + "2027-08-13" + ] + }, + "time_zone": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "What the dates mean in. Default: the host's zone when this is made.", + "examples": [ + "America/New_York" + ] + }, + "reason": { + "type": "string", + "pattern": "^[a-z][a-z0-9_]{0,63}$", + "description": "One of `unspecified`, `vacation`, `travel`, `sick`, `public_holiday`, `parental_leave`, `training` and `other`, or a key from the settings' `out_of_office_reasons`. Only people who manage this host see it: never bookers, webhooks or calendars.", + "examples": [ + "vacation" + ] + }, + "notes": { + "type": "string", + "maxLength": 2000, + "description": "For people who manage this host. Encrypted, and never shown to a booker." + }, + "public_message": { + "type": "string", + "maxLength": 300, + "description": "Shown to bookers while this host is away. Can't contain a link.", + "examples": [ + "Back on the 16th. Priya is seeing my patients until then." + ] + }, + "show_on_calendar": { + "type": "boolean", + "description": "Put a private \"Out of office\" event on the host's calendar. Default: true." + } + }, + "required": [ + "host" + ], + "additionalProperties": false, + "examples": [ + { + "host": "doctor_482", + "start_date": "2027-08-02", + "end_date": "2027-08-13", + "reason": "vacation" + } + ] + }, + "DeletedSchedulingOutOfOffice": { "type": "object", "properties": { "object": { "type": "string", "enum": [ - "scheduling.schedule" + "scheduling.out_of_office" ] }, "id": { @@ -17835,176 +18078,210 @@ ], "examples": [ { - "object": "scheduling.schedule", - "id": "sched_01kd2m9a0b1c2d3e4f5g6h7j8m", + "object": "scheduling.out_of_office", + "id": "ooo_01kd2m9a0b1c2d3e4f5g6h7j8m", "deleted": true } ] }, - "SchedulingEventType": { + "SchedulingOutOfOfficeConflictList": { "type": "object", "properties": { "object": { "type": "string", "enum": [ - "scheduling.event_type" + "list" ] }, - "id": { - "type": "string" + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SchedulingOutOfOfficeConflict" + } }, - "uid": { - "type": [ - "string", - "null" + "has_more": { + "type": "boolean" + } + }, + "required": [ + "object", + "data", + "has_more" + ], + "examples": [ + { + "object": "list", + "data": [ + { + "object": "scheduling.out_of_office_conflict", + "booking": "book_01kd2m9a0b1c2d3e4f5g6h7j8m", + "event_type": "evtype_01kd2m9a0b1c2d3e4f5g6h7j8m", + "title": "Consultation", + "status": "confirmed", + "start": "2027-08-03T15:00:00.000Z", + "end": "2027-08-03T15:30:00.000Z", + "series": null, + "group_session": null + } + ], + "has_more": false + } + ] + }, + "SchedulingOutOfOfficeConflict": { + "type": "object", + "properties": { + "object": { + "type": "string", + "enum": [ + "scheduling.out_of_office_conflict" ] }, - "title": { + "booking": { "type": "string" }, - "kind": { - "type": "string", - "enum": [ - "one_on_one", - "pool", - "collective", - "group" - ] + "event_type": { + "type": "string" + }, + "title": { + "type": "string" }, "status": { "type": "string", "enum": [ - "active", - "archived" + "held", + "pending_approval", + "confirmed", + "cancelled", + "declined" ] }, - "duration_minutes": { - "type": "number" - }, - "duration_options": { - "type": "array", - "items": { - "type": "number" - } + "start": { + "type": "string" }, - "step_minutes": { - "type": "number" + "end": { + "type": "string" }, - "grid_time_zone": { + "series": { "type": [ "string", "null" ] }, - "buffer_before_minutes": { - "type": "number" - }, - "buffer_after_minutes": { - "type": "number" - }, - "min_notice_minutes": { - "type": "number" - }, - "booking_window": { - "$ref": "#/components/schemas/SchedulingBookingWindow" - }, - "limits": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SchedulingLimit" - } - }, - "capacity": { + "group_session": { "type": [ - "number", + "string", "null" ] + } + }, + "required": [ + "object", + "booking", + "event_type", + "title", + "status", + "start", + "end", + "series", + "group_session" + ], + "examples": [ + { + "object": "scheduling.out_of_office_conflict", + "booking": "book_01kd2m9a0b1c2d3e4f5g6h7j8m", + "event_type": "evtype_01kd2m9a0b1c2d3e4f5g6h7j8m", + "title": "Consultation", + "status": "confirmed", + "start": "2027-08-03T15:00:00.000Z", + "end": "2027-08-03T15:30:00.000Z", + "series": null, + "group_session": null + } + ] + }, + "SchedulingSchedule": { + "type": "object", + "properties": { + "object": { + "type": "string", + "enum": [ + "scheduling.schedule" + ] }, - "requires_approval": { - "type": "boolean" - }, - "approval_ttl_minutes": { - "type": "number" + "id": { + "type": "string" }, - "hold_ttl_seconds": { - "type": "number" + "host": { + "type": "string" }, - "cancel_notice_minutes": { - "type": "number" + "name": { + "type": "string" }, - "reschedule_notice_minutes": { - "type": "number" + "time_zone": { + "type": "string" }, - "questions": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SchedulingQuestion" - } + "is_default": { + "type": "boolean" }, - "locations": { + "rules": { "type": "array", "items": { - "$ref": "#/components/schemas/SchedulingLocation" - } - }, - "host_filter": { - "type": [ - "object", - "null" - ], - "additionalProperties": { - "anyOf": [ - { - "type": "string" - }, - { + "type": "object", + "properties": { + "days": { "type": "array", "items": { - "type": "string" + "type": "number" } + }, + "start": { + "type": "string" + }, + "end": { + "type": "string" } + }, + "required": [ + "days", + "start", + "end" ] } }, - "hosts": { + "overrides": { "type": "array", "items": { "type": "object", "properties": { - "host": { + "date": { "type": "string" }, - "role": { - "type": "string", - "enum": [ - "required", - "member" - ] - }, - "weight": { - "type": "number" - }, - "schedule": { - "type": [ - "string", - "null" - ] + "ranges": { + "type": "array", + "items": { + "type": "object", + "properties": { + "start": { + "type": "string" + }, + "end": { + "type": "string" + } + }, + "required": [ + "start", + "end" + ] + } } }, "required": [ - "host", - "role", - "weight", - "schedule" + "date", + "ranges" ] } }, - "metadata": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, "created_at": { "type": "string" }, @@ -18015,142 +18292,591 @@ "required": [ "object", "id", - "uid", - "title", - "kind", - "status", - "duration_minutes", - "duration_options", - "step_minutes", - "grid_time_zone", - "buffer_before_minutes", - "buffer_after_minutes", - "min_notice_minutes", - "booking_window", - "limits", - "capacity", - "requires_approval", - "approval_ttl_minutes", - "hold_ttl_seconds", - "cancel_notice_minutes", - "reschedule_notice_minutes", - "questions", - "locations", - "host_filter", - "hosts", - "metadata", + "host", + "name", + "time_zone", + "is_default", + "rules", + "overrides", "created_at", "updated_at" ], "examples": [ { - "object": "scheduling.event_type", - "id": "evtype_01kd2m9a0b1c2d3e4f5g6h7j8m", - "uid": null, - "title": "Initial consultation", - "kind": "one_on_one", - "status": "active", - "duration_minutes": 30, - "duration_options": [], - "step_minutes": 30, - "grid_time_zone": null, - "buffer_before_minutes": 0, - "buffer_after_minutes": 10, - "min_notice_minutes": 120, - "booking_window": null, - "limits": [], - "capacity": null, - "requires_approval": false, - "approval_ttl_minutes": 1440, - "hold_ttl_seconds": 600, - "cancel_notice_minutes": 0, - "reschedule_notice_minutes": 0, - "questions": [], - "locations": [], - "host_filter": null, - "hosts": [ + "object": "scheduling.schedule", + "id": "sched_01kd2m9a0b1c2d3e4f5g6h7j8m", + "host": "host_01kd2m9a0b1c2d3e4f5g6h7j8m", + "name": "Clinic hours", + "time_zone": "America/New_York", + "is_default": true, + "rules": [ { - "host": "host_01kd2m9a0b1c2d3e4f5g6h7j8m", - "role": "member", - "weight": 100, - "schedule": null + "days": [ + 1, + 2, + 3, + 4, + 5 + ], + "start": "09:00", + "end": "17:00" + } + ], + "overrides": [ + { + "date": "2027-12-24", + "ranges": [] } ], - "metadata": {}, "created_at": "2027-01-01T10:00:00.000Z", "updated_at": "2027-01-01T10:00:00.000Z" } ] }, - "SchedulingBookingWindow": { - "oneOf": [ - { - "type": "object", - "properties": { - "kind": { - "type": "string", - "enum": [ - "rolling" - ] - }, - "days": { - "type": "integer", - "minimum": 1, - "maximum": 730 - } + "UpsertScheduleRequest": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "time_zone": { + "type": "string", + "minLength": 1, + "maxLength": 64, + "description": "Default: the host's.", + "examples": [ + "America/New_York" + ] + }, + "is_default": { + "type": "boolean" + }, + "rules": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SchedulingWeeklyRule" }, - "required": [ - "kind", - "days" - ], - "additionalProperties": false + "maxItems": 50 }, + "overrides": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SchedulingScheduleOverride" + }, + "maxItems": 366, + "description": "Replaces the schedule's overrides when given." + } + }, + "required": [ + "rules" + ], + "additionalProperties": false, + "examples": [ { - "type": "object", - "properties": { - "kind": { - "type": "string", - "enum": [ - "range" - ] - }, - "from": { - "type": "string", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "description": "A local date in the schedule's time zone.", - "examples": [ - "2027-12-24" - ] - }, - "to": { - "type": "string", - "pattern": "^\\d{4}-\\d{2}-\\d{2}$", - "description": "A local date in the schedule's time zone.", - "examples": [ - "2027-12-24" - ] + "name": "Clinic hours", + "rules": [ + { + "days": [ + 1, + 2, + 3, + 4, + 5 + ], + "start": "09:00", + "end": "17:00" } - }, - "required": [ - "kind", - "from", - "to" ], - "additionalProperties": false - }, - { - "type": "null" + "overrides": [ + { + "date": "2027-12-24", + "ranges": [] + } + ] } ] }, - "SchedulingLimit": { + "SchedulingWeeklyRule": { "type": "object", "properties": { - "period": { + "days": { + "type": "array", + "items": { + "type": "integer", + "minimum": 0, + "maximum": 6 + }, + "minItems": 1, + "maxItems": 7, + "description": "Weekdays, with Sunday as 0." + }, + "start": { "type": "string", - "enum": [ - "day", - "week" + "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$", + "description": "A local time, `HH:MM`. `24:00` is the end of the day." + }, + "end": { + "type": "string", + "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$", + "description": "A local time, `HH:MM`. `24:00` is the end of the day." + } + }, + "required": [ + "days", + "start", + "end" + ], + "additionalProperties": false + }, + "SchedulingScheduleOverride": { + "type": "object", + "properties": { + "date": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "description": "A local date in the schedule's time zone.", + "examples": [ + "2027-12-24" + ] + }, + "ranges": { + "type": "array", + "items": { + "type": "object", + "properties": { + "start": { + "type": "string", + "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$", + "description": "A local time, `HH:MM`. `24:00` is the end of the day." + }, + "end": { + "type": "string", + "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$|^24:00$", + "description": "A local time, `HH:MM`. `24:00` is the end of the day." + } + }, + "required": [ + "start", + "end" + ], + "additionalProperties": false + }, + "maxItems": 10, + "description": "Replaces the weekly rules that day. Empty means unavailable all day." + } + }, + "required": [ + "date", + "ranges" + ], + "additionalProperties": false + }, + "SchedulingScheduleList": { + "type": "object", + "properties": { + "object": { + "type": "string", + "enum": [ + "list" + ] + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SchedulingSchedule" + } + }, + "has_more": { + "type": "boolean" + } + }, + "required": [ + "object", + "data", + "has_more" + ], + "examples": [ + { + "object": "list", + "data": [ + { + "object": "scheduling.schedule", + "id": "sched_01kd2m9a0b1c2d3e4f5g6h7j8m", + "host": "host_01kd2m9a0b1c2d3e4f5g6h7j8m", + "name": "Clinic hours", + "time_zone": "America/New_York", + "is_default": true, + "rules": [ + { + "days": [ + 1, + 2, + 3, + 4, + 5 + ], + "start": "09:00", + "end": "17:00" + } + ], + "overrides": [ + { + "date": "2027-12-24", + "ranges": [] + } + ], + "created_at": "2027-01-01T10:00:00.000Z", + "updated_at": "2027-01-01T10:00:00.000Z" + } + ], + "has_more": false + } + ] + }, + "DeletedSchedulingSchedule": { + "type": "object", + "properties": { + "object": { + "type": "string", + "enum": [ + "scheduling.schedule" + ] + }, + "id": { + "type": "string" + }, + "deleted": { + "type": "boolean", + "enum": [ + true + ] + } + }, + "required": [ + "object", + "id", + "deleted" + ], + "examples": [ + { + "object": "scheduling.schedule", + "id": "sched_01kd2m9a0b1c2d3e4f5g6h7j8m", + "deleted": true + } + ] + }, + "SchedulingEventType": { + "type": "object", + "properties": { + "object": { + "type": "string", + "enum": [ + "scheduling.event_type" + ] + }, + "id": { + "type": "string" + }, + "uid": { + "type": [ + "string", + "null" + ] + }, + "title": { + "type": "string" + }, + "kind": { + "type": "string", + "enum": [ + "one_on_one", + "pool", + "collective", + "group" + ] + }, + "status": { + "type": "string", + "enum": [ + "active", + "archived" + ] + }, + "duration_minutes": { + "type": "number" + }, + "duration_options": { + "type": "array", + "items": { + "type": "number" + } + }, + "step_minutes": { + "type": "number" + }, + "grid_time_zone": { + "type": [ + "string", + "null" + ] + }, + "buffer_before_minutes": { + "type": "number" + }, + "buffer_after_minutes": { + "type": "number" + }, + "min_notice_minutes": { + "type": "number" + }, + "booking_window": { + "$ref": "#/components/schemas/SchedulingBookingWindow" + }, + "limits": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SchedulingLimit" + } + }, + "capacity": { + "type": [ + "number", + "null" + ] + }, + "requires_approval": { + "type": "boolean" + }, + "approval_ttl_minutes": { + "type": "number" + }, + "hold_ttl_seconds": { + "type": "number" + }, + "cancel_notice_minutes": { + "type": "number" + }, + "reschedule_notice_minutes": { + "type": "number" + }, + "questions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SchedulingQuestion" + } + }, + "locations": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SchedulingLocation" + } + }, + "host_filter": { + "type": [ + "object", + "null" + ], + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "array", + "items": { + "type": "string" + } + } + ] + } + }, + "hosts": { + "type": "array", + "items": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "role": { + "type": "string", + "enum": [ + "required", + "member" + ] + }, + "weight": { + "type": "number" + }, + "schedule": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "host", + "role", + "weight", + "schedule" + ] + } + }, + "metadata": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + }, + "required": [ + "object", + "id", + "uid", + "title", + "kind", + "status", + "duration_minutes", + "duration_options", + "step_minutes", + "grid_time_zone", + "buffer_before_minutes", + "buffer_after_minutes", + "min_notice_minutes", + "booking_window", + "limits", + "capacity", + "requires_approval", + "approval_ttl_minutes", + "hold_ttl_seconds", + "cancel_notice_minutes", + "reschedule_notice_minutes", + "questions", + "locations", + "host_filter", + "hosts", + "metadata", + "created_at", + "updated_at" + ], + "examples": [ + { + "object": "scheduling.event_type", + "id": "evtype_01kd2m9a0b1c2d3e4f5g6h7j8m", + "uid": null, + "title": "Initial consultation", + "kind": "one_on_one", + "status": "active", + "duration_minutes": 30, + "duration_options": [], + "step_minutes": 30, + "grid_time_zone": null, + "buffer_before_minutes": 0, + "buffer_after_minutes": 10, + "min_notice_minutes": 120, + "booking_window": null, + "limits": [], + "capacity": null, + "requires_approval": false, + "approval_ttl_minutes": 1440, + "hold_ttl_seconds": 600, + "cancel_notice_minutes": 0, + "reschedule_notice_minutes": 0, + "questions": [], + "locations": [], + "host_filter": null, + "hosts": [ + { + "host": "host_01kd2m9a0b1c2d3e4f5g6h7j8m", + "role": "member", + "weight": 100, + "schedule": null + } + ], + "metadata": {}, + "created_at": "2027-01-01T10:00:00.000Z", + "updated_at": "2027-01-01T10:00:00.000Z" + } + ] + }, + "SchedulingBookingWindow": { + "oneOf": [ + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "rolling" + ] + }, + "days": { + "type": "integer", + "minimum": 1, + "maximum": 730 + } + }, + "required": [ + "kind", + "days" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": [ + "range" + ] + }, + "from": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "description": "A local date in the schedule's time zone.", + "examples": [ + "2027-12-24" + ] + }, + "to": { + "type": "string", + "pattern": "^\\d{4}-\\d{2}-\\d{2}$", + "description": "A local date in the schedule's time zone.", + "examples": [ + "2027-12-24" + ] + } + }, + "required": [ + "kind", + "from", + "to" + ], + "additionalProperties": false + }, + { + "type": "null" + } + ] + }, + "SchedulingLimit": { + "type": "object", + "properties": { + "period": { + "type": "string", + "enum": [ + "day", + "week" ], "description": "In the host's time zone." }, @@ -21052,6 +21778,25 @@ ], "description": "Your approved number for SMS reminders. Without one, no SMS is sent." }, + "out_of_office_reasons": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": [ + "key", + "label" + ] + }, + "description": "Reasons of your own for time away, on top of the preset ones." + }, "calendar_failure_mode": { "type": "string", "enum": [ @@ -21090,6 +21835,7 @@ "logo", "email_from", "sms_from", + "out_of_office_reasons", "calendar_failure_mode", "notifications" ], @@ -21104,6 +21850,7 @@ "logo": null, "email_from": "appointments@example.com", "sms_from": null, + "out_of_office_reasons": [], "calendar_failure_mode": "hide", "notifications": { "reminder": { @@ -21178,6 +21925,37 @@ "last_known" ] }, + "out_of_office_reasons": { + "type": [ + "array", + "null" + ], + "items": { + "type": "object", + "properties": { + "key": { + "type": "string", + "pattern": "^[a-z][a-z0-9_]{0,63}$", + "description": "One of `unspecified`, `vacation`, `travel`, `sick`, `public_holiday`, `parental_leave`, `training` and `other`, or a key from the settings' `out_of_office_reasons`. Only people who manage this host see it: never bookers, webhooks or calendars.", + "examples": [ + "vacation" + ] + }, + "label": { + "type": "string", + "minLength": 1, + "maxLength": 60 + } + }, + "required": [ + "key", + "label" + ], + "additionalProperties": false + }, + "maxItems": 50, + "description": "Reasons of your own, on top of the preset ones. Hosts and managers see them." + }, "notifications": { "type": [ "object", @@ -33920,58 +34698,2115 @@ "risk_limit_bucket" ] }, - "id": { - "type": "string" + "id": { + "type": "string" + }, + "deleted": { + "type": "boolean", + "enum": [ + true + ] + } + }, + "required": [ + "object", + "id", + "deleted" + ] + } + }, + "parameters": { + "CossVersion": { + "in": "header", + "name": "Coss-Version", + "required": false, + "description": "The API version (a date) to use for this request. Defaults to your organization's version, pinned to the latest one when it first used the API and upgraded from the dashboard. The SDK always sends the version it was built for.", + "schema": { + "type": "string", + "enum": [ + "2026-10-10" + ], + "examples": [ + "2026-10-10" + ] + } + } + } + }, + "paths": { + "/v1/environment": { + "get": { + "operationId": "getEnvironment", + "tags": [ + "Environment" + ], + "summary": "Retrieve the API key's environment", + "description": "Which environment, project and organization the API key belongs to, and the key itself. Any valid key can read its own environment (no permission needed): use it to check a key, show where it sends and what it may do.", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "The API key's environment.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Environment" + } + } + } + }, + "400": { + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] + } + }, + "/v1/api_key": { + "delete": { + "operationId": "revokeApiKey", + "tags": [ + "Environment" + ], + "summary": "Revoke the API key", + "description": "Revokes the API key making this request, at once: every later request with it fails with `invalid_api_key`. `coss logout --revoke` uses it. Other keys are revoked in the dashboard.", + "security": [ + { + "bearerAuth": [] + } + ], + "responses": { + "200": { + "description": "The key was revoked.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeletedApiKey" + } + } + } + }, + "400": { + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] + } + }, + "/v1/emails": { + "post": { + "operationId": "sendEmail", + "tags": [ + "Emails" + ], + "summary": "Send an email", + "description": "Queues an email from the API key's environment and returns it with `status: \"queued\"`; it is handed to the delivery provider moments later. Follow it with `GET /v1/emails/{id}` or the `email.sent` / `email.failed` webhooks. Live (`coss_live_…`) keys must send from a verified domain of the organization. Sandbox (`coss_test_…`) keys accept any `from` and never deliver anything; the response has `sandbox: true`. Recipients on the environment's suppression list (for every email, or for the email's `category`) are skipped and get the status `suppressed`. With a future `scheduled_at` the email is stored with the status `scheduled` and sent at that time; the domain and the suppression list are checked again then. Attachments are base64-encoded; only metadata is kept after sending. Recipients count against the organization's send quota (per second and per day; sandbox environments have their own daily quota). With open or click tracking on (the environment's settings, or `tracking`), the HTML body is delivered with a tracking pixel and/or links rewritten to coss.com redirects; the stored `html` stays as sent.", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1, + "maxLength": 256, + "description": "Makes retries safe: a repeated request with the same key and body returns the original email (with its current status) instead of sending again, for 24 hours. 1-256 characters.", + "examples": [ + "welcome-user-123" + ] + }, + "required": false, + "description": "Makes retries safe: a repeated request with the same key and body returns the original email (with its current status) instead of sending again, for 24 hours. 1-256 characters.", + "name": "Idempotency-Key", + "in": "header" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SendEmailRequest" + } + } + } + }, + "responses": { + "202": { + "description": "The email, accepted for delivery (`queued` or `scheduled`). A replay returns the original email with its current status.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Idempotent-Replayed": { + "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", + "schema": { + "type": "string", + "enum": [ + "true" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Email" + } + } + } + }, + "400": { + "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "402": { + "description": "Live sending is paused for an overdue invoice or the spend limit (`billing_hold`), or the send would go past the plan's monthly allowance (`usage_limit_exceeded`) (`billing_error`). Never retried: it needs a plan change or a payment.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "The API key lacks the permission this endpoint needs (`insufficient_permissions`), its organization is suspended (`organization_suspended`), live sending is suspended (`account_suspended`), or sending is paused for the organization because of its sending reputation (`sending_paused`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Requests with this `Idempotency-Key` are racing for an expired key (`request_in_progress`). Retry after `Retry-After` seconds.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Retry-After": { + "description": "Seconds to wait.", + "schema": { + "type": "integer" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 40 MB (`payload_too_large`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The body failed validation (`validation_error`, see `issues`), the `from` domain is not a verified domain of the organization (`domain_not_verified`, live keys only), the `Idempotency-Key` was already used with a different body (`idempotency_key_reused`), or the template can't be sent: it doesn't exist (`template_not_found`), has no published version (`template_not_published`) or no such version (`template_version_not_found`), the variables don't match it (`invalid_template_variables`, see `issues`), or it renders an invalid subject or empty body (`template_render_failed`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "429": { + "description": "Too many requests with this API key (`rate_limited`), or the email's recipients exceed the send quota (`quota_exceeded`). Retry after `Retry-After` seconds; without `Retry-After` the email has more recipients than the quota allows at once.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Retry-After": { + "description": "Seconds to wait.", + "schema": { + "type": "integer" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "get": { + "operationId": "listEmails", + "tags": [ + "Emails" + ], + "summary": "List emails", + "description": "Emails sent from the API key's environment, newest first, without their content (retrieve an email for `html`, `text`, `headers` and `attachments`). Filter by recipient (`to`), by the email's or a recipient's status, by category, batch or creation time. Pass the last `id` as `after` to get the next page while `has_more` is true.", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1, + "maxLength": 320, + "description": "Only emails with this recipient (in `to`, `cc` or `bcc`; the bare address, any case).", + "examples": [ + "user@example.com" + ] + }, + "required": false, + "description": "Only emails with this recipient (in `to`, `cc` or `bcc`; the bare address, any case).", + "name": "to", + "in": "query" + }, + { + "schema": { + "type": "string", + "description": "Only emails with a recipient in one of these statuses, comma-separated: `bounced,complained`. With `to`, that recipient's status." + }, + "required": false, + "description": "Only emails with a recipient in one of these statuses, comma-separated: `bounced,complained`. With `to`, that recipient's status.", + "name": "recipient_status", + "in": "query" + }, + { + "schema": { + "type": "string", + "description": "Only emails in these statuses, comma-separated: `failed`." + }, + "required": false, + "description": "Only emails in these statuses, comma-separated: `failed`.", + "name": "status", + "in": "query" + }, + { + "schema": { + "type": "string", + "maxLength": 256, + "description": "Free text, matched against the subject and the `to` addresses." + }, + "required": false, + "description": "Free text, matched against the subject and the `to` addresses.", + "name": "q", + "in": "query" + }, + { + "schema": { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,256}$", + "description": "Only emails of this category." + }, + "required": false, + "description": "Only emails of this category.", + "name": "category", + "in": "query" + }, + { + "schema": { + "type": "string", + "maxLength": 64, + "description": "Only the emails of this batch." + }, + "required": false, + "description": "Only the emails of this batch.", + "name": "batch_id", + "in": "query" + }, + { + "schema": { + "type": "string", + "minLength": 1, + "maxLength": 256, + "description": "Only the emails sent for this sub-account (its id or your uid)." + }, + "required": false, + "description": "Only the emails sent for this sub-account (its id or your uid).", + "name": "subaccount", + "in": "query" + }, + { + "schema": { + "type": "string", + "format": "date-time", + "description": "Only emails created at or after this time." + }, + "required": false, + "description": "Only emails created at or after this time.", + "name": "created_after", + "in": "query" + }, + { + "schema": { + "type": "string", + "format": "date-time", + "description": "Only emails created before this time." + }, + "required": false, + "description": "Only emails created before this time.", + "name": "created_before", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "1-100, default 20." + }, + "required": false, + "description": "1-100, default 20.", + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "maxLength": 64, + "description": "Cursor: the `id` of the last email of the previous page." + }, + "required": false, + "description": "Cursor: the `id` of the last email of the previous page.", + "name": "after", + "in": "query" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "responses": { + "200": { + "description": "A page of emails.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmailSummaryList" + } + } + } + }, + "400": { + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/v1/emails/batch": { + "post": { + "operationId": "sendEmailBatch", + "tags": [ + "Emails" + ], + "summary": "Send a batch of emails", + "description": "Queues up to 100 emails in one request. Each email is handled exactly as by `POST /v1/emails` (sender checks, suppressions, scheduling, attachments, tracking), but the batch is all or nothing: if any email is invalid, or any `from` is not a verified domain (live keys), nothing is stored and the error names the email (e.g. `emails.3.to`). One `Idempotency-Key` covers the whole batch. The emails' recipients are charged against the send quota together, so a batch with more recipients than the quota allows at once is refused (`quota_exceeded` without `Retry-After`): split it. The request body shares the 40 MB limit of a single send.", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1, + "maxLength": 256, + "description": "Makes retries safe: a repeated request with the same key and body returns the original email (with its current status) instead of sending again, for 24 hours. 1-256 characters.", + "examples": [ + "welcome-user-123" + ] + }, + "required": false, + "description": "Makes retries safe: a repeated request with the same key and body returns the original email (with its current status) instead of sending again, for 24 hours. 1-256 characters.", + "name": "Idempotency-Key", + "in": "header" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SendEmailBatchRequest" + } + } + } + }, + "responses": { + "202": { + "description": "The batch, accepted for delivery, with its emails in request order. A replay returns the original batch with the emails' current statuses.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Idempotent-Replayed": { + "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", + "schema": { + "type": "string", + "enum": [ + "true" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmailBatch" + } + } + } + }, + "400": { + "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "402": { + "description": "Live sending is paused for an overdue invoice or the spend limit (`billing_hold`), or the send would go past the plan's monthly allowance (`usage_limit_exceeded`) (`billing_error`). Never retried: it needs a plan change or a payment.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "The API key lacks the permission this endpoint needs (`insufficient_permissions`), its organization is suspended (`organization_suspended`), live sending is suspended (`account_suspended`), or sending is paused for the organization because of its sending reputation (`sending_paused`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Requests with this `Idempotency-Key` are racing for an expired key (`request_in_progress`). Retry after `Retry-After` seconds.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Retry-After": { + "description": "Seconds to wait.", + "schema": { + "type": "integer" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 40 MB (`payload_too_large`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The body failed validation (`validation_error`, see `issues`), a `from` domain is not a verified domain of the organization (`domain_not_verified`, live keys only; `param` names the email), the `Idempotency-Key` was already used with a different body (`idempotency_key_reused`), or an email's template can't be sent (the `template_…` codes of `POST /v1/emails`; `param` names the email).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "429": { + "description": "Too many requests with this API key (`rate_limited`), or the batch's recipients exceed the send quota (`quota_exceeded`). Retry after `Retry-After` seconds; without `Retry-After` the batch has more recipients than the quota allows at once.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Retry-After": { + "description": "Seconds to wait.", + "schema": { + "type": "integer" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/v1/emails/batch/{id}": { + "get": { + "operationId": "getEmailBatch", + "tags": [ + "Emails" + ], + "summary": "Retrieve a batch of emails", + "description": "A batch sent with `POST /v1/emails/batch`, with its emails' current statuses in the order of the request. Emails past the data retention period are left out. Only batches sent from the API key's own environment can be retrieved.", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The batch's id (`batch_id` of its emails).", + "examples": [ + "batch_01k8d0n6x5f3w2e1r9t7y4u6i8" + ] + }, + "required": true, + "description": "The batch's id (`batch_id` of its emails).", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "responses": { + "200": { + "description": "The batch.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmailBatch" + } + } + } + }, + "400": { + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "No batch with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/v1/emails/{id}": { + "get": { + "operationId": "getEmail", + "tags": [ + "Emails" + ], + "summary": "Retrieve an email", + "description": "Only emails sent from the API key's own environment can be retrieved.", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The email's id.", + "examples": [ + "email_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The email's id.", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "responses": { + "200": { + "description": "The email.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Email" + } + } + } + }, + "400": { + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "No email with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/v1/emails/{id}/cancel": { + "post": { + "operationId": "cancelEmail", + "tags": [ + "Emails" + ], + "summary": "Cancel a scheduled email", + "description": "Cancels an email sent with a future `scheduled_at` before it is sent. Canceling an already canceled email returns it unchanged. To send it at another time, reschedule it instead.", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The email's id.", + "examples": [ + "email_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The email's id.", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "responses": { + "200": { + "description": "The canceled email.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Email" + } + } + } + }, + "400": { + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "No email with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The email is not scheduled (it is being sent, was sent or failed): `email_not_cancelable`.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } }, - "deleted": { - "type": "boolean", - "enum": [ - true - ] + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } } - }, - "required": [ - "object", - "id", - "deleted" - ] - } - }, - "parameters": { - "CossVersion": { - "in": "header", - "name": "Coss-Version", - "required": false, - "description": "The API version (a date) to use for this request. Defaults to your organization's version, pinned to the latest one when it first used the API and upgraded from the dashboard. The SDK always sends the version it was built for.", - "schema": { - "type": "string", - "enum": [ - "2026-10-10" - ], - "examples": [ - "2026-10-10" - ] } } - } - }, - "paths": { - "/v1/environment": { - "get": { - "operationId": "getEnvironment", + }, + "/v1/emails/{id}/reschedule": { + "post": { + "operationId": "rescheduleEmail", "tags": [ - "Environment" + "Emails" ], - "summary": "Retrieve the API key's environment", - "description": "Which environment, project and organization the API key belongs to, and the key itself. Any valid key can read its own environment (no permission needed): use it to check a key, show where it sends and what it may do.", + "summary": "Reschedule a scheduled email", + "description": "Moves an email sent with a future `scheduled_at` to a new time, at most 30 days from now, and records an `email.rescheduled` event. A time that is not in the future sends it within seconds. Rescheduling to the time it already has returns it unchanged. The domain and the suppression list are still checked when it is sent.", "security": [ { "bearerAuth": [] } ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The email's id.", + "examples": [ + "email_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The email's id.", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RescheduleEmailRequest" + } + } + } + }, "responses": { "200": { - "description": "The API key's environment.", + "description": "The rescheduled email.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -33995,13 +36830,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Environment" + "$ref": "#/components/schemas/Email" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -34063,6 +36898,69 @@ } } }, + "404": { + "description": "No email with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The body failed validation (`validation_error`, see `issues`), or the email is not scheduled (it is being sent, was sent, failed or was canceled): `email_not_reschedulable`.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -34132,30 +37030,43 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] + } } }, - "/v1/api_key": { - "delete": { - "operationId": "revokeApiKey", + "/v1/emails/{id}/events": { + "get": { + "operationId": "listEmailEvents", "tags": [ - "Environment" + "Emails" ], - "summary": "Revoke the API key", - "description": "Revokes the API key making this request, at once: every later request with it fails with `invalid_api_key`. `coss logout --revoke` uses it. Other keys are revoked in the dashboard.", + "summary": "List an email's delivery events", + "description": "Every delivery event of the email, oldest first: `email.scheduled`, `email.rescheduled`, `email.canceled`, `email.sent` and `email.failed` for the whole email, and `email.delivered`, `email.delivery_delayed`, `email.bounced`, `email.complained` and `email.suppressed` (skipped because of the suppression list) per recipient, plus `email.opened` and `email.clicked` when tracking is on (attributed to a recipient only when the email had a single one) and `email.unsubscribed` after a one-click unsubscribe.", "security": [ { "bearerAuth": [] } ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The email's id.", + "examples": [ + "email_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The email's id.", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], "responses": { "200": { - "description": "The key was revoked.", + "description": "The email's events.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -34179,7 +37090,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedApiKey" + "$ref": "#/components/schemas/EmailEventList" } } } @@ -34247,6 +37158,27 @@ } } }, + "404": { + "description": "No email with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -34316,22 +37248,17 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] + } } }, - "/v1/emails": { - "post": { - "operationId": "sendEmail", + "/v1/emails/{id}/links": { + "get": { + "operationId": "listEmailLinks", "tags": [ "Emails" ], - "summary": "Send an email", - "description": "Queues an email from the API key's environment and returns it with `status: \"queued\"`; it is handed to the delivery provider moments later. Follow it with `GET /v1/emails/{id}` or the `email.sent` / `email.failed` webhooks. Live (`coss_live_…`) keys must send from a verified domain of the organization. Sandbox (`coss_test_…`) keys accept any `from` and never deliver anything; the response has `sandbox: true`. Recipients on the environment's suppression list (for every email, or for the email's `category`) are skipped and get the status `suppressed`. With a future `scheduled_at` the email is stored with the status `scheduled` and sent at that time; the domain and the suppression list are checked again then. Attachments are base64-encoded; only metadata is kept after sending. Recipients count against the organization's send quota (per second and per day; sandbox environments have their own daily quota). With open or click tracking on (the environment's settings, or `tracking`), the HTML body is delivered with a tracking pixel and/or links rewritten to coss.com redirects; the stored `html` stays as sent.", + "summary": "List an email's tracked links", + "description": "The links coss.com rewrote for click tracking, in the order they appear in the HTML, with their click counts. Empty unless the email was sent with click tracking.", "security": [ { "bearerAuth": [] @@ -34341,35 +37268,23 @@ { "schema": { "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "Makes retries safe: a repeated request with the same key and body returns the original email (with its current status) instead of sending again, for 24 hours. 1-256 characters.", + "description": "The email's id.", "examples": [ - "welcome-user-123" + "email_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, - "required": false, - "description": "Makes retries safe: a repeated request with the same key and body returns the original email (with its current status) instead of sending again, for 24 hours. 1-256 characters.", - "name": "Idempotency-Key", - "in": "header" + "required": true, + "description": "The email's id.", + "name": "id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SendEmailRequest" - } - } - } - }, "responses": { - "202": { - "description": "The email, accepted for delivery (`queued` or `scheduled`). A replay returns the original email with its current status.", + "200": { + "description": "The email's tracked links.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -34380,15 +37295,6 @@ ] } }, - "Idempotent-Replayed": { - "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", - "schema": { - "type": "string", - "enum": [ - "true" - ] - } - }, "Coss-Version": { "description": "The API version this response is rendered in.", "schema": { @@ -34402,13 +37308,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Email" + "$ref": "#/components/schemas/EmailLinkList" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -34449,8 +37355,8 @@ } } }, - "402": { - "description": "Live sending is paused for an overdue invoice or the spend limit (`billing_hold`), or the send would go past the plan's monthly allowance (`usage_limit_exceeded`) (`billing_error`). Never retried: it needs a plan change or a payment.", + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -34470,8 +37376,8 @@ } } }, - "403": { - "description": "The API key lacks the permission this endpoint needs (`insufficient_permissions`), its organization is suspended (`organization_suspended`), live sending is suspended (`account_suspended`), or sending is paused for the organization because of its sending reputation (`sending_paused`).", + "404": { + "description": "No email with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -34491,8 +37397,8 @@ } } }, - "409": { - "description": "Requests with this `Idempotency-Key` are racing for an expired key (`request_in_progress`). Retry after `Retry-After` seconds.", + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -34504,7 +37410,7 @@ } }, "Retry-After": { - "description": "Seconds to wait.", + "description": "Seconds to wait before retrying.", "schema": { "type": "integer" } @@ -34518,8 +37424,170 @@ } } }, + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/v1/email_templates": { + "post": { + "operationId": "createEmailTemplate", + "tags": [ + "Email templates" + ], + "summary": "Create an email template", + "description": "Creates a template with a draft holding its variables and a subject, HTML and text per locale. Sends use it once its draft is published. Not idempotent: retrying after a lost response can create a second template (unless it has an `alias`). Templates belong to the API key's own environment: a `coss_test_…` key only ever sees sandbox ones. Give a template the same `alias` in every environment to send it by that name.", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateEmailTemplateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "The template.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EmailTemplate" + } + } + } + }, + "400": { + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "413": { - "description": "The request body is larger than 40 MB (`payload_too_large`).", + "description": "The request body is larger than 5 MB (`payload_too_large`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -34561,7 +37629,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`, see `issues`), the `from` domain is not a verified domain of the organization (`domain_not_verified`, live keys only), the `Idempotency-Key` was already used with a different body (`idempotency_key_reused`), or the template can't be sent: it doesn't exist (`template_not_found`), has no published version (`template_not_published`) or no such version (`template_version_not_found`), the variables don't match it (`invalid_template_variables`, see `issues`), or it renders an invalid subject or empty body (`template_render_failed`).", + "description": "The body failed validation (`validation_error`), another template has the alias (`template_alias_taken`), or the environment has 500 templates (`template_limit_reached`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -34582,7 +37650,7 @@ } }, "429": { - "description": "Too many requests with this API key (`rate_limited`), or the email's recipients exceed the send quota (`quota_exceeded`). Retry after `Retry-After` seconds; without `Retry-After` the email has more recipients than the quota allows at once.", + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -34594,7 +37662,7 @@ } }, "Retry-After": { - "description": "Seconds to wait.", + "description": "Seconds to wait before retrying.", "schema": { "type": "integer" } @@ -34650,143 +37718,45 @@ } } } - } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] }, "get": { - "operationId": "listEmails", + "operationId": "listEmailTemplates", "tags": [ - "Emails" + "Email templates" ], - "summary": "List emails", - "description": "Emails sent from the API key's environment, newest first, without their content (retrieve an email for `html`, `text`, `headers` and `attachments`). Filter by recipient (`to`), by the email's or a recipient's status, by category, batch or creation time. Pass the last `id` as `after` to get the next page while `has_more` is true.", + "summary": "List email templates", + "description": "The environment's templates, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", "security": [ { "bearerAuth": [] } ], "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1, - "maxLength": 320, - "description": "Only emails with this recipient (in `to`, `cc` or `bcc`; the bare address, any case).", - "examples": [ - "user@example.com" - ] - }, - "required": false, - "description": "Only emails with this recipient (in `to`, `cc` or `bcc`; the bare address, any case).", - "name": "to", - "in": "query" - }, - { - "schema": { - "type": "string", - "description": "Only emails with a recipient in one of these statuses, comma-separated: `bounced,complained`. With `to`, that recipient's status." - }, - "required": false, - "description": "Only emails with a recipient in one of these statuses, comma-separated: `bounced,complained`. With `to`, that recipient's status.", - "name": "recipient_status", - "in": "query" - }, - { - "schema": { - "type": "string", - "description": "Only emails in these statuses, comma-separated: `failed`." - }, - "required": false, - "description": "Only emails in these statuses, comma-separated: `failed`.", - "name": "status", - "in": "query" - }, - { - "schema": { - "type": "string", - "maxLength": 256, - "description": "Free text, matched against the subject and the `to` addresses." - }, - "required": false, - "description": "Free text, matched against the subject and the `to` addresses.", - "name": "q", - "in": "query" - }, - { - "schema": { - "type": "string", - "pattern": "^[A-Za-z0-9_-]{1,256}$", - "description": "Only emails of this category." - }, - "required": false, - "description": "Only emails of this category.", - "name": "category", - "in": "query" - }, - { - "schema": { - "type": "string", - "maxLength": 64, - "description": "Only the emails of this batch." - }, - "required": false, - "description": "Only the emails of this batch.", - "name": "batch_id", - "in": "query" - }, - { - "schema": { - "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "Only the emails sent for this sub-account (its id or your uid)." - }, - "required": false, - "description": "Only the emails sent for this sub-account (its id or your uid).", - "name": "subaccount", - "in": "query" - }, - { - "schema": { - "type": "string", - "format": "date-time", - "description": "Only emails created at or after this time." - }, - "required": false, - "description": "Only emails created at or after this time.", - "name": "created_after", - "in": "query" - }, - { - "schema": { - "type": "string", - "format": "date-time", - "description": "Only emails created before this time." - }, - "required": false, - "description": "Only emails created before this time.", - "name": "created_before", - "in": "query" - }, { "schema": { "type": "integer", "minimum": 1, "maximum": 100, - "description": "1-100, default 20." + "description": "1-100, default 50." }, "required": false, - "description": "1-100, default 20.", + "description": "1-100, default 50.", "name": "limit", "in": "query" }, { "schema": { "type": "string", - "maxLength": 64, - "description": "Cursor: the `id` of the last email of the previous page." + "description": "Cursor: the `id` of the last template of the previous page." }, "required": false, - "description": "Cursor: the `id` of the last email of the previous page.", + "description": "Cursor: the `id` of the last template of the previous page.", "name": "after", "in": "query" }, @@ -34796,7 +37766,7 @@ ], "responses": { "200": { - "description": "A page of emails.", + "description": "A page of templates.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -34820,7 +37790,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailSummaryList" + "$ref": "#/components/schemas/EmailTemplateList" } } } @@ -34981,14 +37951,14 @@ } } }, - "/v1/emails/batch": { - "post": { - "operationId": "sendEmailBatch", + "/v1/email_templates/{id}": { + "get": { + "operationId": "getEmailTemplate", "tags": [ - "Emails" + "Email templates" ], - "summary": "Send a batch of emails", - "description": "Queues up to 100 emails in one request. Each email is handled exactly as by `POST /v1/emails` (sender checks, suppressions, scheduling, attachments, tracking), but the batch is all or nothing: if any email is invalid, or any `from` is not a verified domain (live keys), nothing is stored and the error names the email (e.g. `emails.3.to`). One `Idempotency-Key` covers the whole batch. The emails' recipients are charged against the send quota together, so a batch with more recipients than the quota allows at once is refused (`quota_exceeded` without `Retry-After`): split it. The request body shares the 40 MB limit of a single send.", + "summary": "Retrieve an email template", + "description": "A template by id or alias. Its content is in its draft and versions.", "security": [ { "bearerAuth": [] @@ -34998,35 +37968,23 @@ { "schema": { "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "Makes retries safe: a repeated request with the same key and body returns the original email (with its current status) instead of sending again, for 24 hours. 1-256 characters.", + "description": "The template's id or alias.", "examples": [ - "welcome-user-123" + "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, - "required": false, - "description": "Makes retries safe: a repeated request with the same key and body returns the original email (with its current status) instead of sending again, for 24 hours. 1-256 characters.", - "name": "Idempotency-Key", - "in": "header" + "required": true, + "description": "The template's id or alias.", + "name": "id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SendEmailBatchRequest" - } - } - } - }, "responses": { - "202": { - "description": "The batch, accepted for delivery, with its emails in request order. A replay returns the original batch with the emails' current statuses.", + "200": { + "description": "The template.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35037,15 +37995,6 @@ ] } }, - "Idempotent-Replayed": { - "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", - "schema": { - "type": "string", - "enum": [ - "true" - ] - } - }, "Coss-Version": { "description": "The API version this response is rendered in.", "schema": { @@ -35059,13 +38008,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailBatch" + "$ref": "#/components/schemas/EmailTemplate" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35106,98 +38055,8 @@ } } }, - "402": { - "description": "Live sending is paused for an overdue invoice or the spend limit (`billing_hold`), or the send would go past the plan's monthly allowance (`usage_limit_exceeded`) (`billing_error`). Never retried: it needs a plan change or a payment.", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "403": { - "description": "The API key lacks the permission this endpoint needs (`insufficient_permissions`), its organization is suspended (`organization_suspended`), live sending is suspended (`account_suspended`), or sending is paused for the organization because of its sending reputation (`sending_paused`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "409": { - "description": "Requests with this `Idempotency-Key` are racing for an expired key (`request_in_progress`). Retry after `Retry-After` seconds.", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - }, - "Retry-After": { - "description": "Seconds to wait.", - "schema": { - "type": "integer" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "413": { - "description": "The request body is larger than 40 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35217,8 +38076,8 @@ } } }, - "422": { - "description": "The body failed validation (`validation_error`, see `issues`), a `from` domain is not a verified domain of the organization (`domain_not_verified`, live keys only; `param` names the email), the `Idempotency-Key` was already used with a different body (`idempotency_key_reused`), or an email's template can't be sent (the `template_…` codes of `POST /v1/emails`; `param` names the email).", + "404": { + "description": "No template with this id or alias exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35239,7 +38098,7 @@ } }, "429": { - "description": "Too many requests with this API key (`rate_limited`), or the batch's recipients exceed the send quota (`quota_exceeded`). Retry after `Retry-After` seconds; without `Retry-After` the batch has more recipients than the quota allows at once.", + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35251,7 +38110,7 @@ } }, "Retry-After": { - "description": "Seconds to wait.", + "description": "Seconds to wait before retrying.", "schema": { "type": "integer" } @@ -35308,16 +38167,14 @@ } } } - } - }, - "/v1/emails/batch/{id}": { - "get": { - "operationId": "getEmailBatch", + }, + "patch": { + "operationId": "updateEmailTemplate", "tags": [ - "Emails" + "Email templates" ], - "summary": "Retrieve a batch of emails", - "description": "A batch sent with `POST /v1/emails/batch`, with its emails' current statuses in the order of the request. Emails past the data retention period are left out. Only batches sent from the API key's own environment can be retrieved.", + "summary": "Update an email template", + "description": "Changes the template's name, alias or description. Changing the alias changes what sends must use. Content changes go to the draft (`PUT /v1/email_templates/{id}/draft`).", "security": [ { "bearerAuth": [] @@ -35327,13 +38184,13 @@ { "schema": { "type": "string", - "description": "The batch's id (`batch_id` of its emails).", + "description": "The template's id or alias.", "examples": [ - "batch_01k8d0n6x5f3w2e1r9t7y4u6i8" + "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The batch's id (`batch_id` of its emails).", + "description": "The template's id or alias.", "name": "id", "in": "path" }, @@ -35341,9 +38198,19 @@ "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateEmailTemplateRequest" + } + } + } + }, "responses": { "200": { - "description": "The batch.", + "description": "The template.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35367,13 +38234,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailBatch" + "$ref": "#/components/schemas/EmailTemplate" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35436,7 +38303,70 @@ } }, "404": { - "description": "No batch with this id exists in the API key's environment (`not_found`).", + "description": "No template with this id or alias exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The body failed validation (`validation_error`), or another template has the alias (`template_alias_taken`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35526,16 +38456,14 @@ } } } - } - }, - "/v1/emails/{id}": { - "get": { - "operationId": "getEmail", + }, + "delete": { + "operationId": "deleteEmailTemplate", "tags": [ - "Emails" + "Email templates" ], - "summary": "Retrieve an email", - "description": "Only emails sent from the API key's own environment can be retrieved.", + "summary": "Delete an email template", + "description": "Deletes the template with its draft and every version. Emails already sent or scheduled from it keep their content; new sends naming it fail with `template_not_found`.", "security": [ { "bearerAuth": [] @@ -35545,13 +38473,13 @@ { "schema": { "type": "string", - "description": "The email's id.", + "description": "The template's id or alias.", "examples": [ - "email_01k7c8m4q2f3e9v6t5r1n0p8yz" + "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The email's id.", + "description": "The template's id or alias.", "name": "id", "in": "path" }, @@ -35561,7 +38489,7 @@ ], "responses": { "200": { - "description": "The email.", + "description": "The template was deleted.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35585,7 +38513,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Email" + "$ref": "#/components/schemas/DeletedEmailTemplate" } } } @@ -35654,7 +38582,7 @@ } }, "404": { - "description": "No email with this id exists in the API key's environment (`not_found`).", + "description": "No template with this id or alias exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35746,14 +38674,14 @@ } } }, - "/v1/emails/{id}/cancel": { - "post": { - "operationId": "cancelEmail", + "/v1/email_templates/{id}/draft": { + "get": { + "operationId": "getEmailTemplateDraft", "tags": [ - "Emails" + "Email templates" ], - "summary": "Cancel a scheduled email", - "description": "Cancels an email sent with a future `scheduled_at` before it is sent. Canceling an already canceled email returns it unchanged. To send it at another time, reschedule it instead.", + "summary": "Retrieve a template's draft", + "description": "The draft (`version: null`): what the next publish makes sends use. `problems` lists syntax errors and undeclared variables, which keep it from being published.", "security": [ { "bearerAuth": [] @@ -35763,13 +38691,13 @@ { "schema": { "type": "string", - "description": "The email's id.", + "description": "The template's id or alias.", "examples": [ - "email_01k7c8m4q2f3e9v6t5r1n0p8yz" + "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The email's id.", + "description": "The template's id or alias.", "name": "id", "in": "path" }, @@ -35779,7 +38707,7 @@ ], "responses": { "200": { - "description": "The canceled email.", + "description": "The draft.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35803,7 +38731,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Email" + "$ref": "#/components/schemas/EmailTemplateVersion" } } } @@ -35872,28 +38800,7 @@ } }, "404": { - "description": "No email with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The email is not scheduled (it is being sent, was sent or failed): `email_not_cancelable`.", + "description": "No template with this id or alias exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -35983,16 +38890,14 @@ } } } - } - }, - "/v1/emails/{id}/reschedule": { - "post": { - "operationId": "rescheduleEmail", + }, + "put": { + "operationId": "updateEmailTemplateDraft", "tags": [ - "Emails" + "Email templates" ], - "summary": "Reschedule a scheduled email", - "description": "Moves an email sent with a future `scheduled_at` to a new time, at most 30 days from now, and records an `email.rescheduled` event. A time that is not in the future sends it within seconds. Rescheduling to the time it already has returns it unchanged. The domain and the suppression list are still checked when it is sent.", + "summary": "Update a template's draft", + "description": "Replaces the draft's variables and content. Sends keep using the published version until the draft is published. Pass the `revision` you read to refuse overwriting someone else's changes. A draft with problems is saved (and reported in `problems`).", "security": [ { "bearerAuth": [] @@ -36002,13 +38907,13 @@ { "schema": { "type": "string", - "description": "The email's id.", + "description": "The template's id or alias.", "examples": [ - "email_01k7c8m4q2f3e9v6t5r1n0p8yz" + "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The email's id.", + "description": "The template's id or alias.", "name": "id", "in": "path" }, @@ -36021,14 +38926,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RescheduleEmailRequest" + "$ref": "#/components/schemas/UpdateEmailTemplateDraftRequest" } } } }, "responses": { "200": { - "description": "The rescheduled email.", + "description": "The saved draft.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36052,7 +38957,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Email" + "$ref": "#/components/schemas/EmailTemplateVersion" } } } @@ -36121,7 +39026,28 @@ } }, "404": { - "description": "No email with this id exists in the API key's environment (`not_found`).", + "description": "No template with this id or alias exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36163,7 +39089,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`, see `issues`), or the email is not scheduled (it is being sent, was sent, failed or was canceled): `email_not_reschedulable`.", + "description": "The body failed validation (`validation_error`), or the draft changed since `revision` (`template_revision_mismatch`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36255,14 +39181,14 @@ } } }, - "/v1/emails/{id}/events": { - "get": { - "operationId": "listEmailEvents", + "/v1/email_templates/{id}/publish": { + "post": { + "operationId": "publishEmailTemplate", "tags": [ - "Emails" + "Email templates" ], - "summary": "List an email's delivery events", - "description": "Every delivery event of the email, oldest first: `email.scheduled`, `email.rescheduled`, `email.canceled`, `email.sent` and `email.failed` for the whole email, and `email.delivered`, `email.delivery_delayed`, `email.bounced`, `email.complained` and `email.suppressed` (skipped because of the suppression list) per recipient, plus `email.opened` and `email.clicked` when tracking is on (attributed to a recipient only when the email had a single one) and `email.unsubscribed` after a one-click unsubscribe.", + "summary": "Publish a template's draft", + "description": "Copies the draft into the next version, which sends use from then on. Emails already accepted keep the content they were rendered with. A draft without changes since the last publish returns that version, so retrying with the `revision` you reviewed is safe (without it, a retry could publish edits saved in between).", "security": [ { "bearerAuth": [] @@ -36272,13 +39198,13 @@ { "schema": { "type": "string", - "description": "The email's id.", + "description": "The template's id or alias.", "examples": [ - "email_01k7c8m4q2f3e9v6t5r1n0p8yz" + "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The email's id.", + "description": "The template's id or alias.", "name": "id", "in": "path" }, @@ -36286,9 +39212,19 @@ "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PublishEmailTemplateRequest" + } + } + } + }, "responses": { "200": { - "description": "The email's events.", + "description": "The published version.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36312,13 +39248,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailEventList" + "$ref": "#/components/schemas/EmailTemplateVersion" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36381,7 +39317,70 @@ } }, "404": { - "description": "No email with this id exists in the API key's environment (`not_found`).", + "description": "No template with this id or alias exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The draft has problems or no content for its default locale (`template_invalid`, see `issues`), or changed since `revision` (`template_revision_mismatch`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36473,14 +39472,14 @@ } } }, - "/v1/emails/{id}/links": { - "get": { - "operationId": "listEmailLinks", + "/v1/email_templates/{id}/render": { + "post": { + "operationId": "renderEmailTemplate", "tags": [ - "Emails" + "Email templates" ], - "summary": "List an email's tracked links", - "description": "The links coss.com rewrote for click tracking, in the order they appear in the HTML, with their click counts. Empty unless the email was sent with click tracking.", + "summary": "Render a template", + "description": "Renders the draft (or a published `version`) with `variables`, exactly as a send would, and returns the subject, HTML and text: a preview, nothing is sent or stored. Without `variables` it renders the version's `sample_variables`.", "security": [ { "bearerAuth": [] @@ -36490,13 +39489,13 @@ { "schema": { "type": "string", - "description": "The email's id.", + "description": "The template's id or alias.", "examples": [ - "email_01k7c8m4q2f3e9v6t5r1n0p8yz" + "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The email's id.", + "description": "The template's id or alias.", "name": "id", "in": "path" }, @@ -36504,9 +39503,19 @@ "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RenderEmailTemplateRequest" + } + } + } + }, "responses": { "200": { - "description": "The email's tracked links.", + "description": "The rendered template.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36530,13 +39539,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailLinkList" + "$ref": "#/components/schemas/RenderedEmailTemplate" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36599,7 +39608,70 @@ } }, "404": { - "description": "No email with this id exists in the API key's environment (`not_found`).", + "description": "No template with this id or alias exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The body failed validation (`validation_error`), the draft has problems (`template_invalid`, see `issues`), the variables don't match its declarations (`invalid_template_variables`), it has no such version (`template_version_not_found`), or it doesn't render (`template_render_failed`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36691,32 +39763,63 @@ } } }, - "/v1/email_templates": { - "post": { - "operationId": "createEmailTemplate", + "/v1/email_templates/{id}/versions": { + "get": { + "operationId": "listEmailTemplateVersions", "tags": [ "Email templates" ], - "summary": "Create an email template", - "description": "Creates a template with a draft holding its variables and a subject, HTML and text per locale. Sends use it once its draft is published. Not idempotent: retrying after a lost response can create a second template (unless it has an `alias`). Templates belong to the API key's own environment: a `coss_test_…` key only ever sees sandbox ones. Give a template the same `alias` in every environment to send it by that name.", + "summary": "List a template's versions", + "description": "Published versions, newest first. Pass the last `version` as `after` to get the next page while `has_more` is true.", "security": [ { "bearerAuth": [] } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateEmailTemplateRequest" - } - } + "parameters": [ + { + "schema": { + "type": "string", + "description": "The template's id or alias.", + "examples": [ + "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The template's id or alias.", + "name": "id", + "in": "path" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 20, + "description": "1-20, default 10." + }, + "required": false, + "description": "1-20, default 10.", + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "description": "Cursor: the `version` of the last version of the previous page." + }, + "required": false, + "description": "Cursor: the `version` of the last version of the previous page.", + "name": "after", + "in": "query" + }, + { + "$ref": "#/components/parameters/CossVersion" } - }, + ], "responses": { "200": { - "description": "The template.", + "description": "A page of versions.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36740,13 +39843,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailTemplate" + "$ref": "#/components/schemas/EmailTemplateVersionList" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36808,29 +39911,8 @@ } } }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "404": { + "description": "No template with this id or alias exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36851,7 +39933,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`), another template has the alias (`template_alias_taken`), or the environment has 500 templates (`template_limit_reached`).", + "description": "A query parameter failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -36940,20 +40022,17 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] - }, + } + } + }, + "/v1/email_templates/{id}/versions/{version}": { "get": { - "operationId": "listEmailTemplates", + "operationId": "getEmailTemplateVersion", "tags": [ "Email templates" ], - "summary": "List email templates", - "description": "The environment's templates, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", + "summary": "Retrieve a template version", + "description": "A published version, which never changes.", "security": [ { "bearerAuth": [] @@ -36962,25 +40041,30 @@ "parameters": [ { "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "description": "1-100, default 50." + "type": "string", + "description": "The template's id or alias.", + "examples": [ + "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] }, - "required": false, - "description": "1-100, default 50.", - "name": "limit", - "in": "query" + "required": true, + "description": "The template's id or alias.", + "name": "id", + "in": "path" }, { "schema": { - "type": "string", - "description": "Cursor: the `id` of the last template of the previous page." + "type": "integer", + "minimum": 1, + "description": "A published version number.", + "examples": [ + 1 + ] }, - "required": false, - "description": "Cursor: the `id` of the last template of the previous page.", - "name": "after", - "in": "query" + "required": true, + "description": "A published version number.", + "name": "version", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" @@ -36988,7 +40072,7 @@ ], "responses": { "200": { - "description": "A page of templates.", + "description": "The version.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -37012,7 +40096,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailTemplateList" + "$ref": "#/components/schemas/EmailTemplateVersion" } } } @@ -37080,8 +40164,8 @@ } } }, - "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "404": { + "description": "No template with this id or alias exists in the API key's environment, or it has no such version (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -37173,14 +40257,14 @@ } } }, - "/v1/email_templates/{id}": { - "get": { - "operationId": "getEmailTemplate", + "/v1/email_templates/{id}/versions/{version}/restore": { + "post": { + "operationId": "restoreEmailTemplateVersion", "tags": [ "Email templates" ], - "summary": "Retrieve an email template", - "description": "A template by id or alias. Its content is in its draft and versions.", + "summary": "Restore a template version", + "description": "Replaces the draft with a published version's variables and content. Publish the draft to make sends use it again.", "security": [ { "bearerAuth": [] @@ -37200,13 +40284,27 @@ "name": "id", "in": "path" }, + { + "schema": { + "type": "integer", + "minimum": 1, + "description": "A published version number.", + "examples": [ + 1 + ] + }, + "required": true, + "description": "A published version number.", + "name": "version", + "in": "path" + }, { "$ref": "#/components/parameters/CossVersion" } ], "responses": { "200": { - "description": "The template.", + "description": "The draft.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -37230,7 +40328,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailTemplate" + "$ref": "#/components/schemas/EmailTemplateVersion" } } } @@ -37319,6 +40417,27 @@ } } }, + "422": { + "description": "The template has no such version (`template_version_not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -37389,50 +40508,34 @@ } } } - }, - "patch": { - "operationId": "updateEmailTemplate", + } + }, + "/v1/domains": { + "post": { + "operationId": "createDomain", "tags": [ - "Email templates" + "Domains" ], - "summary": "Update an email template", - "description": "Changes the template's name, alias or description. Changing the alias changes what sends must use. Content changes go to the draft (`PUT /v1/email_templates/{id}/draft`).", + "summary": "Add a sending domain", + "description": "Claims the domain for the organization and returns the DNS records to publish. Domains belong to the organization, not to one environment, so every API key of the organization sees the same domains. The records are checked repeatedly in the background and verification gives up after 72 hours; until the domain is `verified`, live keys cannot send from it.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The template's id or alias.", - "examples": [ - "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The template's id or alias.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateEmailTemplateRequest" + "$ref": "#/components/schemas/CreateDomainRequest" } } } }, "responses": { "200": { - "description": "The template.", + "description": "The domain, with the DNS records to publish.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -37456,7 +40559,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailTemplate" + "$ref": "#/components/schemas/Domain" } } } @@ -37503,8 +40606,8 @@ } } }, - "403": { - "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "402": { + "description": "The organization's plan allows no more domains (`plan_limit_reached`) (`billing_error`). Never retried: it needs a plan change or a payment.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -37524,8 +40627,8 @@ } } }, - "404": { - "description": "No template with this id or alias exists in the API key's environment (`not_found`).", + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -37588,7 +40691,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`), or another template has the alias (`template_alias_taken`).", + "description": "The body failed validation (`validation_error`), the name is not a usable domain (`invalid_domain`), it is already in use here or by another account (`domain_taken`), or The organization already has 5 domains awaiting verification (`too_many_pending_domains`). For a sub-account: it doesn't exist in the API key's environment (`subaccount_not_found`), isn't live (`subaccount_not_live`), or has 10 domains already (`too_many_subaccount_domains`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -37656,203 +40759,8 @@ } } }, - "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - }, - "delete": { - "operationId": "deleteEmailTemplate", - "tags": [ - "Email templates" - ], - "summary": "Delete an email template", - "description": "Deletes the template with its draft and every version. Emails already sent or scheduled from it keep their content; new sends naming it fail with `template_not_found`.", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The template's id or alias.", - "examples": [ - "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The template's id or alias.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], - "responses": { - "200": { - "description": "The template was deleted.", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - }, - "Coss-Version": { - "description": "The API version this response is rendered in.", - "schema": { - "type": "string", - "examples": [ - "2026-10-10" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeletedEmailTemplate" - } - } - } - }, - "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "403": { - "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "404": { - "description": "No template with this id or alias exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - }, - "Retry-After": { - "description": "Seconds to wait before retrying.", - "schema": { - "type": "integer" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "500": { - "description": "Unexpected server error (`api_error` / `internal_error`).", + "502": { + "description": "The delivery provider could not set the domain up; retry (`provider_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -37893,17 +40801,20 @@ } } } - } - } - }, - "/v1/email_templates/{id}/draft": { + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] + }, "get": { - "operationId": "getEmailTemplateDraft", + "operationId": "listDomains", "tags": [ - "Email templates" + "Domains" ], - "summary": "Retrieve a template's draft", - "description": "The draft (`version: null`): what the next publish makes sends use. `problems` lists syntax errors and undeclared variables, which keep it from being published.", + "summary": "List sending domains", + "description": "Every domain of the organization, ordered by name. Domains belong to the organization, not to one environment, so every API key of the organization sees the same domains.", "security": [ { "bearerAuth": [] @@ -37913,15 +40824,14 @@ { "schema": { "type": "string", - "description": "The template's id or alias.", - "examples": [ - "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] + "minLength": 1, + "maxLength": 256, + "description": "Only this sub-account's domains (its id or your uid)." }, - "required": true, - "description": "The template's id or alias.", - "name": "id", - "in": "path" + "required": false, + "description": "Only this sub-account's domains (its id or your uid).", + "name": "subaccount", + "in": "query" }, { "$ref": "#/components/parameters/CossVersion" @@ -37929,7 +40839,7 @@ ], "responses": { "200": { - "description": "The draft.", + "description": "The organization's domains.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -37953,7 +40863,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailTemplateVersion" + "$ref": "#/components/schemas/DomainList" } } } @@ -38021,8 +40931,8 @@ } } }, - "404": { - "description": "No template with this id or alias exists in the API key's environment (`not_found`).", + "422": { + "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38112,14 +41022,16 @@ } } } - }, - "put": { - "operationId": "updateEmailTemplateDraft", + } + }, + "/v1/domains/{id}": { + "patch": { + "operationId": "updateDomain", "tags": [ - "Email templates" + "Domains" ], - "summary": "Update a template's draft", - "description": "Replaces the draft's variables and content. Sends keep using the published version until the draft is published. Pass the `revision` you read to refuse overwriting someone else's changes. A draft with problems is saved (and reported in `problems`).", + "summary": "Update a sending domain", + "description": "Shares one of the organization's own domains with its sub-accounts (they may then send from it, through the organization's reputation), or stops sharing it.", "security": [ { "bearerAuth": [] @@ -38129,13 +41041,13 @@ { "schema": { "type": "string", - "description": "The template's id or alias.", + "description": "The domain's id.", "examples": [ - "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The template's id or alias.", + "description": "The domain's id.", "name": "id", "in": "path" }, @@ -38148,14 +41060,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateEmailTemplateDraftRequest" + "$ref": "#/components/schemas/UpdateDomainRequest" } } } }, "responses": { "200": { - "description": "The saved draft.", + "description": "The domain.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38179,7 +41091,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailTemplateVersion" + "$ref": "#/components/schemas/Domain" } } } @@ -38248,7 +41160,7 @@ } }, "404": { - "description": "No template with this id or alias exists in the API key's environment (`not_found`).", + "description": "No domain with this id exists in this organization (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38311,7 +41223,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`), or the draft changed since `revision` (`template_revision_mismatch`).", + "description": "The body failed validation (`validation_error`), or the domain is a sub-account's (`not_shareable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38401,16 +41313,14 @@ } } } - } - }, - "/v1/email_templates/{id}/publish": { - "post": { - "operationId": "publishEmailTemplate", + }, + "get": { + "operationId": "getDomain", "tags": [ - "Email templates" + "Domains" ], - "summary": "Publish a template's draft", - "description": "Copies the draft into the next version, which sends use from then on. Emails already accepted keep the content they were rendered with. A draft without changes since the last publish returns that version, so retrying with the `revision` you reviewed is safe (without it, a retry could publish edits saved in between).", + "summary": "Retrieve a sending domain", + "description": "The domain with the result of the last DNS check, so you can show which records are still missing or mismatched.", "security": [ { "bearerAuth": [] @@ -38420,13 +41330,13 @@ { "schema": { "type": "string", - "description": "The template's id or alias.", + "description": "The domain's id.", "examples": [ - "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The template's id or alias.", + "description": "The domain's id.", "name": "id", "in": "path" }, @@ -38434,19 +41344,9 @@ "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PublishEmailTemplateRequest" - } - } - } - }, "responses": { "200": { - "description": "The published version.", + "description": "The domain.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38470,13 +41370,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailTemplateVersion" + "$ref": "#/components/schemas/Domain" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38539,70 +41439,7 @@ } }, "404": { - "description": "No template with this id or alias exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The draft has problems or no content for its default locale (`template_invalid`, see `issues`), or changed since `revision` (`template_revision_mismatch`).", + "description": "No domain with this id exists in this organization (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38692,16 +41529,14 @@ } } } - } - }, - "/v1/email_templates/{id}/render": { - "post": { - "operationId": "renderEmailTemplate", + }, + "delete": { + "operationId": "deleteDomain", "tags": [ - "Email templates" + "Domains" ], - "summary": "Render a template", - "description": "Renders the draft (or a published `version`) with `variables`, exactly as a send would, and returns the subject, HTML and text: a preview, nothing is sent or stored. Without `variables` it renders the version's `sample_variables`.", + "summary": "Remove a sending domain", + "description": "Removes the domain and its provider identity. Emails already sent are unaffected, but live keys can no longer send from it and the name becomes available again.", "security": [ { "bearerAuth": [] @@ -38711,13 +41546,13 @@ { "schema": { "type": "string", - "description": "The template's id or alias.", + "description": "The domain's id.", "examples": [ - "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The template's id or alias.", + "description": "The domain's id.", "name": "id", "in": "path" }, @@ -38725,19 +41560,9 @@ "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RenderEmailTemplateRequest" - } - } - } - }, "responses": { "200": { - "description": "The rendered template.", + "description": "The domain was removed.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38761,13 +41586,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RenderedEmailTemplate" + "$ref": "#/components/schemas/DeletedDomain" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38830,7 +41655,7 @@ } }, "404": { - "description": "No template with this id or alias exists in the API key's environment (`not_found`).", + "description": "No domain with this id exists in this organization (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38850,8 +41675,8 @@ } } }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", + "422": { + "description": "The organization's single sign-on uses the domain (`domain_in_use_by_sso`): remove it from the SSO provider in the dashboard first.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38871,8 +41696,8 @@ } } }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38882,26 +41707,11 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The body failed validation (`validation_error`), the draft has problems (`template_invalid`, see `issues`), the variables don't match its declarations (`invalid_template_variables`), it has no such version (`template_version_not_found`), or it doesn't render (`template_render_failed`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] + "type": "integer" } } }, @@ -38913,8 +41723,8 @@ } } }, - "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38924,12 +41734,6 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } - }, - "Retry-After": { - "description": "Seconds to wait before retrying.", - "schema": { - "type": "integer" - } } }, "content": { @@ -38940,8 +41744,8 @@ } } }, - "500": { - "description": "Unexpected server error (`api_error` / `internal_error`).", + "502": { + "description": "The delivery provider could not remove the domain; retry (`provider_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -38985,14 +41789,14 @@ } } }, - "/v1/email_templates/{id}/versions": { - "get": { - "operationId": "listEmailTemplateVersions", + "/v1/domains/{id}/verify": { + "post": { + "operationId": "verifyDomain", "tags": [ - "Email templates" + "Domains" ], - "summary": "List a template's versions", - "description": "Published versions, newest first. Pass the last `version` as `after` to get the next page while `has_more` is true.", + "summary": "Check a domain's DNS records now", + "description": "Asks the delivery provider and DNS about the domain immediately instead of waiting for the next background check, and returns the updated domain. A `failed` domain starts verification over with fresh DKIM records, which have to be published again. Its tracking domain, if any, is checked too (and set up again if it `failed`).", "security": [ { "bearerAuth": [] @@ -39002,46 +41806,23 @@ { "schema": { "type": "string", - "description": "The template's id or alias.", + "description": "The domain's id.", "examples": [ - "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The template's id or alias.", + "description": "The domain's id.", "name": "id", "in": "path" }, - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 20, - "description": "1-20, default 10." - }, - "required": false, - "description": "1-20, default 10.", - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1, - "description": "Cursor: the `version` of the last version of the previous page." - }, - "required": false, - "description": "Cursor: the `version` of the last version of the previous page.", - "name": "after", - "in": "query" - }, { "$ref": "#/components/parameters/CossVersion" } ], "responses": { "200": { - "description": "A page of versions.", + "description": "The domain, as the check left it.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39065,7 +41846,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailTemplateVersionList" + "$ref": "#/components/schemas/Domain" } } } @@ -39134,7 +41915,7 @@ } }, "404": { - "description": "No template with this id or alias exists in the API key's environment (`not_found`).", + "description": "No domain with this id exists in this organization (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39155,7 +41936,7 @@ } }, "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "description": "The organization already has 5 domains awaiting verification, so a `failed` one cannot restart (`too_many_pending_domains`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39176,7 +41957,7 @@ } }, "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "description": "The domain was checked moments ago (`domain_recently_checked`), or too many requests with this API key (`rate_limited`). Retry after `Retry-After` seconds, or just read the domain.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39188,7 +41969,7 @@ } }, "Retry-After": { - "description": "Seconds to wait before retrying.", + "description": "Seconds to wait.", "schema": { "type": "integer" } @@ -39223,6 +42004,27 @@ } } }, + "502": { + "description": "The delivery provider could not be reached; retry (`provider_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "503": { "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { @@ -39247,14 +42049,14 @@ } } }, - "/v1/email_templates/{id}/versions/{version}": { - "get": { - "operationId": "getEmailTemplateVersion", + "/v1/domains/{id}/tracking": { + "post": { + "operationId": "createTrackingDomain", "tags": [ - "Email templates" + "Domains" ], - "summary": "Retrieve a template version", - "description": "A published version, which never changes.", + "summary": "Add a custom tracking domain", + "description": "Sets up a subdomain of the domain (e.g. `links.acme.com`) to serve open and click tracking. Publish the CNAME record in `tracking.record`; coss.com then issues its certificate and checks it in the background, giving up after 72 hours. Open pixels and click redirects of emails sent from the domain (or its subdomains without a domain of their own) use the tracking domain while it is `active`, and the default tracking host otherwise. A domain has at most one tracking domain: remove it to use another hostname.", "security": [ { "bearerAuth": [] @@ -39264,37 +42066,33 @@ { "schema": { "type": "string", - "description": "The template's id or alias.", + "description": "The domain's id.", "examples": [ - "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The template's id or alias.", + "description": "The domain's id.", "name": "id", "in": "path" }, - { - "schema": { - "type": "integer", - "minimum": 1, - "description": "A published version number.", - "examples": [ - 1 - ] - }, - "required": true, - "description": "A published version number.", - "name": "version", - "in": "path" - }, { "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateTrackingDomainRequest" + } + } + } + }, "responses": { "200": { - "description": "The version.", + "description": "The domain, with its tracking domain and the CNAME to publish.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39318,13 +42116,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailTemplateVersion" + "$ref": "#/components/schemas/Domain" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39365,6 +42163,27 @@ } } }, + "402": { + "description": "The organization's plan doesn't include custom tracking domains (`plan_feature_unavailable`) (`billing_error`). Never retried: it needs a plan change or a payment.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "403": { "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { @@ -39387,7 +42206,70 @@ } }, "404": { - "description": "No template with this id or alias exists in the API key's environment, or it has no such version (`not_found`).", + "description": "No domain with this id exists in this organization (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The body failed validation (`validation_error`), the hostname is not a subdomain of the domain it can use (`invalid_tracking_hostname`), the domain already has a tracking domain (`tracking_domain_exists`), or the hostname is already in use (`tracking_domain_taken`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39455,6 +42337,27 @@ } } }, + "502": { + "description": "The certificate provider could not set the hostname up; retry (`provider_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "503": { "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { @@ -39477,16 +42380,14 @@ } } } - } - }, - "/v1/email_templates/{id}/versions/{version}/restore": { - "post": { - "operationId": "restoreEmailTemplateVersion", + }, + "delete": { + "operationId": "deleteTrackingDomain", "tags": [ - "Email templates" + "Domains" ], - "summary": "Restore a template version", - "description": "Replaces the draft with a published version's variables and content. Publish the draft to make sends use it again.", + "summary": "Remove a custom tracking domain", + "description": "Removes the domain's tracking domain. Later emails use the default tracking host, but links and open pixels in emails already sent through the tracking domain stop working.", "security": [ { "bearerAuth": [] @@ -39496,37 +42397,23 @@ { "schema": { "type": "string", - "description": "The template's id or alias.", + "description": "The domain's id.", "examples": [ - "etpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The template's id or alias.", + "description": "The domain's id.", "name": "id", "in": "path" }, - { - "schema": { - "type": "integer", - "minimum": 1, - "description": "A published version number.", - "examples": [ - 1 - ] - }, - "required": true, - "description": "A published version number.", - "name": "version", - "in": "path" - }, { "$ref": "#/components/parameters/CossVersion" } ], "responses": { "200": { - "description": "The draft.", + "description": "The domain, without a tracking domain.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39550,7 +42437,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/EmailTemplateVersion" + "$ref": "#/components/schemas/Domain" } } } @@ -39619,7 +42506,7 @@ } }, "404": { - "description": "No template with this id or alias exists in the API key's environment (`not_found`).", + "description": "No domain with this id exists in this organization, or it has no tracking domain (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39639,8 +42526,8 @@ } } }, - "422": { - "description": "The template has no such version (`template_version_not_found`).", + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39650,6 +42537,12 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } } }, "content": { @@ -39660,8 +42553,8 @@ } } }, - "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39671,12 +42564,6 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } - }, - "Retry-After": { - "description": "Seconds to wait before retrying.", - "schema": { - "type": "integer" - } } }, "content": { @@ -39687,8 +42574,8 @@ } } }, - "500": { - "description": "Unexpected server error (`api_error` / `internal_error`).", + "502": { + "description": "The certificate provider could not remove the hostname; retry (`provider_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39732,32 +42619,50 @@ } } }, - "/v1/domains": { + "/v1/domains/{id}/receiving": { "post": { - "operationId": "createDomain", + "operationId": "createReceivingDomain", "tags": [ "Domains" ], - "summary": "Add a sending domain", - "description": "Claims the domain for the organization and returns the DNS records to publish. Domains belong to the organization, not to one environment, so every API key of the organization sees the same domains. The records are checked repeatedly in the background and verification gives up after 72 hours; until the domain is `verified`, live keys cannot send from it.", + "summary": "Receive email at a domain", + "description": "Starts receiving email at the domain itself or a subdomain (e.g. `inbound.acme.com`): email sent to any address at that hostname becomes a received email of the API key's environment (an `email.received` webhook, `GET /v1/received_emails`). Publish the MX record in `receiving.record`; coss.com checks it in the background. Using the domain itself moves all of its mail to coss.com. A domain has at most one receiving hostname: remove it to use another one.", "security": [ { "bearerAuth": [] } ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The domain's id.", + "examples": [ + "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The domain's id.", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateDomainRequest" + "$ref": "#/components/schemas/CreateReceivingDomainRequest" } } } }, "responses": { "200": { - "description": "The domain, with the DNS records to publish.", + "description": "The domain, with its receiving domain and the MX record to publish.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39828,8 +42733,8 @@ } } }, - "402": { - "description": "The organization's plan allows no more domains (`plan_limit_reached`) (`billing_error`). Never retried: it needs a plan change or a payment.", + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39849,8 +42754,8 @@ } } }, - "403": { - "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "404": { + "description": "No domain with this id exists in this organization (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39913,7 +42818,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`), the name is not a usable domain (`invalid_domain`), it is already in use here or by another account (`domain_taken`), or The organization already has 5 domains awaiting verification (`too_many_pending_domains`). For a sub-account: it doesn't exist in the API key's environment (`subaccount_not_found`), isn't live (`subaccount_not_live`), or has 10 domains already (`too_many_subaccount_domains`).", + "description": "The body failed validation (`validation_error`), the hostname is not one the domain can receive at (`invalid_receiving_hostname`), the domain already receives email (`receiving_domain_exists`), the hostname is already in use (`receiving_domain_taken`), or this deployment does not receive email (`receiving_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -39981,27 +42886,6 @@ } } }, - "502": { - "description": "The delivery provider could not set the domain up; retry (`provider_error`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "503": { "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { @@ -40023,20 +42907,15 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] + } }, - "get": { - "operationId": "listDomains", + "delete": { + "operationId": "deleteReceivingDomain", "tags": [ "Domains" ], - "summary": "List sending domains", - "description": "Every domain of the organization, ordered by name. Domains belong to the organization, not to one environment, so every API key of the organization sees the same domains.", + "summary": "Stop receiving email at a domain", + "description": "Stops receiving at the domain's receiving hostname: later mail to it is dropped (remove the MX record too). Emails already received stay until their retention ends.", "security": [ { "bearerAuth": [] @@ -40046,14 +42925,15 @@ { "schema": { "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "Only this sub-account's domains (its id or your uid)." + "description": "The domain's id.", + "examples": [ + "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] }, - "required": false, - "description": "Only this sub-account's domains (its id or your uid).", - "name": "subaccount", - "in": "query" + "required": true, + "description": "The domain's id.", + "name": "id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" @@ -40061,7 +42941,7 @@ ], "responses": { "200": { - "description": "The organization's domains.", + "description": "The domain, without a receiving domain.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -40085,7 +42965,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DomainList" + "$ref": "#/components/schemas/Domain" } } } @@ -40153,8 +43033,8 @@ } } }, - "422": { - "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", + "404": { + "description": "No domain with this id exists in this organization, or it does not receive email (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -40246,14 +43126,14 @@ } } }, - "/v1/domains/{id}": { - "patch": { - "operationId": "updateDomain", + "/v1/domains/{id}/dmarc": { + "get": { + "operationId": "getDomainDmarc", "tags": [ "Domains" ], - "summary": "Update a sending domain", - "description": "Shares one of the organization's own domains with its sub-accounts (they may then send from it, through the organization's reputation), or stops sharing it.", + "summary": "Retrieve a domain's DMARC status", + "description": "The domain's published DMARC record, where it is on the path from `p=none` to `p=reject`, the record to publish next and whether the last 14 days of aggregate reports say that is safe (`ready`, with the `checks` behind it), and a summary of those reports. Mailbox providers send DMARC aggregate reports to the domain's `report_address` once its `_dmarc` record names it (`rua=mailto:…`), usually once a day each.", "security": [ { "bearerAuth": [] @@ -40277,19 +43157,9 @@ "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateDomainRequest" - } - } - } - }, "responses": { "200": { - "description": "The domain.", + "description": "The domain's DMARC status.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -40313,13 +43183,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Domain" + "$ref": "#/components/schemas/DomainDmarc" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -40402,69 +43272,6 @@ } } }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The body failed validation (`validation_error`), or the domain is a sub-account's (`not_shareable`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -40535,14 +43342,16 @@ } } } - }, + } + }, + "/v1/domains/{id}/dmarc/reports": { "get": { - "operationId": "getDomain", + "operationId": "listDomainDmarcReports", "tags": [ "Domains" ], - "summary": "Retrieve a sending domain", - "description": "The domain with the result of the last DNS check, so you can show which records are still missing or mismatched.", + "summary": "List a domain's DMARC reports", + "description": "The aggregate reports received about the domain, newest first, without their rows (retrieve one for those). Pass the last `id` as `after` to get the next page while `has_more` is true. Mailbox providers send DMARC aggregate reports to the domain's `report_address` once its `_dmarc` record names it (`rua=mailto:…`), usually once a day each.", "security": [ { "bearerAuth": [] @@ -40562,13 +43371,36 @@ "name": "id", "in": "path" }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "1-100, default 20." + }, + "required": false, + "description": "1-100, default 20.", + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "maxLength": 64, + "description": "Cursor: the `id` of the last report of the previous page." + }, + "required": false, + "description": "Cursor: the `id` of the last report of the previous page.", + "name": "after", + "in": "query" + }, { "$ref": "#/components/parameters/CossVersion" } ], "responses": { "200": { - "description": "The domain.", + "description": "A page of DMARC reports.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -40592,7 +43424,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Domain" + "$ref": "#/components/schemas/DmarcReportList" } } } @@ -40681,6 +43513,27 @@ } } }, + "422": { + "description": "A query parameter failed validation (`validation_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -40751,14 +43604,16 @@ } } } - }, - "delete": { - "operationId": "deleteDomain", + } + }, + "/v1/domains/{id}/dmarc/reports/{report_id}": { + "get": { + "operationId": "getDomainDmarcReport", "tags": [ "Domains" ], - "summary": "Remove a sending domain", - "description": "Removes the domain and its provider identity. Emails already sent are unaffected, but live keys can no longer send from it and the name becomes available again.", + "summary": "Retrieve a DMARC report", + "description": "One aggregate report with its rows: each source IP, how many messages it sent, whether they passed DMARC (aligned DKIM or SPF) and what the receiver did with them.", "security": [ { "bearerAuth": [] @@ -40778,13 +43633,26 @@ "name": "id", "in": "path" }, + { + "schema": { + "type": "string", + "description": "The report's id.", + "examples": [ + "dmarcrep_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The report's id.", + "name": "report_id", + "in": "path" + }, { "$ref": "#/components/parameters/CossVersion" } ], "responses": { "200": { - "description": "The domain was removed.", + "description": "The report.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -40808,7 +43676,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedDomain" + "$ref": "#/components/schemas/DmarcReport" } } } @@ -40877,28 +43745,7 @@ } }, "404": { - "description": "No domain with this id exists in this organization (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The organization's single sign-on uses the domain (`domain_in_use_by_sso`): remove it from the SSO provider in the dashboard first.", + "description": "No such domain in this organization, or no such report of it (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -40966,27 +43813,6 @@ } } }, - "502": { - "description": "The delivery provider could not remove the domain; retry (`provider_error`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "503": { "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { @@ -41011,40 +43837,22 @@ } } }, - "/v1/domains/{id}/verify": { - "post": { - "operationId": "verifyDomain", + "/v1/dedicated_ips": { + "get": { + "operationId": "getDedicatedIpPool", "tags": [ - "Domains" + "Dedicated IPs" ], - "summary": "Check a domain's DNS records now", - "description": "Asks the delivery provider and DNS about the domain immediately instead of waiting for the next background check, and returns the updated domain. A `failed` domain starts verification over with fresh DKIM records, which have to be published again. Its tracking domain, if any, is checked too (and set up again if it `failed`).", + "summary": "Retrieve the organization's dedicated IPs", + "description": "The organization's dedicated IP pool (the Dedicated IPs add-on, bought on the dashboard's billing page): its status, its IPs and how much of the last week's mail they delivered. Organization-wide, like domains: every environment's key sees the same pool; only live emails go through it. Without the add-on the status is `not_enabled`.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The domain's id.", - "examples": [ - "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The domain's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], "responses": { "200": { - "description": "The domain, as the check left it.", + "description": "The organization's dedicated IPs.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -41068,7 +43876,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Domain" + "$ref": "#/components/schemas/DedicatedIpPool" } } } @@ -41136,50 +43944,8 @@ } } }, - "404": { - "description": "No domain with this id exists in this organization (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The organization already has 5 domains awaiting verification, so a `failed` one cannot restart (`too_many_pending_domains`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "429": { - "description": "The domain was checked moments ago (`domain_recently_checked`), or too many requests with this API key (`rate_limited`). Retry after `Retry-After` seconds, or just read the domain.", + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -41191,7 +43957,7 @@ } }, "Retry-After": { - "description": "Seconds to wait.", + "description": "Seconds to wait before retrying.", "schema": { "type": "integer" } @@ -41226,27 +43992,6 @@ } } }, - "502": { - "description": "The delivery provider could not be reached; retry (`provider_error`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "503": { "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { @@ -41268,53 +44013,40 @@ } } } - } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] } }, - "/v1/domains/{id}/tracking": { + "/v1/webhook_endpoints": { "post": { - "operationId": "createTrackingDomain", + "operationId": "createWebhookEndpoint", "tags": [ - "Domains" + "Webhook endpoints" ], - "summary": "Add a custom tracking domain", - "description": "Sets up a subdomain of the domain (e.g. `links.acme.com`) to serve open and click tracking. Publish the CNAME record in `tracking.record`; coss.com then issues its certificate and checks it in the background, giving up after 72 hours. Open pixels and click redirects of emails sent from the domain (or its subdomains without a domain of their own) use the tracking domain while it is `active`, and the default tracking host otherwise. A domain has at most one tracking domain: remove it to use another hostname.", + "summary": "Create a webhook endpoint", + "description": "Registers a URL that receives signed event notifications. Webhook endpoints belong to the API key's own environment: a `coss_test_…` key only ever sees sandbox endpoints, and a `coss_live_…` key only production ones. The response carries the signing secret, which is returned only here and when it is rolled: store it, and verify every delivery with it (`verifyWebhook` in the SDK).", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The domain's id.", - "examples": [ - "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The domain's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateTrackingDomainRequest" + "$ref": "#/components/schemas/CreateWebhookEndpointRequest" } } } }, "responses": { "200": { - "description": "The domain, with its tracking domain and the CNAME to publish.", + "description": "The endpoint and its signing secret.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -41338,7 +44070,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Domain" + "$ref": "#/components/schemas/WebhookEndpointWithSecret" } } } @@ -41385,27 +44117,6 @@ } } }, - "402": { - "description": "The organization's plan doesn't include custom tracking domains (`plan_feature_unavailable`) (`billing_error`). Never retried: it needs a plan change or a payment.", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "403": { "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { @@ -41427,27 +44138,6 @@ } } }, - "404": { - "description": "No domain with this id exists in this organization (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "413": { "description": "The request body is larger than 5 MB (`payload_too_large`).", "headers": { @@ -41491,7 +44181,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`), the hostname is not a subdomain of the domain it can use (`invalid_tracking_hostname`), the domain already has a tracking domain (`tracking_domain_exists`), or the hostname is already in use (`tracking_domain_taken`).", + "description": "The body failed validation (`validation_error`, including an unknown `api_version`), the URL is not a usable https:// URL (`invalid_url`), or the environment already has 10 endpoints (`too_many_endpoints`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -41559,27 +44249,6 @@ } } }, - "502": { - "description": "The certificate provider could not set the hostname up; retry (`provider_error`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "503": { "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { @@ -41601,41 +44270,28 @@ } } } - } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] }, - "delete": { - "operationId": "deleteTrackingDomain", + "get": { + "operationId": "listWebhookEndpoints", "tags": [ - "Domains" + "Webhook endpoints" ], - "summary": "Remove a custom tracking domain", - "description": "Removes the domain's tracking domain. Later emails use the default tracking host, but links and open pixels in emails already sent through the tracking domain stop working.", + "summary": "List webhook endpoints", + "description": "Every endpoint of the API key's environment, oldest first. Webhook endpoints belong to the API key's own environment: a `coss_test_…` key only ever sees sandbox endpoints, and a `coss_live_…` key only production ones.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The domain's id.", - "examples": [ - "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The domain's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], "responses": { "200": { - "description": "The domain, without a tracking domain.", + "description": "The environment's webhook endpoints.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -41659,7 +44315,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Domain" + "$ref": "#/components/schemas/WebhookEndpointList" } } } @@ -41727,27 +44383,6 @@ } } }, - "404": { - "description": "No domain with this id exists in this organization, or it has no tracking domain (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -41796,27 +44431,6 @@ } } }, - "502": { - "description": "The certificate provider could not remove the hostname; retry (`provider_error`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "503": { "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { @@ -41838,17 +44452,22 @@ } } } - } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] } }, - "/v1/domains/{id}/receiving": { - "post": { - "operationId": "createReceivingDomain", + "/v1/webhook_endpoints/{id}": { + "get": { + "operationId": "getWebhookEndpoint", "tags": [ - "Domains" + "Webhook endpoints" ], - "summary": "Receive email at a domain", - "description": "Starts receiving email at the domain itself or a subdomain (e.g. `inbound.acme.com`): email sent to any address at that hostname becomes a received email of the API key's environment (an `email.received` webhook, `GET /v1/received_emails`). Publish the MX record in `receiving.record`; coss.com checks it in the background. Using the domain itself moves all of its mail to coss.com. A domain has at most one receiving hostname: remove it to use another one.", + "summary": "Retrieve a webhook endpoint", + "description": "The endpoint without its signing secret, which is only returned when created or rolled.", "security": [ { "bearerAuth": [] @@ -41858,13 +44477,13 @@ { "schema": { "type": "string", - "description": "The domain's id.", + "description": "The webhook endpoint's id.", "examples": [ - "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" + "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The domain's id.", + "description": "The webhook endpoint's id.", "name": "id", "in": "path" }, @@ -41872,19 +44491,9 @@ "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateReceivingDomainRequest" - } - } - } - }, "responses": { "200": { - "description": "The domain, with its receiving domain and the MX record to publish.", + "description": "The webhook endpoint.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -41908,13 +44517,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Domain" + "$ref": "#/components/schemas/WebhookEndpoint" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -41977,7 +44586,7 @@ } }, "404": { - "description": "No domain with this id exists in this organization (`not_found`).", + "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -41997,8 +44606,8 @@ } } }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42008,6 +44617,12 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } } }, "content": { @@ -42018,8 +44633,8 @@ } } }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42039,8 +44654,8 @@ } } }, - "422": { - "description": "The body failed validation (`validation_error`), the hostname is not one the domain can receive at (`invalid_receiving_hostname`), the domain already receives email (`receiving_domain_exists`), the hostname is already in use (`receiving_domain_taken`), or this deployment does not receive email (`receiving_unavailable`).", + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42059,9 +44674,52 @@ } } } + } + } + }, + "patch": { + "operationId": "updateWebhookEndpoint", + "tags": [ + "Webhook endpoints" + ], + "summary": "Update a webhook endpoint", + "description": "Changes the URL, description, subscribed event types, API version or `enabled` flag. Omitted fields keep their current value, and the signing secret stays the same (see Roll a signing secret), so receivers keep verifying deliveries. Disabling an endpoint stops deliveries without losing its configuration.", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The webhook endpoint's id.", + "examples": [ + "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The webhook endpoint's id.", + "name": "id", + "in": "path" }, - "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateWebhookEndpointRequest" + } + } + } + }, + "responses": { + "200": { + "description": "The updated endpoint.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42072,23 +44730,26 @@ ] } }, - "Retry-After": { - "description": "Seconds to wait before retrying.", + "Coss-Version": { + "description": "The API version this response is rendered in.", "schema": { - "type": "integer" + "type": "string", + "examples": [ + "2026-10-10" + ] } } }, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/WebhookEndpoint" } } } }, - "500": { - "description": "Unexpected server error (`api_error` / `internal_error`).", + "400": { + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42108,8 +44769,8 @@ } } }, - "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42128,42 +44789,9 @@ } } } - } - } - }, - "delete": { - "operationId": "deleteReceivingDomain", - "tags": [ - "Domains" - ], - "summary": "Stop receiving email at a domain", - "description": "Stops receiving at the domain's receiving hostname: later mail to it is dropped (remove the MX record too). Emails already received stay until their retention ends.", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The domain's id.", - "examples": [ - "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The domain's id.", - "name": "id", - "in": "path" }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], - "responses": { - "200": { - "description": "The domain, without a receiving domain.", + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42173,27 +44801,18 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } - }, - "Coss-Version": { - "description": "The API version this response is rendered in.", - "schema": { - "type": "string", - "examples": [ - "2026-10-10" - ] - } } }, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Domain" + "$ref": "#/components/schemas/Error" } } } }, - "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "404": { + "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42213,8 +44832,8 @@ } } }, - "401": { - "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42234,8 +44853,8 @@ } } }, - "403": { - "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42255,8 +44874,8 @@ } } }, - "404": { - "description": "No domain with this id exists in this organization, or it does not receive email (`not_found`).", + "422": { + "description": "The body failed validation (`validation_error`) or the URL is not a usable https:// URL (`invalid_url`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42346,16 +44965,14 @@ } } } - } - }, - "/v1/domains/{id}/dmarc": { - "get": { - "operationId": "getDomainDmarc", + }, + "delete": { + "operationId": "deleteWebhookEndpoint", "tags": [ - "Domains" + "Webhook endpoints" ], - "summary": "Retrieve a domain's DMARC status", - "description": "The domain's published DMARC record, where it is on the path from `p=none` to `p=reject`, the record to publish next and whether the last 14 days of aggregate reports say that is safe (`ready`, with the `checks` behind it), and a summary of those reports. Mailbox providers send DMARC aggregate reports to the domain's `report_address` once its `_dmarc` record names it (`rua=mailto:…`), usually once a day each.", + "summary": "Delete a webhook endpoint", + "description": "Removes the endpoint and its delivery log. Deliveries already queued for it are dropped. To stop deliveries temporarily, set `enabled` to `false` instead.", "security": [ { "bearerAuth": [] @@ -42365,13 +44982,13 @@ { "schema": { "type": "string", - "description": "The domain's id.", + "description": "The webhook endpoint's id.", "examples": [ - "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" + "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The domain's id.", + "description": "The webhook endpoint's id.", "name": "id", "in": "path" }, @@ -42381,7 +44998,7 @@ ], "responses": { "200": { - "description": "The domain's DMARC status.", + "description": "The endpoint was deleted.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42405,7 +45022,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DomainDmarc" + "$ref": "#/components/schemas/DeletedWebhookEndpoint" } } } @@ -42474,7 +45091,7 @@ } }, "404": { - "description": "No domain with this id exists in this organization (`not_found`).", + "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42566,14 +45183,14 @@ } } }, - "/v1/domains/{id}/dmarc/reports": { - "get": { - "operationId": "listDomainDmarcReports", + "/v1/webhook_endpoints/{id}/roll_secret": { + "post": { + "operationId": "rollWebhookEndpointSecret", "tags": [ - "Domains" + "Webhook endpoints" ], - "summary": "List a domain's DMARC reports", - "description": "The aggregate reports received about the domain, newest first, without their rows (retrieve one for those). Pass the last `id` as `after` to get the next page while `has_more` is true. Mailbox providers send DMARC aggregate reports to the domain's `report_address` once its `_dmarc` record names it (`rua=mailto:…`), usually once a day each.", + "summary": "Roll a signing secret", + "description": "Replaces the endpoint's signing secret with a new one, returned in the response (the only time it is). Until `previous_secret_expires_at`, every delivery is signed with both secrets (`webhook-signature` lists two signatures), so receivers verifying with either one accept it: deploy the new secret, then let the old one expire. Rolling again in that time stops the older secret at once. Not idempotent: after a lost response, roll again.", "security": [ { "bearerAuth": [] @@ -42583,46 +45200,33 @@ { "schema": { "type": "string", - "description": "The domain's id.", + "description": "The webhook endpoint's id.", "examples": [ - "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" + "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The domain's id.", + "description": "The webhook endpoint's id.", "name": "id", "in": "path" }, - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "description": "1-100, default 20." - }, - "required": false, - "description": "1-100, default 20.", - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "maxLength": 64, - "description": "Cursor: the `id` of the last report of the previous page." - }, - "required": false, - "description": "Cursor: the `id` of the last report of the previous page.", - "name": "after", - "in": "query" - }, { "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RollWebhookEndpointSecretRequest" + } + } + } + }, "responses": { "200": { - "description": "A page of DMARC reports.", + "description": "The endpoint and its new signing secret.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42646,13 +45250,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DmarcReportList" + "$ref": "#/components/schemas/WebhookEndpointWithSecret" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42715,7 +45319,49 @@ } }, "404": { - "description": "No domain with this id exists in this organization (`not_found`).", + "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42736,7 +45382,7 @@ } }, "422": { - "description": "A query parameter failed validation (`validation_error`).", + "description": "The body failed validation (`validation_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42828,14 +45474,14 @@ } } }, - "/v1/domains/{id}/dmarc/reports/{report_id}": { - "get": { - "operationId": "getDomainDmarcReport", + "/v1/webhook_endpoints/{id}/recover": { + "post": { + "operationId": "recoverWebhookEndpoint", "tags": [ - "Domains" + "Webhook endpoints" ], - "summary": "Retrieve a DMARC report", - "description": "One aggregate report with its rows: each source IP, how many messages it sent, whether they passed DMARC (aligned DKIM or SPF) and what the receiver did with them.", + "summary": "Recover failed deliveries", + "description": "Queues the endpoint's deliveries that `failed` since `since` for one more attempt each, oldest first, spread over the next minute, e.g. after fixing a receiver that was down. At most 1000 per call: while `has_more` is `true`, call again with the same `since`. The endpoint must be enabled.", "security": [ { "bearerAuth": [] @@ -42845,36 +45491,33 @@ { "schema": { "type": "string", - "description": "The domain's id.", + "description": "The webhook endpoint's id.", "examples": [ - "dom_01k7c8m4q2f3e9v6t5r1n0p8yz" + "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The domain's id.", + "description": "The webhook endpoint's id.", "name": "id", "in": "path" }, - { - "schema": { - "type": "string", - "description": "The report's id.", - "examples": [ - "dmarcrep_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The report's id.", - "name": "report_id", - "in": "path" - }, { "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RecoverWebhookEndpointRequest" + } + } + } + }, "responses": { "200": { - "description": "The report.", + "description": "How many deliveries were queued.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42898,13 +45541,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DmarcReport" + "$ref": "#/components/schemas/WebhookEndpointRecovery" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -42967,76 +45610,7 @@ } }, "404": { - "description": "No such domain in this organization, or no such report of it (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - }, - "Retry-After": { - "description": "Seconds to wait before retrying.", - "schema": { - "type": "integer" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "500": { - "description": "Unexpected server error (`api_error` / `internal_error`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43055,56 +45629,9 @@ } } } - } - } - } - }, - "/v1/dedicated_ips": { - "get": { - "operationId": "getDedicatedIpPool", - "tags": [ - "Dedicated IPs" - ], - "summary": "Retrieve the organization's dedicated IPs", - "description": "The organization's dedicated IP pool (the Dedicated IPs add-on, bought on the dashboard's billing page): its status, its IPs and how much of the last week's mail they delivered. Organization-wide, like domains: every environment's key sees the same pool; only live emails go through it. Without the add-on the status is `not_enabled`.", - "security": [ - { - "bearerAuth": [] - } - ], - "responses": { - "200": { - "description": "The organization's dedicated IPs.", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - }, - "Coss-Version": { - "description": "The API version this response is rendered in.", - "schema": { - "type": "string", - "examples": [ - "2026-10-10" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DedicatedIpPool" - } - } - } }, - "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43124,8 +45651,8 @@ } } }, - "401": { - "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43145,8 +45672,8 @@ } } }, - "403": { - "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "422": { + "description": "The body failed validation (`validation_error`), or the endpoint is disabled (`endpoint_disabled`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43235,40 +45762,90 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] + } } }, - "/v1/webhook_endpoints": { - "post": { - "operationId": "createWebhookEndpoint", + "/v1/webhook_endpoints/{id}/deliveries": { + "get": { + "operationId": "listWebhookDeliveries", "tags": [ "Webhook endpoints" ], - "summary": "Create a webhook endpoint", - "description": "Registers a URL that receives signed event notifications. Webhook endpoints belong to the API key's own environment: a `coss_test_…` key only ever sees sandbox endpoints, and a `coss_live_…` key only production ones. The response carries the signing secret, which is returned only here and when it is rolled: store it, and verify every delivery with it (`verifyWebhook` in the SDK).", + "summary": "List an endpoint's deliveries", + "description": "The endpoint's delivery log, newest first: one delivery per event sent to it, with every HTTP attempt and the payload as sent. Pass the last `id` as `after` to get the next page while `has_more` is true. Deleting the endpoint deletes its log.", "security": [ { "bearerAuth": [] } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateWebhookEndpointRequest" - } - } + "parameters": [ + { + "schema": { + "type": "string", + "description": "The webhook endpoint's id.", + "examples": [ + "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The webhook endpoint's id.", + "name": "id", + "in": "path" + }, + { + "schema": { + "type": "string", + "enum": [ + "pending", + "succeeded", + "failed" + ], + "description": "Only deliveries with this status." + }, + "required": false, + "description": "Only deliveries with this status.", + "name": "status", + "in": "query" + }, + { + "schema": { + "type": "string", + "description": "Only the delivery of this event." + }, + "required": false, + "description": "Only the delivery of this event.", + "name": "event_id", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "1-100, default 50." + }, + "required": false, + "description": "1-100, default 50.", + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "description": "Cursor: the `id` of the last delivery of the previous page." + }, + "required": false, + "description": "Cursor: the `id` of the last delivery of the previous page.", + "name": "after", + "in": "query" + }, + { + "$ref": "#/components/parameters/CossVersion" } - }, + ], "responses": { "200": { - "description": "The endpoint and its signing secret.", + "description": "A page of deliveries.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43292,13 +45869,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WebhookEndpointWithSecret" + "$ref": "#/components/schemas/WebhookDeliveryList" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43360,29 +45937,8 @@ } } }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "404": { + "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43403,7 +45959,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`, including an unknown `api_version`), the URL is not a usable https:// URL (`invalid_url`), or the environment already has 10 endpoints (`too_many_endpoints`).", + "description": "A query parameter failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43492,28 +46048,56 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] - }, + } + } + }, + "/v1/webhook_endpoints/{id}/deliveries/{delivery_id}": { "get": { - "operationId": "listWebhookEndpoints", + "operationId": "getWebhookDelivery", "tags": [ "Webhook endpoints" ], - "summary": "List webhook endpoints", - "description": "Every endpoint of the API key's environment, oldest first. Webhook endpoints belong to the API key's own environment: a `coss_test_…` key only ever sees sandbox endpoints, and a `coss_live_…` key only production ones.", + "summary": "Retrieve a delivery", + "description": "One delivery of the endpoint, with every HTTP attempt and the payload as sent.", "security": [ { "bearerAuth": [] } ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The webhook endpoint's id.", + "examples": [ + "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The webhook endpoint's id.", + "name": "id", + "in": "path" + }, + { + "schema": { + "type": "string", + "description": "The delivery's id.", + "examples": [ + "whdel_01k7c8n2b5d7f9h1k3m5p7r9tv" + ] + }, + "required": true, + "description": "The delivery's id.", + "name": "delivery_id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], "responses": { "200": { - "description": "The environment's webhook endpoints.", + "description": "The delivery.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43537,7 +46121,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WebhookEndpointList" + "$ref": "#/components/schemas/WebhookDelivery" } } } @@ -43605,6 +46189,27 @@ } } }, + "404": { + "description": "No webhook endpoint with this id exists in the API key's environment, or the endpoint has no delivery with this id (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -43674,22 +46279,17 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] + } } }, - "/v1/webhook_endpoints/{id}": { - "get": { - "operationId": "getWebhookEndpoint", + "/v1/webhook_endpoints/{id}/deliveries/{delivery_id}/retry": { + "post": { + "operationId": "retryWebhookDelivery", "tags": [ "Webhook endpoints" ], - "summary": "Retrieve a webhook endpoint", - "description": "The endpoint without its signing secret, which is only returned when created or rolled.", + "summary": "Retry a delivery", + "description": "Queues a finished delivery (`succeeded` or `failed`) for one more attempt, made within seconds, signed with the endpoint's current secret and sent to its current URL. A delivery that is still `pending` is returned unchanged: it is already scheduled for `next_attempt_at` (automatic retries stop after 8 attempts).", "security": [ { "bearerAuth": [] @@ -43709,13 +46309,26 @@ "name": "id", "in": "path" }, + { + "schema": { + "type": "string", + "description": "The delivery's id.", + "examples": [ + "whdel_01k7c8n2b5d7f9h1k3m5p7r9tv" + ] + }, + "required": true, + "description": "The delivery's id.", + "name": "delivery_id", + "in": "path" + }, { "$ref": "#/components/parameters/CossVersion" } ], "responses": { "200": { - "description": "The webhook endpoint.", + "description": "The delivery, now `pending`.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43739,7 +46352,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WebhookEndpoint" + "$ref": "#/components/schemas/WebhookDelivery" } } } @@ -43808,7 +46421,7 @@ } }, "404": { - "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", + "description": "No webhook endpoint with this id exists in the API key's environment, or the endpoint has no delivery with this id (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43898,50 +46511,34 @@ } } } - }, - "patch": { - "operationId": "updateWebhookEndpoint", + } + }, + "/v1/webhook_listeners": { + "post": { + "operationId": "createWebhookListener", "tags": [ "Webhook endpoints" ], - "summary": "Update a webhook endpoint", - "description": "Changes the URL, description, subscribed event types, API version or `enabled` flag. Omitted fields keep their current value, and the signing secret stays the same (see Roll a signing secret), so receivers keep verifying deliveries. Disabling an endpoint stops deliveries without losing its configuration.", + "summary": "Open a webhook listener", + "description": "Listeners are how `coss listen` forwards events to a local server: coss.com can't reach `localhost`, so the CLI pulls them. They belong to the API key's environment, receive events created after they open, and don't count toward the plan's webhook endpoints. A listener closes when it is deleted or after 10 minutes without a poll; an environment has at most 5 open at once. Events reach it unsigned: the CLI signs what it forwards with its own secret.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The webhook endpoint's id.", - "examples": [ - "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The webhook endpoint's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateWebhookEndpointRequest" + "$ref": "#/components/schemas/CreateWebhookListenerRequest" } } } }, "responses": { "200": { - "description": "The updated endpoint.", + "description": "The listener.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -43965,7 +46562,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WebhookEndpoint" + "$ref": "#/components/schemas/WebhookListener" } } } @@ -44033,27 +46630,6 @@ } } }, - "404": { - "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "413": { "description": "The request body is larger than 5 MB (`payload_too_large`).", "headers": { @@ -44097,7 +46673,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`) or the URL is not a usable https:// URL (`invalid_url`).", + "description": "The body failed validation (`validation_error`, including an unknown `api_version`), or the environment already has 5 open listeners (`too_many_listeners`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -44186,15 +46762,22 @@ } } } - } - }, - "delete": { - "operationId": "deleteWebhookEndpoint", + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] + } + }, + "/v1/webhook_listeners/{id}/poll": { + "post": { + "operationId": "pollWebhookListener", "tags": [ "Webhook endpoints" ], - "summary": "Delete a webhook endpoint", - "description": "Removes the endpoint and its delivery log. Deliveries already queued for it are dropped. To stop deliveries temporarily, set `enabled` to `false` instead.", + "summary": "Poll a webhook listener", + "description": "Acknowledges deliveries handed out earlier, keeps the listener open for another 10 minutes, and waits up to `wait_ms` (at most 25 s) for events. Deliveries come oldest first; one not acknowledged within two minutes is handed out again (with the same `event_id`). The answer may come early, with no deliveries, when the API restarts: poll again. Polls are not request-logged; each acknowledgement is logged as a `webhook.forward` line.", "security": [ { "bearerAuth": [] @@ -44204,13 +46787,13 @@ { "schema": { "type": "string", - "description": "The webhook endpoint's id.", + "description": "The webhook listener's id.", "examples": [ - "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" + "whlis_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The webhook endpoint's id.", + "description": "The webhook listener's id.", "name": "id", "in": "path" }, @@ -44218,9 +46801,19 @@ "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PollWebhookListenerRequest" + } + } + } + }, "responses": { "200": { - "description": "The endpoint was deleted.", + "description": "Deliveries to forward (possibly none).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -44244,13 +46837,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedWebhookEndpoint" + "$ref": "#/components/schemas/WebhookListenerPoll" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -44313,7 +46906,70 @@ } }, "404": { - "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", + "description": "No open webhook listener with this id exists in the API key's environment: it was closed, or expired after 10 minutes without a poll (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The body failed validation (`validation_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -44405,14 +47061,14 @@ } } }, - "/v1/webhook_endpoints/{id}/roll_secret": { - "post": { - "operationId": "rollWebhookEndpointSecret", + "/v1/webhook_listeners/{id}": { + "delete": { + "operationId": "deleteWebhookListener", "tags": [ "Webhook endpoints" ], - "summary": "Roll a signing secret", - "description": "Replaces the endpoint's signing secret with a new one, returned in the response (the only time it is). Until `previous_secret_expires_at`, every delivery is signed with both secrets (`webhook-signature` lists two signatures), so receivers verifying with either one accept it: deploy the new secret, then let the old one expire. Rolling again in that time stops the older secret at once. Not idempotent: after a lost response, roll again.", + "summary": "Close a webhook listener", + "description": "Closes the listener: it receives nothing more, and deliveries it was still holding are dropped. `coss listen` closes its listener when it exits.", "security": [ { "bearerAuth": [] @@ -44422,13 +47078,13 @@ { "schema": { "type": "string", - "description": "The webhook endpoint's id.", + "description": "The webhook listener's id.", "examples": [ - "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" + "whlis_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The webhook endpoint's id.", + "description": "The webhook listener's id.", "name": "id", "in": "path" }, @@ -44436,19 +47092,9 @@ "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RollWebhookEndpointSecretRequest" - } - } - } - }, "responses": { "200": { - "description": "The endpoint and its new signing secret.", + "description": "The listener was closed.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -44472,13 +47118,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WebhookEndpointWithSecret" + "$ref": "#/components/schemas/DeletedWebhookListener" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -44541,70 +47187,7 @@ } }, "404": { - "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The body failed validation (`validation_error`).", + "description": "No open webhook listener with this id exists in the API key's environment: it was closed, or expired after 10 minutes without a poll (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -44696,50 +47279,32 @@ } } }, - "/v1/webhook_endpoints/{id}/recover": { + "/v1/webhook_events/test": { "post": { - "operationId": "recoverWebhookEndpoint", + "operationId": "createTestWebhookEvent", "tags": [ "Webhook endpoints" ], - "summary": "Recover failed deliveries", - "description": "Queues the endpoint's deliveries that `failed` since `since` for one more attempt each, oldest first, spread over the next minute, e.g. after fixing a receiver that was down. At most 1000 per call: while `has_more` is `true`, call again with the same `since`. The endpoint must be enabled.", + "summary": "Send a test event", + "description": "Sends a sample event of a type to the environment's enabled endpoints subscribed to it and its open listeners (`coss listen`), exactly as a real one is sent: same body, signature, retries and log lines. `coss trigger` calls it. Sandbox environments only. The ids in the sample are made up (pass real ones in `data` for a handler that looks them up), and nothing marks the event as a test: your handler takes it like the real thing. When nothing is subscribed, the event goes nowhere and isn't kept.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The webhook endpoint's id.", - "examples": [ - "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The webhook endpoint's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RecoverWebhookEndpointRequest" + "$ref": "#/components/schemas/CreateTestWebhookEventRequest" } } } }, "responses": { "200": { - "description": "How many deliveries were queued.", + "description": "The event that was sent, and to how many receivers.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -44763,7 +47328,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WebhookEndpointRecovery" + "$ref": "#/components/schemas/WebhookTestEvent" } } } @@ -44811,28 +47376,7 @@ } }, "403": { - "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "404": { - "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", + "description": "The API key lacks the `webhook:create` permission, its organization is suspended, or it belongs to a live environment (`sandbox_only`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -44895,7 +47439,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`), or the endpoint is disabled (`endpoint_disabled`).", + "description": "The body failed validation (`validation_error`), the type only reaches live environments (`live_only_event_type`: `domain.*`, `account.*`, `billing.*`), or `data` doesn't fit the type (`invalid_test_event`, with `issues`; unknown fields included).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -44984,90 +47528,40 @@ } } } - } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] } }, - "/v1/webhook_endpoints/{id}/deliveries": { - "get": { - "operationId": "listWebhookDeliveries", + "/v1/suppressions": { + "post": { + "operationId": "createSuppression", "tags": [ - "Webhook endpoints" + "Suppressions" ], - "summary": "List an endpoint's deliveries", - "description": "The endpoint's delivery log, newest first: one delivery per event sent to it, with every HTTP attempt and the payload as sent. Pass the last `id` as `after` to get the next page while `has_more` is true. Deleting the endpoint deletes its log.", + "summary": "Add an address to the suppression list", + "description": "Suppresses an address in the API key's environment: later sends skip it, either for every email (`scope: \"*\"`, the default) or only for emails with the given `category` (e.g. to back an unsubscribe link). Adding an address that is already suppressed with the same scope returns the existing entry with status 200.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The webhook endpoint's id.", - "examples": [ - "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The webhook endpoint's id.", - "name": "id", - "in": "path" - }, - { - "schema": { - "type": "string", - "enum": [ - "pending", - "succeeded", - "failed" - ], - "description": "Only deliveries with this status." - }, - "required": false, - "description": "Only deliveries with this status.", - "name": "status", - "in": "query" - }, - { - "schema": { - "type": "string", - "description": "Only the delivery of this event." - }, - "required": false, - "description": "Only the delivery of this event.", - "name": "event_id", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "description": "1-100, default 50." - }, - "required": false, - "description": "1-100, default 50.", - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "description": "Cursor: the `id` of the last delivery of the previous page." - }, - "required": false, - "description": "Cursor: the `id` of the last delivery of the previous page.", - "name": "after", - "in": "query" - }, - { - "$ref": "#/components/parameters/CossVersion" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSuppressionRequest" + } + } } - ], + }, "responses": { "200": { - "description": "A page of deliveries.", + "description": "The address already had an entry with this scope.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -45091,13 +47585,43 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WebhookDeliveryList" + "$ref": "#/components/schemas/Suppression" + } + } + } + }, + "201": { + "description": "The new entry.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Suppression" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -45160,7 +47684,49 @@ } }, "404": { - "description": "No webhook endpoint with this id exists in the API key's environment (`not_found`).", + "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -45181,7 +47747,7 @@ } }, "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "description": "The body failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -45270,17 +47836,20 @@ } } } - } - } - }, - "/v1/webhook_endpoints/{id}/deliveries/{delivery_id}": { + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] + }, "get": { - "operationId": "getWebhookDelivery", + "operationId": "listSuppressions", "tags": [ - "Webhook endpoints" + "Suppressions" ], - "summary": "Retrieve a delivery", - "description": "One delivery of the endpoint, with every HTTP attempt and the payload as sent.", + "summary": "List suppressed addresses", + "description": "The suppression list of the API key's environment, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", "security": [ { "bearerAuth": [] @@ -45290,28 +47859,76 @@ { "schema": { "type": "string", - "description": "The webhook endpoint's id.", + "minLength": 1, + "maxLength": 256, + "description": "List a sub-account's own list (its id or your uid) instead of the environment's.", "examples": [ - "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" + "user_8812" ] }, - "required": true, - "description": "The webhook endpoint's id.", - "name": "id", - "in": "path" + "required": false, + "description": "List a sub-account's own list (its id or your uid) instead of the environment's.", + "name": "subaccount", + "in": "query" }, { "schema": { "type": "string", - "description": "The delivery's id.", - "examples": [ - "whdel_01k7c8n2b5d7f9h1k3m5p7r9tv" - ] + "description": "Only entries for this address." }, - "required": true, - "description": "The delivery's id.", - "name": "delivery_id", - "in": "path" + "required": false, + "description": "Only entries for this address.", + "name": "address", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": [ + "*" + ] + }, + { + "type": "string", + "enum": [ + "stream:marketing" + ] + }, + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,256}$" + } + ], + "description": "Only entries with this scope." + }, + "required": false, + "description": "Only entries with this scope.", + "name": "scope", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "1-100, default 50." + }, + "required": false, + "description": "1-100, default 50.", + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "description": "Cursor: the `id` of the last entry of the previous page." + }, + "required": false, + "description": "Cursor: the `id` of the last entry of the previous page.", + "name": "after", + "in": "query" }, { "$ref": "#/components/parameters/CossVersion" @@ -45319,7 +47936,7 @@ ], "responses": { "200": { - "description": "The delivery.", + "description": "A page of entries.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -45343,7 +47960,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WebhookDelivery" + "$ref": "#/components/schemas/SuppressionList" } } } @@ -45412,7 +48029,28 @@ } }, "404": { - "description": "No webhook endpoint with this id exists in the API key's environment, or the endpoint has no delivery with this id (`not_found`).", + "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "A query parameter failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -45504,14 +48142,14 @@ } } }, - "/v1/webhook_endpoints/{id}/deliveries/{delivery_id}/retry": { - "post": { - "operationId": "retryWebhookDelivery", + "/v1/suppressions/check": { + "get": { + "operationId": "checkSuppression", "tags": [ - "Webhook endpoints" + "Suppressions" ], - "summary": "Retry a delivery", - "description": "Queues a finished delivery (`succeeded` or `failed`) for one more attempt, made within seconds, signed with the endpoint's current secret and sent to its current URL. A delivery that is still `pending` is returned unchanged: it is already scheduled for `next_attempt_at` (automatic retries stop after 8 attempts).", + "summary": "Check whether an address is suppressed", + "description": "Whether a send to `address` (with `category`, if given) would skip it, and the entries that match: those with scope `*` and, with a `category`, those for that category.", "security": [ { "bearerAuth": [] @@ -45521,28 +48159,52 @@ { "schema": { "type": "string", - "description": "The webhook endpoint's id.", + "description": "The address to check.", "examples": [ - "whep_01k7c8m4q2f3e9v6t5r1n0p8yz" + "user@example.com" ] }, "required": true, - "description": "The webhook endpoint's id.", - "name": "id", - "in": "path" + "description": "The address to check.", + "name": "address", + "in": "query" }, { "schema": { "type": "string", - "description": "The delivery's id.", - "examples": [ - "whdel_01k7c8n2b5d7f9h1k3m5p7r9tv" - ] + "pattern": "^[A-Za-z0-9_-]{1,256}$", + "description": "The category of the email you plan to send. Without it, only `*` entries count." }, - "required": true, - "description": "The delivery's id.", - "name": "delivery_id", - "in": "path" + "required": false, + "description": "The category of the email you plan to send. Without it, only `*` entries count.", + "name": "category", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "transactional", + "marketing" + ], + "description": "The stream of the email you plan to send (default `transactional`). `marketing` also counts `stream:marketing` entries." + }, + "required": false, + "description": "The stream of the email you plan to send (default `transactional`). `marketing` also counts `stream:marketing` entries.", + "name": "stream", + "in": "query" + }, + { + "schema": { + "type": "string", + "minLength": 1, + "maxLength": 256, + "description": "The sub-account you plan to send for (its id or your uid): its own entries count too." + }, + "required": false, + "description": "The sub-account you plan to send for (its id or your uid): its own entries count too.", + "name": "subaccount", + "in": "query" }, { "$ref": "#/components/parameters/CossVersion" @@ -45550,7 +48212,7 @@ ], "responses": { "200": { - "description": "The delivery, now `pending`.", + "description": "The result.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -45574,7 +48236,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WebhookDelivery" + "$ref": "#/components/schemas/SuppressionCheck" } } } @@ -45643,7 +48305,28 @@ } }, "404": { - "description": "No webhook endpoint with this id exists in the API key's environment, or the endpoint has no delivery with this id (`not_found`).", + "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "A query parameter failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -45735,14 +48418,14 @@ } } }, - "/v1/webhook_listeners": { + "/v1/suppressions/import": { "post": { - "operationId": "createWebhookListener", + "operationId": "importSuppressions", "tags": [ - "Webhook endpoints" + "Suppressions" ], - "summary": "Open a webhook listener", - "description": "Listeners are how `coss listen` forwards events to a local server: coss.com can't reach `localhost`, so the CLI pulls them. They belong to the API key's environment, receive events created after they open, and don't count toward the plan's webhook endpoints. A listener closes when it is deleted or after 10 minutes without a poll; an environment has at most 5 open at once. Events reach it unsigned: the CLI signs what it forwards with its own secret.", + "summary": "Import suppressions in bulk", + "description": "Adds up to 1000 entries at once, with reason `import`. Each entry is validated on its own: invalid ones are skipped and listed in `invalid`, entries already on the list are left unchanged and counted in `existing`. Importing again is safe.", "security": [ { "bearerAuth": [] @@ -45753,14 +48436,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateWebhookListenerRequest" + "$ref": "#/components/schemas/ImportSuppressionsRequest" } } } }, "responses": { "200": { - "description": "The listener.", + "description": "What the import did.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -45784,7 +48467,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WebhookListener" + "$ref": "#/components/schemas/SuppressionImport" } } } @@ -45852,6 +48535,27 @@ } } }, + "404": { + "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "413": { "description": "The request body is larger than 5 MB (`payload_too_large`).", "headers": { @@ -45895,7 +48599,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`, including an unknown `api_version`), or the environment already has 5 open listeners (`too_many_listeners`).", + "description": "The body is not a list of 1-1000 `{ address, scope? }` objects (`validation_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -45992,14 +48696,14 @@ ] } }, - "/v1/webhook_listeners/{id}/poll": { - "post": { - "operationId": "pollWebhookListener", + "/v1/suppressions/export": { + "get": { + "operationId": "exportSuppressions", "tags": [ - "Webhook endpoints" + "Suppressions" ], - "summary": "Poll a webhook listener", - "description": "Acknowledges deliveries handed out earlier, keeps the listener open for another 10 minutes, and waits up to `wait_ms` (at most 25 s) for events. Deliveries come oldest first; one not acknowledged within two minutes is handed out again (with the same `event_id`). The answer may come early, with no deliveries, when the API restarts: poll again. Polls are not request-logged; each acknowledgement is logged as a `webhook.forward` line.", + "summary": "Export the suppression list as CSV", + "description": "The whole suppression list of the API key's environment (optionally filtered), oldest first, as CSV with the columns `address,scope,reason,created_at,email_id,id`. The file can be imported again as is. Values a spreadsheet would run as a formula are prefixed with `'`.", "security": [ { "bearerAuth": [] @@ -46009,33 +48713,72 @@ { "schema": { "type": "string", - "description": "The webhook listener's id.", + "minLength": 1, + "maxLength": 256, + "description": "Export a sub-account's own list (its id or your uid) instead of the environment's.", "examples": [ - "whlis_01k7c8m4q2f3e9v6t5r1n0p8yz" + "user_8812" ] }, - "required": true, - "description": "The webhook listener's id.", - "name": "id", - "in": "path" + "required": false, + "description": "Export a sub-account's own list (its id or your uid) instead of the environment's.", + "name": "subaccount", + "in": "query" + }, + { + "schema": { + "anyOf": [ + { + "type": "string", + "enum": [ + "*" + ] + }, + { + "type": "string", + "enum": [ + "stream:marketing" + ] + }, + { + "type": "string", + "pattern": "^[A-Za-z0-9_-]{1,256}$" + } + ], + "description": "Only entries with this scope." + }, + "required": false, + "description": "Only entries with this scope.", + "name": "scope", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "bounce", + "complaint", + "manual", + "import", + "unsubscribe" + ], + "description": "Only entries with this reason.", + "examples": [ + "bounce" + ] + }, + "required": false, + "description": "Only entries with this reason.", + "name": "reason", + "in": "query" }, { "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/PollWebhookListenerRequest" - } - } - } - }, "responses": { "200": { - "description": "Deliveries to forward (possibly none).", + "description": "The CSV file.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46057,15 +48800,15 @@ } }, "content": { - "application/json": { + "text/csv": { "schema": { - "$ref": "#/components/schemas/WebhookListenerPoll" + "type": "string" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46128,49 +48871,7 @@ } }, "404": { - "description": "No open webhook listener with this id exists in the API key's environment: it was closed, or expired after 10 minutes without a poll (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46191,7 +48892,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`).", + "description": "A query parameter failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46283,14 +48984,13 @@ } } }, - "/v1/webhook_listeners/{id}": { - "delete": { - "operationId": "deleteWebhookListener", + "/v1/suppressions/{id}": { + "get": { + "operationId": "getSuppression", "tags": [ - "Webhook endpoints" + "Suppressions" ], - "summary": "Close a webhook listener", - "description": "Closes the listener: it receives nothing more, and deliveries it was still holding are dropped. `coss listen` closes its listener when it exits.", + "summary": "Retrieve a suppression", "security": [ { "bearerAuth": [] @@ -46300,13 +49000,13 @@ { "schema": { "type": "string", - "description": "The webhook listener's id.", + "description": "The suppression's id.", "examples": [ - "whlis_01k7c8m4q2f3e9v6t5r1n0p8yz" + "sup_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The webhook listener's id.", + "description": "The suppression's id.", "name": "id", "in": "path" }, @@ -46316,7 +49016,7 @@ ], "responses": { "200": { - "description": "The listener was closed.", + "description": "The entry.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46340,7 +49040,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedWebhookListener" + "$ref": "#/components/schemas/Suppression" } } } @@ -46409,7 +49109,7 @@ } }, "404": { - "description": "No open webhook listener with this id exists in the API key's environment: it was closed, or expired after 10 minutes without a poll (`not_found`).", + "description": "No suppression with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46499,34 +49199,40 @@ } } } - } - }, - "/v1/webhook_events/test": { - "post": { - "operationId": "createTestWebhookEvent", + }, + "delete": { + "operationId": "deleteSuppression", "tags": [ - "Webhook endpoints" + "Suppressions" ], - "summary": "Send a test event", - "description": "Sends a sample event of a type to the environment's enabled endpoints subscribed to it and its open listeners (`coss listen`), exactly as a real one is sent: same body, signature, retries and log lines. `coss trigger` calls it. Sandbox environments only. The ids in the sample are made up (pass real ones in `data` for a handler that looks them up), and nothing marks the event as a test: your handler takes it like the real thing. When nothing is subscribed, the event goes nowhere and isn't kept.", + "summary": "Remove a suppression", + "description": "Removes the entry, so later sends reach the address again (unless another entry still matches). Entries added for bounces and complaints can be removed too.", "security": [ { "bearerAuth": [] } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateTestWebhookEventRequest" - } - } + "parameters": [ + { + "schema": { + "type": "string", + "description": "The suppression's id.", + "examples": [ + "sup_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The suppression's id.", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" } - }, + ], "responses": { "200": { - "description": "The event that was sent, and to how many receivers.", + "description": "The entry was removed.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46550,13 +49256,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/WebhookTestEvent" + "$ref": "#/components/schemas/DeletedSuppression" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46598,49 +49304,7 @@ } }, "403": { - "description": "The API key lacks the `webhook:create` permission, its organization is suspended, or it belongs to a live environment (`sandbox_only`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46660,8 +49324,8 @@ } } }, - "422": { - "description": "The body failed validation (`validation_error`), the type only reaches live environments (`live_only_event_type`: `domain.*`, `account.*`, `billing.*`), or `data` doesn't fit the type (`invalid_test_event`, with `issues`; unknown fields included).", + "404": { + "description": "No suppression with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46750,22 +49414,17 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] + } } }, - "/v1/suppressions": { + "/v1/subaccounts": { "post": { - "operationId": "createSuppression", + "operationId": "createSubaccount", "tags": [ - "Suppressions" + "Sub-accounts" ], - "summary": "Add an address to the suppression list", - "description": "Suppresses an address in the API key's environment: later sends skip it, either for every email (`scope: \"*\"`, the default) or only for emails with the given `category` (e.g. to back an unsubscribe link). Adding an address that is already suppressed with the same scope returns the existing entry with status 200.", + "summary": "Create a sub-account", + "description": "Creates a sub-account: one of your users, who gets their own domains, suppressions, quotas and reputation. Give it a `uid` (e.g. your user's id) to address it by in every path and send. Sub-accounts belong to the API key's own environment: a `coss_test_…` key only ever sees sandbox ones, a `coss_live_…` key only production ones.", "security": [ { "bearerAuth": [] @@ -46776,44 +49435,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateSuppressionRequest" + "$ref": "#/components/schemas/CreateSubaccountRequest" } } } }, "responses": { "200": { - "description": "The address already had an entry with this scope.", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - }, - "Coss-Version": { - "description": "The API version this response is rendered in.", - "schema": { - "type": "string", - "examples": [ - "2026-10-10" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Suppression" - } - } - } - }, - "201": { - "description": "The new entry.", + "description": "The sub-account.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46837,7 +49466,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Suppression" + "$ref": "#/components/schemas/Subaccount" } } } @@ -46884,8 +49513,8 @@ } } }, - "403": { - "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "402": { + "description": "Live sub-accounts need a plan with sub-accounts (`plan_feature_unavailable`), up to its limit (`plan_limit_reached`). (`billing_error`). Never retried: it needs a plan change or a payment.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46905,8 +49534,8 @@ } } }, - "404": { - "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -46969,7 +49598,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`, see `issues`).", + "description": "The body failed validation (`validation_error`), the `uid` is taken (`uid_taken`), the quotas don't fit together (`invalid_quotas`), or the sandbox environment has the most sub-accounts it can (100: `too_many_subaccounts`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47066,70 +49695,18 @@ ] }, "get": { - "operationId": "listSuppressions", + "operationId": "listSubaccounts", "tags": [ - "Suppressions" + "Sub-accounts" ], - "summary": "List suppressed addresses", - "description": "The suppression list of the API key's environment, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", + "summary": "List sub-accounts", + "description": "The environment's sub-accounts, newest first. Sub-accounts belong to the API key's own environment: a `coss_test_…` key only ever sees sandbox ones, a `coss_live_…` key only production ones.", "security": [ { "bearerAuth": [] } ], "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "List a sub-account's own list (its id or your uid) instead of the environment's.", - "examples": [ - "user_8812" - ] - }, - "required": false, - "description": "List a sub-account's own list (its id or your uid) instead of the environment's.", - "name": "subaccount", - "in": "query" - }, - { - "schema": { - "type": "string", - "description": "Only entries for this address." - }, - "required": false, - "description": "Only entries for this address.", - "name": "address", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "*" - ] - }, - { - "type": "string", - "enum": [ - "stream:marketing" - ] - }, - { - "type": "string", - "pattern": "^[A-Za-z0-9_-]{1,256}$" - } - ], - "description": "Only entries with this scope." - }, - "required": false, - "description": "Only entries with this scope.", - "name": "scope", - "in": "query" - }, { "schema": { "type": "integer", @@ -47145,10 +49722,13 @@ { "schema": { "type": "string", - "description": "Cursor: the `id` of the last entry of the previous page." + "description": "The last `id` of the previous page.", + "examples": [ + "sub_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] }, "required": false, - "description": "Cursor: the `id` of the last entry of the previous page.", + "description": "The last `id` of the previous page.", "name": "after", "in": "query" }, @@ -47158,7 +49738,7 @@ ], "responses": { "200": { - "description": "A page of entries.", + "description": "A page of sub-accounts.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47182,7 +49762,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SuppressionList" + "$ref": "#/components/schemas/SubaccountList" } } } @@ -47250,8 +49830,8 @@ } } }, - "404": { - "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47261,6 +49841,12 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } } }, "content": { @@ -47271,8 +49857,178 @@ } } }, - "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + } + }, + "/v1/subaccounts/{subaccount}": { + "get": { + "operationId": "getSubaccount", + "tags": [ + "Sub-accounts" + ], + "summary": "Retrieve a sub-account", + "description": "A sub-account of the API key's environment, by its id or uid, with its quotas and reputation.", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", + "examples": [ + "user_8812" + ] + }, + "required": true, + "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", + "name": "subaccount", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "responses": { + "200": { + "description": "The sub-account.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Subaccount" + } + } + } + }, + "400": { + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "404": { + "description": "No sub-account with this id or uid exists in the API key's environment (`subaccount_not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47362,16 +50118,14 @@ } } } - } - }, - "/v1/suppressions/check": { - "get": { - "operationId": "checkSuppression", + }, + "patch": { + "operationId": "updateSubaccount", "tags": [ - "Suppressions" + "Sub-accounts" ], - "summary": "Check whether an address is suppressed", - "description": "Whether a send to `address` (with `category`, if given) would skip it, and the entries that match: those with scope `*` and, with a `category`, those for that category.", + "summary": "Update a sub-account", + "description": "Changes the name, uid, metadata, status or quotas. Fields left out keep their value; `status: \"disabled\"` refuses its sends until it is `active` again.", "security": [ { "bearerAuth": [] @@ -47381,60 +50135,33 @@ { "schema": { "type": "string", - "description": "The address to check.", + "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", "examples": [ - "user@example.com" + "user_8812" ] }, "required": true, - "description": "The address to check.", - "name": "address", - "in": "query" - }, - { - "schema": { - "type": "string", - "pattern": "^[A-Za-z0-9_-]{1,256}$", - "description": "The category of the email you plan to send. Without it, only `*` entries count." - }, - "required": false, - "description": "The category of the email you plan to send. Without it, only `*` entries count.", - "name": "category", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "transactional", - "marketing" - ], - "description": "The stream of the email you plan to send (default `transactional`). `marketing` also counts `stream:marketing` entries." - }, - "required": false, - "description": "The stream of the email you plan to send (default `transactional`). `marketing` also counts `stream:marketing` entries.", - "name": "stream", - "in": "query" - }, - { - "schema": { - "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "The sub-account you plan to send for (its id or your uid): its own entries count too." - }, - "required": false, - "description": "The sub-account you plan to send for (its id or your uid): its own entries count too.", + "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", "name": "subaccount", - "in": "query" + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSubaccountRequest" + } + } + } + }, "responses": { "200": { - "description": "The result.", + "description": "The sub-account.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47458,13 +50185,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SuppressionCheck" + "$ref": "#/components/schemas/Subaccount" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47527,7 +50254,7 @@ } }, "404": { - "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", + "description": "No sub-account with this id or uid exists in the API key's environment (`subaccount_not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47547,8 +50274,8 @@ } } }, - "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47568,8 +50295,8 @@ } } }, - "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47579,12 +50306,6 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } - }, - "Retry-After": { - "description": "Seconds to wait before retrying.", - "schema": { - "type": "integer" - } } }, "content": { @@ -47595,8 +50316,8 @@ } } }, - "500": { - "description": "Unexpected server error (`api_error` / `internal_error`).", + "422": { + "description": "The body failed validation (`validation_error`), the uid is taken (`uid_taken`), the quotas don't fit together (`invalid_quotas`), or it is being deleted (`subaccount_deleting`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47616,8 +50337,8 @@ } } }, - "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "429": { + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47627,6 +50348,12 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } } }, "content": { @@ -47636,36 +50363,9 @@ } } } - } - } - } - }, - "/v1/suppressions/import": { - "post": { - "operationId": "importSuppressions", - "tags": [ - "Suppressions" - ], - "summary": "Import suppressions in bulk", - "description": "Adds up to 1000 entries at once, with reason `import`. Each entry is validated on its own: invalid ones are skipped and listed in `invalid`, entries already on the list are left unchanged and counted in `existing`. Importing again is safe.", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ImportSuppressionsRequest" - } - } - } - }, - "responses": { - "200": { - "description": "What the import did.", + }, + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47675,27 +50375,18 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } - }, - "Coss-Version": { - "description": "The API version this response is rendered in.", - "schema": { - "type": "string", - "examples": [ - "2026-10-10" - ] - } } }, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SuppressionImport" + "$ref": "#/components/schemas/Error" } } } }, - "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47714,9 +50405,42 @@ } } } + } + } + }, + "delete": { + "operationId": "deleteSubaccount", + "tags": [ + "Sub-accounts" + ], + "summary": "Delete a sub-account", + "description": "Starts deleting the sub-account: its sends are refused at once, then its domains are released and it is removed with its suppressions (`status` is `deleting` until then). Its emails stay, with its id. Repeating the call returns it as it is.", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", + "examples": [ + "user_8812" + ] + }, + "required": true, + "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", + "name": "subaccount", + "in": "path" }, - "401": { - "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "responses": { + "202": { + "description": "The sub-account, being deleted.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47726,25 +50450,13 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "403": { - "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", "schema": { "type": "string", "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + "2026-10-10" ] } } @@ -47752,13 +50464,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/Subaccount" } } } }, - "404": { - "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", + "400": { + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47778,8 +50490,8 @@ } } }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47799,8 +50511,8 @@ } } }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47820,8 +50532,8 @@ } } }, - "422": { - "description": "The body is not a list of 1-1000 `{ address, scope? }` objects (`validation_error`).", + "404": { + "description": "No sub-account with this id or uid exists in the API key's environment (`subaccount_not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -47910,22 +50622,17 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] + } } }, - "/v1/suppressions/export": { - "get": { - "operationId": "exportSuppressions", + "/v1/subaccounts/{subaccount}/reinstate": { + "post": { + "operationId": "reinstateSubaccount", "tags": [ - "Suppressions" + "Sub-accounts" ], - "summary": "Export the suppression list as CSV", - "description": "The whole suppression list of the API key's environment (optionally filtered), oldest first, as CSV with the columns `address,scope,reason,created_at,email_id,id`. The file can be imported again as is. Values a spreadsheet would run as a formula are prefixed with `'`.", + "summary": "Reinstate a sub-account", + "description": "Lifts the sub-account's reputation pause (or warning) once you fixed what caused it: its rates are measured again from now on. A pause is never lifted on its own. Repeating the call returns it as it is. Your organization's own reputation still counts its sending.", "security": [ { "bearerAuth": [] @@ -47935,64 +50642,15 @@ { "schema": { "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "Export a sub-account's own list (its id or your uid) instead of the environment's.", + "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", "examples": [ "user_8812" ] }, - "required": false, - "description": "Export a sub-account's own list (its id or your uid) instead of the environment's.", + "required": true, + "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", "name": "subaccount", - "in": "query" - }, - { - "schema": { - "anyOf": [ - { - "type": "string", - "enum": [ - "*" - ] - }, - { - "type": "string", - "enum": [ - "stream:marketing" - ] - }, - { - "type": "string", - "pattern": "^[A-Za-z0-9_-]{1,256}$" - } - ], - "description": "Only entries with this scope." - }, - "required": false, - "description": "Only entries with this scope.", - "name": "scope", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "bounce", - "complaint", - "manual", - "import", - "unsubscribe" - ], - "description": "Only entries with this reason.", - "examples": [ - "bounce" - ] - }, - "required": false, - "description": "Only entries with this reason.", - "name": "reason", - "in": "query" + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" @@ -48000,7 +50658,7 @@ ], "responses": { "200": { - "description": "The CSV file.", + "description": "The sub-account.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48022,9 +50680,9 @@ } }, "content": { - "text/csv": { + "application/json": { "schema": { - "type": "string" + "$ref": "#/components/schemas/Subaccount" } } } @@ -48093,28 +50751,7 @@ } }, "404": { - "description": "`subaccount` names no sub-account of the API key's environment (`subaccount_not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "description": "No sub-account with this id or uid exists in the API key's environment (`subaccount_not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48206,13 +50843,14 @@ } } }, - "/v1/suppressions/{id}": { + "/v1/subaccounts/{subaccount}/stats": { "get": { - "operationId": "getSuppression", + "operationId": "getSubaccountStats", "tags": [ - "Suppressions" + "Sub-accounts" ], - "summary": "Retrieve a suppression", + "summary": "Retrieve a sub-account's stats", + "description": "The sub-account's sending per UTC day: recipients, sent, delivered, bounced, complained, failed and suppressed, counted from its emails as they are now (a later bounce moves its day's numbers). Emails are kept 45 days, so earlier days are left out.", "security": [ { "bearerAuth": [] @@ -48222,23 +50860,51 @@ { "schema": { "type": "string", - "description": "The suppression's id.", + "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", "examples": [ - "sup_01k7c8m4q2f3e9v6t5r1n0p8yz" + "user_8812" ] }, "required": true, - "description": "The suppression's id.", - "name": "id", + "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", + "name": "subaccount", "in": "path" }, + { + "schema": { + "type": "string", + "format": "date", + "description": "First day (UTC, `YYYY-MM-DD`); default 30 days before `to`.", + "examples": [ + "2026-10-01" + ] + }, + "required": false, + "description": "First day (UTC, `YYYY-MM-DD`); default 30 days before `to`.", + "name": "from", + "in": "query" + }, + { + "schema": { + "type": "string", + "format": "date", + "description": "Last day (UTC, `YYYY-MM-DD`), included; default today.", + "examples": [ + "2026-10-15" + ] + }, + "required": false, + "description": "Last day (UTC, `YYYY-MM-DD`), included; default today.", + "name": "to", + "in": "query" + }, { "$ref": "#/components/parameters/CossVersion" } ], "responses": { "200": { - "description": "The entry.", + "description": "The sub-account's stats.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48262,7 +50928,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Suppression" + "$ref": "#/components/schemas/SubaccountStats" } } } @@ -48331,7 +50997,28 @@ } }, "404": { - "description": "No suppression with this id exists in the API key's environment (`not_found`).", + "description": "No sub-account with this id or uid exists in the API key's environment (`subaccount_not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "A query parameter failed validation (`validation_error`), or `from` is after `to` (`invalid_range`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48421,14 +51108,16 @@ } } } - }, - "delete": { - "operationId": "deleteSuppression", + } + }, + "/v1/sms": { + "post": { + "operationId": "sendSms", "tags": [ - "Suppressions" + "SMS" ], - "summary": "Remove a suppression", - "description": "Removes the entry, so later sends reach the address again (unless another entry still matches). Entries added for bounces and complaints can be removed too.", + "summary": "Send an SMS", + "description": "Queues a text message from the API key's environment and returns it with `status: \"queued\"`; it is handed to the carrier moments later. Follow it with `GET /v1/sms/{id}` or the `sms.sent`, `sms.delivered`, `sms.undelivered` and `sms.failed` webhooks. Live (`coss_live_…`) keys send `from` one of the organization's numbers whose carrier registration is approved, to the countries the organization allows (US and Canada unless changed in the dashboard). Sandbox (`coss_test_…`) keys accept any `from`, deliver nothing and answer the SMS simulator's numbers (`+15005550006` delivered, `+15005550001` invalid, `+15005550004` filtered by the carrier, `+15005550009` opted out, `+15005550008` replies). A number on the environment's SMS suppression list (it replied STOP, or it can't receive SMS) is skipped: the message is `failed` with `suppressed`. Segments count against the organization's send quota, and each is billed by the destination country.", "security": [ { "bearerAuth": [] @@ -48438,23 +51127,35 @@ { "schema": { "type": "string", - "description": "The suppression's id.", + "minLength": 1, + "maxLength": 256, + "description": "Makes retries safe: a repeated request with the same key and body returns the original message (with its current status) instead of sending again, for 24 hours. 1-256 characters.", "examples": [ - "sup_01k7c8m4q2f3e9v6t5r1n0p8yz" + "welcome-user-123" ] }, - "required": true, - "description": "The suppression's id.", - "name": "id", - "in": "path" + "required": false, + "description": "Makes retries safe: a repeated request with the same key and body returns the original message (with its current status) instead of sending again, for 24 hours. 1-256 characters.", + "name": "Idempotency-Key", + "in": "header" }, { "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SendSmsRequest" + } + } + } + }, "responses": { - "200": { - "description": "The entry was removed.", + "202": { + "description": "The message, accepted (`queued` or `scheduled`; `failed` when its number is suppressed). A replay returns the original message with its current status.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48465,6 +51166,15 @@ ] } }, + "Idempotent-Replayed": { + "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", + "schema": { + "type": "string", + "enum": [ + "true" + ] + } + }, "Coss-Version": { "description": "The API version this response is rendered in.", "schema": { @@ -48478,13 +51188,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedSuppression" + "$ref": "#/components/schemas/Sms" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48525,8 +51235,8 @@ } } }, - "403": { - "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "402": { + "description": "Live sending is paused for an overdue invoice or the spend limit (`billing_hold`) or a used-up budget (`budget_exceeded`), the plan doesn't include SMS or the destination country isn't priced (`plan_feature_unavailable`) (`billing_error`). Never retried: it needs a plan change or a payment.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48546,8 +51256,8 @@ } } }, - "404": { - "description": "No suppression with this id exists in the API key's environment (`not_found`).", + "403": { + "description": "The API key lacks the permission this endpoint needs (`insufficient_permissions`), its organization is suspended (`organization_suspended`), or live sending is suspended (`account_suspended`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48567,8 +51277,8 @@ } } }, - "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "409": { + "description": "Requests with this `Idempotency-Key` are racing for an expired key (`request_in_progress`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48580,7 +51290,7 @@ } }, "Retry-After": { - "description": "Seconds to wait before retrying.", + "description": "Seconds to wait.", "schema": { "type": "integer" } @@ -48594,8 +51304,8 @@ } } }, - "500": { - "description": "Unexpected server error (`api_error` / `internal_error`).", + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48615,8 +51325,8 @@ } } }, - "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48635,36 +51345,9 @@ } } } - } - } - } - }, - "/v1/subaccounts": { - "post": { - "operationId": "createSubaccount", - "tags": [ - "Sub-accounts" - ], - "summary": "Create a sub-account", - "description": "Creates a sub-account: one of your users, who gets their own domains, suppressions, quotas and reputation. Give it a `uid` (e.g. your user's id) to address it by in every path and send. Sub-accounts belong to the API key's own environment: a `coss_test_…` key only ever sees sandbox ones, a `coss_live_…` key only production ones.", - "security": [ - { - "bearerAuth": [] - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSubaccountRequest" - } - } - } - }, - "responses": { - "200": { - "description": "The sub-account.", + }, + "422": { + "description": "The body failed validation (`validation_error`, see `issues`), `to` isn't a valid number (`invalid_phone_number`), `from` isn't one of the organization's numbers (`sender_not_found`) or can't send yet (`sender_not_ready`), the destination country isn't allowed (`country_not_allowed`), or the `Idempotency-Key` was already used with a different body (`idempotency_key_reused`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48674,27 +51357,45 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } - }, - "Coss-Version": { - "description": "The API version this response is rendered in.", + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "429": { + "description": "Too many requests with this API key (`rate_limited`), or the message's segments exceed the send quota or too many messages went to this number in the last hour (`quota_exceeded`). Retry after `Retry-After` seconds.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", "schema": { "type": "string", "examples": [ - "2026-10-10" + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } + }, + "Retry-After": { + "description": "Seconds to wait.", + "schema": { + "type": "integer" + } } }, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Subaccount" + "$ref": "#/components/schemas/Error" } } } }, - "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "500": { + "description": "Unexpected server error (`api_error` / `internal_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48714,8 +51415,8 @@ } } }, - "401": { - "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "503": { + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48734,9 +51435,95 @@ } } } + } + } + }, + "get": { + "operationId": "listSms", + "tags": [ + "SMS" + ], + "summary": "List SMS", + "description": "Messages sent from the API key's environment, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ + { + "schema": { + "type": "string", + "pattern": "^\\+[1-9]\\d{6,14}$", + "description": "Only messages to this number." + }, + "required": false, + "description": "Only messages to this number.", + "name": "to", + "in": "query" }, - "402": { - "description": "Live sub-accounts need a plan with sub-accounts (`plan_feature_unavailable`), up to its limit (`plan_limit_reached`). (`billing_error`). Never retried: it needs a plan change or a payment.", + { + "schema": { + "type": "string", + "description": "Only messages in these statuses, comma-separated: `failed`." + }, + "required": false, + "description": "Only messages in these statuses, comma-separated: `failed`.", + "name": "status", + "in": "query" + }, + { + "schema": { + "type": "string", + "format": "date-time", + "description": "Only messages created at or after this time." + }, + "required": false, + "description": "Only messages created at or after this time.", + "name": "created_after", + "in": "query" + }, + { + "schema": { + "type": "string", + "format": "date-time", + "description": "Only messages created before this time." + }, + "required": false, + "description": "Only messages created before this time.", + "name": "created_before", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "1-100, default 20." + }, + "required": false, + "description": "1-100, default 20.", + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "maxLength": 64, + "description": "Cursor: the `id` of the last item of the previous page." + }, + "required": false, + "description": "Cursor: the `id` of the last item of the previous page.", + "name": "after", + "in": "query" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "responses": { + "200": { + "description": "A page of messages.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48746,18 +51533,27 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } } }, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Error" + "$ref": "#/components/schemas/SmsList" } } } }, - "403": { - "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "400": { + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48777,8 +51573,8 @@ } } }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", + "401": { + "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48798,8 +51594,8 @@ } } }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "403": { + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48820,7 +51616,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`), the `uid` is taken (`uid_taken`), the quotas don't fit together (`invalid_quotas`), or the sandbox environment has the most sub-accounts it can (100: `too_many_subaccounts`).", + "description": "A query parameter failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48909,58 +51705,35 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] - }, - "get": { - "operationId": "listSubaccounts", + } + } + }, + "/v1/sms/suppressions": { + "post": { + "operationId": "createSmsSuppression", "tags": [ - "Sub-accounts" + "SMS" ], - "summary": "List sub-accounts", - "description": "The environment's sub-accounts, newest first. Sub-accounts belong to the API key's own environment: a `coss_test_…` key only ever sees sandbox ones, a `coss_live_…` key only production ones.", + "summary": "Add a number to the SMS suppression list", + "description": "Later sends from the API key's environment to the number are skipped. Adding a number already on the list returns its entry with status 200.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "description": "1-100, default 50." - }, - "required": false, - "description": "1-100, default 50.", - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "description": "The last `id` of the previous page.", - "examples": [ - "sub_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": false, - "description": "The last `id` of the previous page.", - "name": "after", - "in": "query" - }, - { - "$ref": "#/components/parameters/CossVersion" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSmsSuppressionRequest" + } + } } - ], + }, "responses": { "200": { - "description": "A page of sub-accounts.", + "description": "The number already had an entry.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -48984,13 +51757,43 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubaccountList" + "$ref": "#/components/schemas/SmsSuppression" + } + } + } + }, + "201": { + "description": "The new entry.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SmsSuppression" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -49052,6 +51855,69 @@ } } }, + "413": { + "description": "The request body is larger than 5 MB (`payload_too_large`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The body failed validation (`validation_error`) or the number isn't valid (`invalid_phone_number`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -49121,17 +51987,20 @@ } } } - } - } - }, - "/v1/subaccounts/{subaccount}": { + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] + }, "get": { - "operationId": "getSubaccount", + "operationId": "listSmsSuppressions", "tags": [ - "Sub-accounts" + "SMS" ], - "summary": "Retrieve a sub-account", - "description": "A sub-account of the API key's environment, by its id or uid, with its quotas and reputation.", + "summary": "List suppressed numbers", + "description": "The SMS suppression list of the API key's environment, newest first: opt-outs, invalid numbers and numbers you added.", "security": [ { "bearerAuth": [] @@ -49141,15 +52010,36 @@ { "schema": { "type": "string", - "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", - "examples": [ - "user_8812" - ] + "pattern": "^\\+[1-9]\\d{6,14}$", + "description": "Only this number's entry." }, - "required": true, - "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", - "name": "subaccount", - "in": "path" + "required": false, + "description": "Only this number's entry.", + "name": "phone_number", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "1-100, default 20." + }, + "required": false, + "description": "1-100, default 20.", + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "maxLength": 64, + "description": "Cursor: the `id` of the last item of the previous page." + }, + "required": false, + "description": "Cursor: the `id` of the last item of the previous page.", + "name": "after", + "in": "query" }, { "$ref": "#/components/parameters/CossVersion" @@ -49157,7 +52047,7 @@ ], "responses": { "200": { - "description": "The sub-account.", + "description": "A page of entries.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -49181,7 +52071,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Subaccount" + "$ref": "#/components/schemas/SmsSuppressionList" } } } @@ -49249,8 +52139,8 @@ } } }, - "404": { - "description": "No sub-account with this id or uid exists in the API key's environment (`subaccount_not_found`).", + "422": { + "description": "A query parameter failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -49340,14 +52230,15 @@ } } } - }, - "patch": { - "operationId": "updateSubaccount", + } + }, + "/v1/sms/suppressions/check": { + "get": { + "operationId": "checkSmsSuppression", "tags": [ - "Sub-accounts" + "SMS" ], - "summary": "Update a sub-account", - "description": "Changes the name, uid, metadata, status or quotas. Fields left out keep their value; `status: \"disabled\"` refuses its sends until it is `active` again.", + "summary": "Check whether a number is suppressed", "security": [ { "bearerAuth": [] @@ -49357,33 +52248,19 @@ { "schema": { "type": "string", - "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", - "examples": [ - "user_8812" - ] + "pattern": "^\\+[1-9]\\d{6,14}$" }, "required": true, - "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", - "name": "subaccount", - "in": "path" + "name": "phone_number", + "in": "query" }, { "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateSubaccountRequest" - } - } - } - }, "responses": { "200": { - "description": "The sub-account.", + "description": "The result.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -49407,13 +52284,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Subaccount" + "$ref": "#/components/schemas/SmsSuppressionCheck" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -49475,71 +52352,8 @@ } } }, - "404": { - "description": "No sub-account with this id or uid exists in the API key's environment (`subaccount_not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "422": { - "description": "The body failed validation (`validation_error`), the uid is taken (`uid_taken`), the quotas don't fit together (`invalid_quotas`), or it is being deleted (`subaccount_deleting`).", + "description": "A query parameter failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -49629,14 +52443,15 @@ } } } - }, - "delete": { - "operationId": "deleteSubaccount", + } + }, + "/v1/sms/suppressions/{id}": { + "get": { + "operationId": "getSmsSuppression", "tags": [ - "Sub-accounts" + "SMS" ], - "summary": "Delete a sub-account", - "description": "Starts deleting the sub-account: its sends are refused at once, then its domains are released and it is removed with its suppressions (`status` is `deleting` until then). Its emails stay, with its id. Repeating the call returns it as it is.", + "summary": "Retrieve an SMS suppression", "security": [ { "bearerAuth": [] @@ -49646,14 +52461,14 @@ { "schema": { "type": "string", - "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", + "description": "The entry's id.", "examples": [ - "user_8812" + "smssup_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", - "name": "subaccount", + "description": "The entry's id.", + "name": "id", "in": "path" }, { @@ -49661,8 +52476,8 @@ } ], "responses": { - "202": { - "description": "The sub-account, being deleted.", + "200": { + "description": "The entry.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -49686,7 +52501,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Subaccount" + "$ref": "#/components/schemas/SmsSuppression" } } } @@ -49755,7 +52570,7 @@ } }, "404": { - "description": "No sub-account with this id or uid exists in the API key's environment (`subaccount_not_found`).", + "description": "No entry with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -49845,16 +52660,14 @@ } } } - } - }, - "/v1/subaccounts/{subaccount}/reinstate": { - "post": { - "operationId": "reinstateSubaccount", + }, + "delete": { + "operationId": "deleteSmsSuppression", "tags": [ - "Sub-accounts" + "SMS" ], - "summary": "Reinstate a sub-account", - "description": "Lifts the sub-account's reputation pause (or warning) once you fixed what caused it: its rates are measured again from now on. A pause is never lifted on its own. Repeating the call returns it as it is. Your organization's own reputation still counts its sending.", + "summary": "Remove a number from the SMS suppression list", + "description": "Sends to the number go out again. Remove an opt-out only when the person asked to receive messages again (they can also reply START).", "security": [ { "bearerAuth": [] @@ -49864,14 +52677,14 @@ { "schema": { "type": "string", - "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", + "description": "The entry's id.", "examples": [ - "user_8812" + "smssup_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", - "name": "subaccount", + "description": "The entry's id.", + "name": "id", "in": "path" }, { @@ -49880,7 +52693,7 @@ ], "responses": { "200": { - "description": "The sub-account.", + "description": "The entry was removed.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -49904,7 +52717,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Subaccount" + "$ref": "#/components/schemas/DeletedSmsSuppression" } } } @@ -49973,7 +52786,7 @@ } }, "404": { - "description": "No sub-account with this id or uid exists in the API key's environment (`subaccount_not_found`).", + "description": "No entry with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -50065,14 +52878,14 @@ } } }, - "/v1/subaccounts/{subaccount}/stats": { + "/v1/sms/received": { "get": { - "operationId": "getSubaccountStats", + "operationId": "listReceivedSms", "tags": [ - "Sub-accounts" + "SMS" ], - "summary": "Retrieve a sub-account's stats", - "description": "The sub-account's sending per UTC day: recipients, sent, delivered, bounced, complained, failed and suppressed, counted from its emails as they are now (a later bounce moves its day's numbers). Emails are kept 45 days, so earlier days are left out.", + "summary": "List received SMS", + "description": "Messages sent to the organization's numbers whose replies go to the API key's environment, newest first.", "security": [ { "bearerAuth": [] @@ -50082,42 +52895,64 @@ { "schema": { "type": "string", - "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", - "examples": [ - "user_8812" - ] + "pattern": "^\\+[1-9]\\d{6,14}$", + "description": "Only messages from this number." }, - "required": true, - "description": "The sub-account's `id` (`sub_…`) or your `uid` for it.", - "name": "subaccount", - "in": "path" + "required": false, + "description": "Only messages from this number.", + "name": "from", + "in": "query" }, { "schema": { "type": "string", - "format": "date", - "description": "First day (UTC, `YYYY-MM-DD`); default 30 days before `to`.", - "examples": [ - "2026-10-01" - ] + "pattern": "^\\+[1-9]\\d{6,14}$", + "description": "Only messages to this number of yours." }, "required": false, - "description": "First day (UTC, `YYYY-MM-DD`); default 30 days before `to`.", - "name": "from", + "description": "Only messages to this number of yours.", + "name": "to", "in": "query" }, { "schema": { "type": "string", - "format": "date", - "description": "Last day (UTC, `YYYY-MM-DD`), included; default today.", - "examples": [ - "2026-10-15" - ] + "format": "date-time" }, "required": false, - "description": "Last day (UTC, `YYYY-MM-DD`), included; default today.", - "name": "to", + "name": "created_after", + "in": "query" + }, + { + "schema": { + "type": "string", + "format": "date-time" + }, + "required": false, + "name": "created_before", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "1-100, default 20." + }, + "required": false, + "description": "1-100, default 20.", + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "maxLength": 64, + "description": "Cursor: the `id` of the last item of the previous page." + }, + "required": false, + "description": "Cursor: the `id` of the last item of the previous page.", + "name": "after", "in": "query" }, { @@ -50126,7 +52961,7 @@ ], "responses": { "200": { - "description": "The sub-account's stats.", + "description": "A page of received messages.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -50150,7 +52985,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubaccountStats" + "$ref": "#/components/schemas/ReceivedSmsList" } } } @@ -50218,29 +53053,8 @@ } } }, - "404": { - "description": "No sub-account with this id or uid exists in the API key's environment (`subaccount_not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "422": { - "description": "A query parameter failed validation (`validation_error`), or `from` is after `to` (`invalid_range`).", + "description": "A query parameter failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -50332,14 +53146,13 @@ } } }, - "/v1/sms": { - "post": { - "operationId": "sendSms", + "/v1/sms/received/{id}": { + "get": { + "operationId": "getReceivedSms", "tags": [ "SMS" ], - "summary": "Send an SMS", - "description": "Queues a text message from the API key's environment and returns it with `status: \"queued\"`; it is handed to the carrier moments later. Follow it with `GET /v1/sms/{id}` or the `sms.sent`, `sms.delivered`, `sms.undelivered` and `sms.failed` webhooks. Live (`coss_live_…`) keys send `from` one of the organization's numbers whose carrier registration is approved, to the countries the organization allows (US and Canada unless changed in the dashboard). Sandbox (`coss_test_…`) keys accept any `from`, deliver nothing and answer the SMS simulator's numbers (`+15005550006` delivered, `+15005550001` invalid, `+15005550004` filtered by the carrier, `+15005550009` opted out, `+15005550008` replies). A number on the environment's SMS suppression list (it replied STOP, or it can't receive SMS) is skipped: the message is `failed` with `suppressed`. Segments count against the organization's send quota, and each is billed by the destination country.", + "summary": "Retrieve a received SMS", "security": [ { "bearerAuth": [] @@ -50349,35 +53162,23 @@ { "schema": { "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "Makes retries safe: a repeated request with the same key and body returns the original message (with its current status) instead of sending again, for 24 hours. 1-256 characters.", + "description": "The received message's id.", "examples": [ - "welcome-user-123" + "smsin_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, - "required": false, - "description": "Makes retries safe: a repeated request with the same key and body returns the original message (with its current status) instead of sending again, for 24 hours. 1-256 characters.", - "name": "Idempotency-Key", - "in": "header" + "required": true, + "description": "The received message's id.", + "name": "id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SendSmsRequest" - } - } - } - }, "responses": { - "202": { - "description": "The message, accepted (`queued` or `scheduled`; `failed` when its number is suppressed). A replay returns the original message with its current status.", + "200": { + "description": "The received message.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -50388,15 +53189,6 @@ ] } }, - "Idempotent-Replayed": { - "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", - "schema": { - "type": "string", - "enum": [ - "true" - ] - } - }, "Coss-Version": { "description": "The API version this response is rendered in.", "schema": { @@ -50410,13 +53202,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Sms" + "$ref": "#/components/schemas/ReceivedSms" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -50457,98 +53249,8 @@ } } }, - "402": { - "description": "Live sending is paused for an overdue invoice or the spend limit (`billing_hold`) or a used-up budget (`budget_exceeded`), the plan doesn't include SMS or the destination country isn't priced (`plan_feature_unavailable`) (`billing_error`). Never retried: it needs a plan change or a payment.", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "403": { - "description": "The API key lacks the permission this endpoint needs (`insufficient_permissions`), its organization is suspended (`organization_suspended`), or live sending is suspended (`account_suspended`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "409": { - "description": "Requests with this `Idempotency-Key` are racing for an expired key (`request_in_progress`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - }, - "Retry-After": { - "description": "Seconds to wait.", - "schema": { - "type": "integer" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -50568,8 +53270,8 @@ } } }, - "422": { - "description": "The body failed validation (`validation_error`, see `issues`), `to` isn't a valid number (`invalid_phone_number`), `from` isn't one of the organization's numbers (`sender_not_found`) or can't send yet (`sender_not_ready`), the destination country isn't allowed (`country_not_allowed`), or the `Idempotency-Key` was already used with a different body (`idempotency_key_reused`).", + "404": { + "description": "No received message with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -50590,7 +53292,7 @@ } }, "429": { - "description": "Too many requests with this API key (`rate_limited`), or the message's segments exceed the send quota or too many messages went to this number in the last hour (`quota_exceeded`). Retry after `Retry-After` seconds.", + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -50602,7 +53304,7 @@ } }, "Retry-After": { - "description": "Seconds to wait.", + "description": "Seconds to wait before retrying.", "schema": { "type": "integer" } @@ -50659,93 +53361,24 @@ } } } - }, + } + }, + "/v1/sms/numbers": { "get": { - "operationId": "listSms", + "operationId": "listSmsNumbers", "tags": [ "SMS" ], - "summary": "List SMS", - "description": "Messages sent from the API key's environment, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", + "summary": "List the organization's phone numbers", + "description": "Every number of the organization, whether it can send live messages now (its carrier registration is approved) and whether its replies arrive in the API key's environment. Numbers are bought and registered in the dashboard.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "pattern": "^\\+[1-9]\\d{6,14}$", - "description": "Only messages to this number." - }, - "required": false, - "description": "Only messages to this number.", - "name": "to", - "in": "query" - }, - { - "schema": { - "type": "string", - "description": "Only messages in these statuses, comma-separated: `failed`." - }, - "required": false, - "description": "Only messages in these statuses, comma-separated: `failed`.", - "name": "status", - "in": "query" - }, - { - "schema": { - "type": "string", - "format": "date-time", - "description": "Only messages created at or after this time." - }, - "required": false, - "description": "Only messages created at or after this time.", - "name": "created_after", - "in": "query" - }, - { - "schema": { - "type": "string", - "format": "date-time", - "description": "Only messages created before this time." - }, - "required": false, - "description": "Only messages created before this time.", - "name": "created_before", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "description": "1-100, default 20." - }, - "required": false, - "description": "1-100, default 20.", - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "maxLength": 64, - "description": "Cursor: the `id` of the last item of the previous page." - }, - "required": false, - "description": "Cursor: the `id` of the last item of the previous page.", - "name": "after", - "in": "query" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], "responses": { "200": { - "description": "A page of messages.", + "description": "The numbers.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -50769,7 +53402,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SmsList" + "$ref": "#/components/schemas/SmsNumberList" } } } @@ -50837,27 +53470,6 @@ } } }, - "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -50927,65 +53539,47 @@ } } } - } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] } }, - "/v1/sms/suppressions": { - "post": { - "operationId": "createSmsSuppression", + "/v1/sms/{id}": { + "get": { + "operationId": "getSms", "tags": [ "SMS" ], - "summary": "Add a number to the SMS suppression list", - "description": "Later sends from the API key's environment to the number are skipped. Adding a number already on the list returns its entry with status 200.", + "summary": "Retrieve an SMS", "security": [ { "bearerAuth": [] } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSmsSuppressionRequest" - } - } + "parameters": [ + { + "schema": { + "type": "string", + "description": "The message's id.", + "examples": [ + "sms_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The message's id.", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" } - }, + ], "responses": { "200": { - "description": "The number already had an entry.", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - }, - "Coss-Version": { - "description": "The API version this response is rendered in.", - "schema": { - "type": "string", - "examples": [ - "2026-10-10" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/SmsSuppression" - } - } - } - }, - "201": { - "description": "The new entry.", + "description": "The message.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -51009,13 +53603,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SmsSuppression" + "$ref": "#/components/schemas/Sms" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -51077,50 +53671,8 @@ } } }, - "413": { - "description": "The request body is larger than 5 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The body failed validation (`validation_error`) or the number isn't valid (`invalid_phone_number`).", + "404": { + "description": "No message with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -51209,20 +53761,17 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] - }, + } + } + }, + "/v1/sms/{id}/events": { "get": { - "operationId": "listSmsSuppressions", + "operationId": "listSmsEvents", "tags": [ "SMS" ], - "summary": "List suppressed numbers", - "description": "The SMS suppression list of the API key's environment, newest first: opt-outs, invalid numbers and numbers you added.", + "summary": "List an SMS's events", + "description": "Everything that happened to the message, oldest first.", "security": [ { "bearerAuth": [] @@ -51232,36 +53781,15 @@ { "schema": { "type": "string", - "pattern": "^\\+[1-9]\\d{6,14}$", - "description": "Only this number's entry." - }, - "required": false, - "description": "Only this number's entry.", - "name": "phone_number", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "description": "1-100, default 20." - }, - "required": false, - "description": "1-100, default 20.", - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "maxLength": 64, - "description": "Cursor: the `id` of the last item of the previous page." + "description": "The message's id.", + "examples": [ + "sms_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] }, - "required": false, - "description": "Cursor: the `id` of the last item of the previous page.", - "name": "after", - "in": "query" + "required": true, + "description": "The message's id.", + "name": "id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" @@ -51269,7 +53797,7 @@ ], "responses": { "200": { - "description": "A page of entries.", + "description": "The events.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -51293,7 +53821,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SmsSuppressionList" + "$ref": "#/components/schemas/SmsEventList" } } } @@ -51361,8 +53889,8 @@ } } }, - "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "404": { + "description": "No message with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -51454,13 +53982,14 @@ } } }, - "/v1/sms/suppressions/check": { - "get": { - "operationId": "checkSmsSuppression", + "/v1/sms/{id}/cancel": { + "post": { + "operationId": "cancelSms", "tags": [ "SMS" ], - "summary": "Check whether a number is suppressed", + "summary": "Cancel a scheduled SMS", + "description": "Cancels a message scheduled with `scheduled_at` before it is sent. Canceling a canceled message returns it as is.", "security": [ { "bearerAuth": [] @@ -51470,11 +53999,15 @@ { "schema": { "type": "string", - "pattern": "^\\+[1-9]\\d{6,14}$" + "description": "The message's id.", + "examples": [ + "sms_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] }, "required": true, - "name": "phone_number", - "in": "query" + "description": "The message's id.", + "name": "id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" @@ -51482,7 +54015,7 @@ ], "responses": { "200": { - "description": "The result.", + "description": "The canceled message.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -51506,7 +54039,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SmsSuppressionCheck" + "$ref": "#/components/schemas/Sms" } } } @@ -51574,8 +54107,29 @@ } } }, + "404": { + "description": "No message with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "description": "The message isn't scheduled (`sms_not_cancelable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -51667,39 +54221,32 @@ } } }, - "/v1/sms/suppressions/{id}": { - "get": { - "operationId": "getSmsSuppression", + "/v1/sign/documents": { + "post": { + "operationId": "uploadSignDocument", "tags": [ - "SMS" + "Sign documents" ], - "summary": "Retrieve an SMS suppression", + "summary": "Upload a document", + "description": "Uploads a PDF (base64, at most 25 MB and 500 pages, not password-protected) for signature requests to use. The response lists each page's size and the text anchors found in it (`{{signature:signer_1}}`), which fields can be placed by. Requests can also take PDFs inline.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The entry's id.", - "examples": [ - "smssup_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The entry's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UploadSignDocumentRequest" + } + } } - ], + }, "responses": { - "200": { - "description": "The entry.", + "201": { + "description": "The uploaded document.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -51723,13 +54270,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SmsSuppression" + "$ref": "#/components/schemas/SignDocument" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -51791,182 +54338,8 @@ } } }, - "404": { - "description": "No entry with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - }, - "Retry-After": { - "description": "Seconds to wait before retrying.", - "schema": { - "type": "integer" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "500": { - "description": "Unexpected server error (`api_error` / `internal_error`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - } - } - }, - "delete": { - "operationId": "deleteSmsSuppression", - "tags": [ - "SMS" - ], - "summary": "Remove a number from the SMS suppression list", - "description": "Sends to the number go out again. Remove an opt-out only when the person asked to receive messages again (they can also reply START).", - "security": [ - { - "bearerAuth": [] - } - ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The entry's id.", - "examples": [ - "smssup_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The entry's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], - "responses": { - "200": { - "description": "The entry was removed.", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - }, - "Coss-Version": { - "description": "The API version this response is rendered in.", - "schema": { - "type": "string", - "examples": [ - "2026-10-10" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeletedSmsSuppression" - } - } - } - }, - "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "401": { - "description": "The API key is missing, invalid, revoked or expired (`authentication_error`).", + "413": { + "description": "The request body is larger than 40 MB (`payload_too_large`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -51986,8 +54359,8 @@ } } }, - "403": { - "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52007,8 +54380,8 @@ } } }, - "404": { - "description": "No entry with this id exists in the API key's environment (`not_found`).", + "422": { + "description": "The body failed validation (`validation_error`, see `issues`), or the file isn't a PDF coss.com can read (`invalid_document`: damaged, encrypted or too many pages).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52077,7 +54450,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52097,63 +54470,26 @@ } } } - } - } - }, - "/v1/sms/received": { + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] + }, "get": { - "operationId": "listReceivedSms", + "operationId": "listSignDocuments", "tags": [ - "SMS" + "Sign documents" ], - "summary": "List received SMS", - "description": "Messages sent to the organization's numbers whose replies go to the API key's environment, newest first.", + "summary": "List documents", + "description": "Documents uploaded to the API key's environment, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", "security": [ { "bearerAuth": [] } ], "parameters": [ - { - "schema": { - "type": "string", - "pattern": "^\\+[1-9]\\d{6,14}$", - "description": "Only messages from this number." - }, - "required": false, - "description": "Only messages from this number.", - "name": "from", - "in": "query" - }, - { - "schema": { - "type": "string", - "pattern": "^\\+[1-9]\\d{6,14}$", - "description": "Only messages to this number of yours." - }, - "required": false, - "description": "Only messages to this number of yours.", - "name": "to", - "in": "query" - }, - { - "schema": { - "type": "string", - "format": "date-time" - }, - "required": false, - "name": "created_after", - "in": "query" - }, - { - "schema": { - "type": "string", - "format": "date-time" - }, - "required": false, - "name": "created_before", - "in": "query" - }, { "schema": { "type": "integer", @@ -52183,7 +54519,7 @@ ], "responses": { "200": { - "description": "A page of received messages.", + "description": "A page of documents.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52207,7 +54543,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ReceivedSmsList" + "$ref": "#/components/schemas/SignDocumentList" } } } @@ -52368,13 +54704,13 @@ } } }, - "/v1/sms/received/{id}": { + "/v1/sign/documents/{id}": { "get": { - "operationId": "getReceivedSms", + "operationId": "getSignDocument", "tags": [ - "SMS" + "Sign documents" ], - "summary": "Retrieve a received SMS", + "summary": "Retrieve a document", "security": [ { "bearerAuth": [] @@ -52384,13 +54720,13 @@ { "schema": { "type": "string", - "description": "The received message's id.", + "description": "The document's id.", "examples": [ - "smsin_01k7c8m4q2f3e9v6t5r1n0p8yz" + "sdoc_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The received message's id.", + "description": "The document's id.", "name": "id", "in": "path" }, @@ -52400,7 +54736,7 @@ ], "responses": { "200": { - "description": "The received message.", + "description": "The document.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52424,7 +54760,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ReceivedSms" + "$ref": "#/components/schemas/SignDocument" } } } @@ -52493,7 +54829,7 @@ } }, "404": { - "description": "No received message with this id exists in the API key's environment (`not_found`).", + "description": "No document with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52583,24 +54919,40 @@ } } } - } - }, - "/v1/sms/numbers": { - "get": { - "operationId": "listSmsNumbers", + }, + "delete": { + "operationId": "deleteSignDocument", "tags": [ - "SMS" + "Sign documents" ], - "summary": "List the organization's phone numbers", - "description": "Every number of the organization, whether it can send live messages now (its carrier registration is approved) and whether its replies arrive in the API key's environment. Numbers are bought and registered in the dashboard.", + "summary": "Delete a document", + "description": "Deletes an uploaded document and its file. Documents a request uses can't be deleted.", "security": [ { "bearerAuth": [] } ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The document's id.", + "examples": [ + "sdoc_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The document's id.", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], "responses": { "200": { - "description": "The numbers.", + "description": "The document was deleted.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52624,7 +54976,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SmsNumberList" + "$ref": "#/components/schemas/DeletedSignDocument" } } } @@ -52692,6 +55044,48 @@ } } }, + "404": { + "description": "No document with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "A signature request uses the document (`document_in_use`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -52741,7 +55135,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52761,21 +55155,17 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] + } } }, - "/v1/sms/{id}": { - "get": { - "operationId": "getSms", + "/v1/sign/requests": { + "post": { + "operationId": "createSignRequest", "tags": [ - "SMS" + "Signature requests" ], - "summary": "Retrieve an SMS", + "summary": "Create a signature request", + "description": "Asks one or more signers to sign one or more PDFs. Give documents by id (uploaded) or inline, and each signer's fields by position (`page`, `x`, `y`, `width`, `height` in PDF points from the page's top left) or by text anchor (`{{signature:signer_1}}`). Every signer needs a `signature` field. Sent at once unless `send` is `false` (a `draft`). Each signer signs by email (`delivery: \"email\"`, the default) or in your app (`\"embedded\"`).", "security": [ { "bearerAuth": [] @@ -52785,23 +55175,35 @@ { "schema": { "type": "string", - "description": "The message's id.", + "minLength": 1, + "maxLength": 256, + "description": "Makes retries safe: a repeated request with the same key and body returns the original request (in its current state) instead of creating another, for 24 hours. 1-256 characters.", "examples": [ - "sms_01k7c8m4q2f3e9v6t5r1n0p8yz" + "welcome-user-123" ] }, - "required": true, - "description": "The message's id.", - "name": "id", - "in": "path" + "required": false, + "description": "Makes retries safe: a repeated request with the same key and body returns the original request (in its current state) instead of creating another, for 24 hours. 1-256 characters.", + "name": "Idempotency-Key", + "in": "header" }, { "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignRequestRequest" + } + } + } + }, "responses": { - "200": { - "description": "The message.", + "201": { + "description": "The signature request (`sent`, or `draft`). A replay returns the original request in its current state.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52812,6 +55214,15 @@ ] } }, + "Idempotent-Replayed": { + "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", + "schema": { + "type": "string", + "enum": [ + "true" + ] + } + }, "Coss-Version": { "description": "The API version this response is rendered in.", "schema": { @@ -52825,13 +55236,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Sms" + "$ref": "#/components/schemas/SignRequest" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52893,8 +55304,71 @@ } } }, - "404": { - "description": "No message with this id exists in the API key's environment (`not_found`).", + "409": { + "description": "Requests with this `Idempotency-Key` are racing for an expired key (`request_in_progress`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 40 MB (`payload_too_large`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The body failed validation (`validation_error`, see `issues`), a document isn't a PDF coss.com can read (`invalid_document`) or isn't in the environment (`not_found`), a field doesn't fit on its page or names an anchor no document has (`invalid_fields`), a signer is listed twice (`invalid_signers`), `expires_at` is out of range (`invalid_expiry`), or the `Idempotency-Key` was already used with a different body (`idempotency_key_reused`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52963,7 +55437,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -52984,16 +55458,14 @@ } } } - } - }, - "/v1/sms/{id}/events": { + }, "get": { - "operationId": "listSmsEvents", + "operationId": "listSignRequests", "tags": [ - "SMS" + "Signature requests" ], - "summary": "List an SMS's events", - "description": "Everything that happened to the message, oldest first.", + "summary": "List signature requests", + "description": "Signature requests of the API key's environment, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", "security": [ { "bearerAuth": [] @@ -53003,15 +55475,35 @@ { "schema": { "type": "string", - "description": "The message's id.", - "examples": [ - "sms_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] + "description": "Only requests in these statuses, comma-separated: `sent,draft`." }, - "required": true, - "description": "The message's id.", - "name": "id", - "in": "path" + "required": false, + "description": "Only requests in these statuses, comma-separated: `sent,draft`.", + "name": "status", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "1-100, default 20." + }, + "required": false, + "description": "1-100, default 20.", + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "maxLength": 64, + "description": "Cursor: the `id` of the last item of the previous page." + }, + "required": false, + "description": "Cursor: the `id` of the last item of the previous page.", + "name": "after", + "in": "query" }, { "$ref": "#/components/parameters/CossVersion" @@ -53019,7 +55511,7 @@ ], "responses": { "200": { - "description": "The events.", + "description": "A page of signature requests.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -53043,7 +55535,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SmsEventList" + "$ref": "#/components/schemas/SignRequestList" } } } @@ -53111,8 +55603,8 @@ } } }, - "404": { - "description": "No message with this id exists in the API key's environment (`not_found`).", + "422": { + "description": "A query parameter failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -53204,14 +55696,13 @@ } } }, - "/v1/sms/{id}/cancel": { - "post": { - "operationId": "cancelSms", + "/v1/sign/requests/{id}": { + "get": { + "operationId": "getSignRequest", "tags": [ - "SMS" + "Signature requests" ], - "summary": "Cancel a scheduled SMS", - "description": "Cancels a message scheduled with `scheduled_at` before it is sent. Canceling a canceled message returns it as is.", + "summary": "Retrieve a signature request", "security": [ { "bearerAuth": [] @@ -53221,13 +55712,13 @@ { "schema": { "type": "string", - "description": "The message's id.", + "description": "The signature request's id.", "examples": [ - "sms_01k7c8m4q2f3e9v6t5r1n0p8yz" + "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The message's id.", + "description": "The signature request's id.", "name": "id", "in": "path" }, @@ -53237,7 +55728,7 @@ ], "responses": { "200": { - "description": "The canceled message.", + "description": "The signature request.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -53261,7 +55752,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Sms" + "$ref": "#/components/schemas/SignRequest" } } } @@ -53330,28 +55821,7 @@ } }, "404": { - "description": "No message with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The message isn't scheduled (`sms_not_cancelable`).", + "description": "No signature request with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -53441,34 +55911,40 @@ } } } - } - }, - "/v1/sign/documents": { - "post": { - "operationId": "uploadSignDocument", + }, + "delete": { + "operationId": "deleteSignRequest", "tags": [ - "Sign documents" + "Signature requests" ], - "summary": "Upload a document", - "description": "Uploads a PDF (base64, at most 25 MB and 500 pages, not password-protected) for signature requests to use. The response lists each page's size and the text anchors found in it (`{{signature:signer_1}}`), which fields can be placed by. Requests can also take PDFs inline.", + "summary": "Delete a signature request", + "description": "Deletes a request that isn't `sent` (cancel it first) with its signers, fields, audit trail, signatures and signed document, for good. Its documents stay (delete them on their own). Keep the signed document first if you need it: it is your record.", "security": [ { "bearerAuth": [] } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UploadSignDocumentRequest" - } - } + "parameters": [ + { + "schema": { + "type": "string", + "description": "The signature request's id.", + "examples": [ + "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The signature request's id.", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" } - }, + ], "responses": { - "201": { - "description": "The uploaded document.", + "200": { + "description": "The deleted request.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -53492,13 +55968,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignDocument" + "$ref": "#/components/schemas/DeletedSignRequest" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -53560,29 +56036,8 @@ } } }, - "413": { - "description": "The request body is larger than 40 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "404": { + "description": "No signature request with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -53603,7 +56058,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`, see `issues`), or the file isn't a PDF coss.com can read (`invalid_document`: damaged, encrypted or too many pages).", + "description": "The request is `sent`: cancel it first (`request_not_deletable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -53692,48 +56147,35 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] - }, - "get": { - "operationId": "listSignDocuments", + } + } + }, + "/v1/sign/requests/{id}/send": { + "post": { + "operationId": "sendSignRequest", "tags": [ - "Sign documents" + "Signature requests" ], - "summary": "List documents", - "description": "Documents uploaded to the API key's environment, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", + "summary": "Send a draft signature request", + "description": "Sends a `draft`. An already sent request is returned as is.", "security": [ { "bearerAuth": [] } ], "parameters": [ - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "description": "1-100, default 20." - }, - "required": false, - "description": "1-100, default 20.", - "name": "limit", - "in": "query" - }, { "schema": { "type": "string", - "maxLength": 64, - "description": "Cursor: the `id` of the last item of the previous page." + "description": "The signature request's id.", + "examples": [ + "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] }, - "required": false, - "description": "Cursor: the `id` of the last item of the previous page.", - "name": "after", - "in": "query" + "required": true, + "description": "The signature request's id.", + "name": "id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" @@ -53741,7 +56183,7 @@ ], "responses": { "200": { - "description": "A page of documents.", + "description": "The sent request.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -53765,7 +56207,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignDocumentList" + "$ref": "#/components/schemas/SignRequest" } } } @@ -53833,8 +56275,29 @@ } } }, + "404": { + "description": "No signature request with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "description": "The request isn't a draft (`request_not_draft`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -53926,13 +56389,14 @@ } } }, - "/v1/sign/documents/{id}": { - "get": { - "operationId": "getSignDocument", + "/v1/sign/requests/{id}/cancel": { + "post": { + "operationId": "cancelSignRequest", "tags": [ - "Sign documents" + "Signature requests" ], - "summary": "Retrieve a document", + "summary": "Cancel a signature request", + "description": "Cancels a `draft` or `sent` request: its signers can no longer sign. An already canceled request is returned as is.", "security": [ { "bearerAuth": [] @@ -53942,13 +56406,13 @@ { "schema": { "type": "string", - "description": "The document's id.", + "description": "The signature request's id.", "examples": [ - "sdoc_01k7c8m4q2f3e9v6t5r1n0p8yz" + "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The document's id.", + "description": "The signature request's id.", "name": "id", "in": "path" }, @@ -53958,7 +56422,7 @@ ], "responses": { "200": { - "description": "The document.", + "description": "The canceled request.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -53982,7 +56446,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignDocument" + "$ref": "#/components/schemas/SignRequest" } } } @@ -54051,7 +56515,28 @@ } }, "404": { - "description": "No document with this id exists in the API key's environment (`not_found`).", + "description": "No signature request with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The request is already completed, declined or expired (`request_not_cancelable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54141,14 +56626,16 @@ } } } - }, - "delete": { - "operationId": "deleteSignDocument", + } + }, + "/v1/sign/requests/{id}/audit_trail": { + "get": { + "operationId": "listSignRequestEvents", "tags": [ - "Sign documents" + "Signature requests" ], - "summary": "Delete a document", - "description": "Deletes an uploaded document and its file. Documents a request uses can't be deleted.", + "summary": "List a signature request's audit trail", + "description": "Everything that happened to the request, oldest first: who did it, from which address, the documents' SHA-256 when it mattered, and a hash chain (`previous_hash`, `hash`) that shows the trail is complete and unchanged.", "security": [ { "bearerAuth": [] @@ -54158,13 +56645,13 @@ { "schema": { "type": "string", - "description": "The document's id.", + "description": "The signature request's id.", "examples": [ - "sdoc_01k7c8m4q2f3e9v6t5r1n0p8yz" + "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The document's id.", + "description": "The signature request's id.", "name": "id", "in": "path" }, @@ -54174,7 +56661,7 @@ ], "responses": { "200": { - "description": "The document was deleted.", + "description": "The audit trail.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54198,7 +56685,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedSignDocument" + "$ref": "#/components/schemas/SignEventList" } } } @@ -54267,28 +56754,7 @@ } }, "404": { - "description": "No document with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "A signature request uses the document (`document_in_use`).", + "description": "No signature request with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54357,7 +56823,7 @@ } }, "503": { - "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54380,14 +56846,14 @@ } } }, - "/v1/sign/requests": { + "/v1/sign/requests/{id}/remind": { "post": { - "operationId": "createSignRequest", + "operationId": "remindSignRequest", "tags": [ "Signature requests" ], - "summary": "Create a signature request", - "description": "Asks one or more signers to sign one or more PDFs. Give documents by id (uploaded) or inline, and each signer's fields by position (`page`, `x`, `y`, `width`, `height` in PDF points from the page's top left) or by text anchor (`{{signature:signer_1}}`). Every signer needs a `signature` field. Sent at once unless `send` is `false` (a `draft`). Each signer signs by email (`delivery: \"email\"`, the default) or in your app (`\"embedded\"`).", + "summary": "Remind signers", + "description": "Emails a reminder, with a fresh link, to every email signer of a sent request who hasn't signed and whose turn it is, unless they were emailed in the last hour. Embedded signers are yours to remind. Sent within seconds; each is a `reminded` event in the audit trail.", "security": [ { "bearerAuth": [] @@ -54397,35 +56863,23 @@ { "schema": { "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "Makes retries safe: a repeated request with the same key and body returns the original request (in its current state) instead of creating another, for 24 hours. 1-256 characters.", + "description": "The signature request's id.", "examples": [ - "welcome-user-123" + "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, - "required": false, - "description": "Makes retries safe: a repeated request with the same key and body returns the original request (in its current state) instead of creating another, for 24 hours. 1-256 characters.", - "name": "Idempotency-Key", - "in": "header" + "required": true, + "description": "The signature request's id.", + "name": "id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSignRequestRequest" - } - } - } - }, "responses": { - "201": { - "description": "The signature request (`sent`, or `draft`). A replay returns the original request in its current state.", + "200": { + "description": "The request.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54436,15 +56890,6 @@ ] } }, - "Idempotent-Replayed": { - "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", - "schema": { - "type": "string", - "enum": [ - "true" - ] - } - }, "Coss-Version": { "description": "The API version this response is rendered in.", "schema": { @@ -54464,7 +56909,7 @@ } }, "400": { - "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54526,50 +56971,8 @@ } } }, - "409": { - "description": "Requests with this `Idempotency-Key` are racing for an expired key (`request_in_progress`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "413": { - "description": "The request body is larger than 40 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "404": { + "description": "No signature request with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54590,7 +56993,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`, see `issues`), a document isn't a PDF coss.com can read (`invalid_document`) or isn't in the environment (`not_found`), a field doesn't fit on its page or names an anchor no document has (`invalid_fields`), a signer is listed twice (`invalid_signers`), `expires_at` is out of range (`invalid_expiry`), or the `Idempotency-Key` was already used with a different body (`idempotency_key_reused`).", + "description": "The request isn't `sent`, or nobody can be reminded now (`reminder_not_due`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54659,7 +57062,7 @@ } }, "503": { - "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54680,14 +57083,16 @@ } } } - }, + } + }, + "/v1/sign/requests/{id}/signed_document": { "get": { - "operationId": "listSignRequests", + "operationId": "getSignedDocument", "tags": [ "Signature requests" ], - "summary": "List signature requests", - "description": "Signature requests of the API key's environment, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", + "summary": "Download the signed document", + "description": "The completed request's sealed PDF: every document with the signatures and values filled in, then a certificate of completion (signers, how they were identified, what they agreed to, the documents' SHA-256 and the audit trail). coss.com's seal makes any later change visible in PDF viewers. Ready once `signed_document` is set, which the `sign_request.completed` webhook announces.", "security": [ { "bearerAuth": [] @@ -54697,35 +57102,15 @@ { "schema": { "type": "string", - "description": "Only requests in these statuses, comma-separated: `sent,draft`." - }, - "required": false, - "description": "Only requests in these statuses, comma-separated: `sent,draft`.", - "name": "status", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "description": "1-100, default 20." - }, - "required": false, - "description": "1-100, default 20.", - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "maxLength": 64, - "description": "Cursor: the `id` of the last item of the previous page." + "description": "The signature request's id.", + "examples": [ + "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] }, - "required": false, - "description": "Cursor: the `id` of the last item of the previous page.", - "name": "after", - "in": "query" + "required": true, + "description": "The signature request's id.", + "name": "id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" @@ -54733,7 +57118,7 @@ ], "responses": { "200": { - "description": "A page of signature requests.", + "description": "The sealed PDF.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54755,9 +57140,10 @@ } }, "content": { - "application/json": { + "application/pdf": { "schema": { - "$ref": "#/components/schemas/SignRequestList" + "type": "string", + "format": "binary" } } } @@ -54825,8 +57211,29 @@ } } }, + "404": { + "description": "No signature request with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "description": "The request isn't completed, or its document is still being sealed (`signed_document_not_ready`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54895,7 +57302,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54918,13 +57325,14 @@ } } }, - "/v1/sign/requests/{id}": { - "get": { - "operationId": "getSignRequest", + "/v1/sign/requests/{id}/signers/{signer_id}/sessions": { + "post": { + "operationId": "createSignSession", "tags": [ "Signature requests" ], - "summary": "Retrieve a signature request", + "summary": "Create a signing session", + "description": "A short-lived link to the signing page for one `embedded` signer of a sent request. Your app vouches for who the signer is (the audit trail records `customer_asserted`), so create it only for that signed-in user, when they open the page that shows it. Embed the `url` in an iframe from an origin in your Sign settings' `allowed_origins` (`mountSigning` from `coss/sign` does it), or redirect to it. Each call creates a new session.", "security": [ { "bearerAuth": [] @@ -54944,13 +57352,36 @@ "name": "id", "in": "path" }, + { + "schema": { + "type": "string", + "description": "The signer's id (`signers[].id` of the request).", + "examples": [ + "ssgn_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The signer's id (`signers[].id` of the request).", + "name": "signer_id", + "in": "path" + }, { "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": false, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignSessionRequest" + } + } + } + }, "responses": { - "200": { - "description": "The signature request.", + "201": { + "description": "The session, with its link.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -54974,7 +57405,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignRequest" + "$ref": "#/components/schemas/SignSession" } } } @@ -55043,7 +57474,28 @@ } }, "404": { - "description": "No signature request with this id exists in the API key's environment (`not_found`).", + "description": "No such signer on a signature request in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The signer signs by email (`signer_not_embedded`), already signed or declined (`signer_finished`), or the request isn't `sent` or has expired (`request_not_signable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55112,7 +57564,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55133,40 +57585,24 @@ } } } - }, - "delete": { - "operationId": "deleteSignRequest", + } + }, + "/v1/sign/settings": { + "get": { + "operationId": "getSignSettings", "tags": [ - "Signature requests" + "Sign settings" ], - "summary": "Delete a signature request", - "description": "Deletes a request that isn't `sent` (cancel it first) with its signers, fields, audit trail, signatures and signed document, for good. Its documents stay (delete them on their own). Keep the signed document first if you need it: it is your record.", + "summary": "Get the Sign settings", + "description": "The API key's environment's settings: which sites may embed the signing page, how it looks, and the consent text signers accept.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The signature request's id.", - "examples": [ - "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The signature request's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], "responses": { "200": { - "description": "The deleted request.", + "description": "The settings.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55190,7 +57626,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedSignRequest" + "$ref": "#/components/schemas/SignSettings" } } } @@ -55258,48 +57694,6 @@ } } }, - "404": { - "description": "No signature request with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The request is `sent`: cancel it first (`request_not_deletable`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -55349,7 +57743,7 @@ } }, "503": { - "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55369,43 +57763,38 @@ } } } - } - } - }, - "/v1/sign/requests/{id}/send": { - "post": { - "operationId": "sendSignRequest", + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] + }, + "patch": { + "operationId": "updateSignSettings", "tags": [ - "Signature requests" + "Sign settings" ], - "summary": "Send a draft signature request", - "description": "Sends a `draft`. An already sent request is returned as is.", + "summary": "Update the Sign settings", + "description": "Changes the fields given; the others keep their values.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The signature request's id.", - "examples": [ - "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The signature request's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSignSettingsRequest" + } + } } - ], + }, "responses": { "200": { - "description": "The sent request.", + "description": "The settings.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55429,7 +57818,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignRequest" + "$ref": "#/components/schemas/SignSettings" } } } @@ -55497,29 +57886,8 @@ } } }, - "404": { - "description": "No signature request with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "422": { - "description": "The request isn't a draft (`request_not_draft`).", + "description": "The body failed validation (`validation_error`), or an origin isn't `https://host[:port]` (`invalid_origin`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55608,43 +57976,40 @@ } } } - } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] } }, - "/v1/sign/requests/{id}/cancel": { + "/v1/sign/templates": { "post": { - "operationId": "cancelSignRequest", + "operationId": "createSignTemplate", "tags": [ - "Signature requests" + "Sign templates" ], - "summary": "Cancel a signature request", - "description": "Cancels a `draft` or `sent` request: its signers can no longer sign. An already canceled request is returned as is.", + "summary": "Create a template", + "description": "Documents with fields for roles (`client`, `company`) instead of named signers, made into requests by naming a signer per role. Fields by position or text anchor (resolved now). Can start empty and be built in the embedded builder (create a builder session).", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The signature request's id.", - "examples": [ - "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The signature request's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignTemplateRequest" + } + } } - ], + }, "responses": { - "200": { - "description": "The canceled request.", + "201": { + "description": "The template.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55668,13 +58033,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignRequest" + "$ref": "#/components/schemas/SignTemplate" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55736,8 +58101,8 @@ } } }, - "404": { - "description": "No signature request with this id exists in the API key's environment (`not_found`).", + "413": { + "description": "The request body is larger than 40 MB (`payload_too_large`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55758,7 +58123,7 @@ } }, "422": { - "description": "The request is already completed, declined or expired (`request_not_cancelable`).", + "description": "The body failed validation (`validation_error`), a document isn't a PDF coss.com can read (`invalid_document`) or isn't in the environment (`not_found`), a field doesn't fit or names an unknown role or anchor (`invalid_fields`), or a role is listed twice (`invalid_signers`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55827,7 +58192,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55847,35 +58212,48 @@ } } } - } - } - }, - "/v1/sign/requests/{id}/audit_trail": { + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] + }, "get": { - "operationId": "listSignRequestEvents", + "operationId": "listSignTemplates", "tags": [ - "Signature requests" + "Sign templates" ], - "summary": "List a signature request's audit trail", - "description": "Everything that happened to the request, oldest first: who did it, from which address, the documents' SHA-256 when it mattered, and a hash chain (`previous_hash`, `hash`) that shows the trail is complete and unchanged.", + "summary": "List templates", + "description": "Newest first. Pass the last `id` as `after` while `has_more` is true.", "security": [ { "bearerAuth": [] } ], "parameters": [ + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "1-100, default 20." + }, + "required": false, + "description": "1-100, default 20.", + "name": "limit", + "in": "query" + }, { "schema": { "type": "string", - "description": "The signature request's id.", - "examples": [ - "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] + "maxLength": 64, + "description": "Cursor: the `id` of the last item of the previous page." }, - "required": true, - "description": "The signature request's id.", - "name": "id", - "in": "path" + "required": false, + "description": "Cursor: the `id` of the last item of the previous page.", + "name": "after", + "in": "query" }, { "$ref": "#/components/parameters/CossVersion" @@ -55883,7 +58261,7 @@ ], "responses": { "200": { - "description": "The audit trail.", + "description": "A page of templates.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -55907,7 +58285,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignEventList" + "$ref": "#/components/schemas/SignTemplateList" } } } @@ -55975,8 +58353,8 @@ } } }, - "404": { - "description": "No signature request with this id exists in the API key's environment (`not_found`).", + "422": { + "description": "A query parameter failed validation (`validation_error`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56068,14 +58446,13 @@ } } }, - "/v1/sign/requests/{id}/remind": { - "post": { - "operationId": "remindSignRequest", + "/v1/sign/templates/{id}": { + "get": { + "operationId": "getSignTemplate", "tags": [ - "Signature requests" + "Sign templates" ], - "summary": "Remind signers", - "description": "Emails a reminder, with a fresh link, to every email signer of a sent request who hasn't signed and whose turn it is, unless they were emailed in the last hour. Embedded signers are yours to remind. Sent within seconds; each is a `reminded` event in the audit trail.", + "summary": "Retrieve a template", "security": [ { "bearerAuth": [] @@ -56085,13 +58462,13 @@ { "schema": { "type": "string", - "description": "The signature request's id.", + "description": "The template's id.", "examples": [ - "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" + "stpl_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The signature request's id.", + "description": "The template's id.", "name": "id", "in": "path" }, @@ -56101,7 +58478,7 @@ ], "responses": { "200": { - "description": "The request.", + "description": "The template.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56125,7 +58502,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignRequest" + "$ref": "#/components/schemas/SignTemplate" } } } @@ -56194,28 +58571,7 @@ } }, "404": { - "description": "No signature request with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The request isn't `sent`, or nobody can be reminded now (`reminder_not_due`).", + "description": "No template with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56305,16 +58661,14 @@ } } } - } - }, - "/v1/sign/requests/{id}/signed_document": { - "get": { - "operationId": "getSignedDocument", + }, + "patch": { + "operationId": "updateSignTemplate", "tags": [ - "Signature requests" + "Sign templates" ], - "summary": "Download the signed document", - "description": "The completed request's sealed PDF: every document with the signatures and values filled in, then a certificate of completion (signers, how they were identified, what they agreed to, the documents' SHA-256 and the audit trail). coss.com's seal makes any later change visible in PDF viewers. Ready once `signed_document` is set, which the `sign_request.completed` webhook announces.", + "summary": "Update a template", + "description": "Changes the fields given. `documents`, `roles` and `fields` each replace the whole list. Requests already made from it don't change.", "security": [ { "bearerAuth": [] @@ -56324,13 +58678,13 @@ { "schema": { "type": "string", - "description": "The signature request's id.", + "description": "The template's id.", "examples": [ - "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" + "stpl_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The signature request's id.", + "description": "The template's id.", "name": "id", "in": "path" }, @@ -56338,9 +58692,19 @@ "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSignTemplateRequest" + } + } + } + }, "responses": { "200": { - "description": "The sealed PDF.", + "description": "The template.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56362,16 +58726,15 @@ } }, "content": { - "application/pdf": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "$ref": "#/components/schemas/SignTemplate" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56434,7 +58797,28 @@ } }, "404": { - "description": "No signature request with this id exists in the API key's environment (`not_found`).", + "description": "No template with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "413": { + "description": "The request body is larger than 40 MB (`payload_too_large`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56455,7 +58839,7 @@ } }, "422": { - "description": "The request isn't completed, or its document is still being sealed (`signed_document_not_ready`).", + "description": "The body failed validation (`validation_error`), a document isn't a PDF coss.com can read (`invalid_document`) or isn't in the environment (`not_found`), a field doesn't fit or names an unknown role or anchor (`invalid_fields`), or a role is listed twice (`invalid_signers`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56545,16 +58929,14 @@ } } } - } - }, - "/v1/sign/requests/{id}/signers/{signer_id}/sessions": { - "post": { - "operationId": "createSignSession", + }, + "delete": { + "operationId": "deleteSignTemplate", "tags": [ - "Signature requests" + "Sign templates" ], - "summary": "Create a signing session", - "description": "A short-lived link to the signing page for one `embedded` signer of a sent request. Your app vouches for who the signer is (the audit trail records `customer_asserted`), so create it only for that signed-in user, when they open the page that shows it. Embed the `url` in an iframe from an origin in your Sign settings' `allowed_origins` (`mountSigning` from `coss/sign` does it), or redirect to it. Each call creates a new session.", + "summary": "Delete a template", + "description": "Requests made from it, and its documents, stay.", "security": [ { "bearerAuth": [] @@ -56564,46 +58946,23 @@ { "schema": { "type": "string", - "description": "The signature request's id.", + "description": "The template's id.", "examples": [ - "sreq_01k7c8m4q2f3e9v6t5r1n0p8yz" + "stpl_01k7c8m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The signature request's id.", + "description": "The template's id.", "name": "id", "in": "path" }, - { - "schema": { - "type": "string", - "description": "The signer's id (`signers[].id` of the request).", - "examples": [ - "ssgn_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The signer's id (`signers[].id` of the request).", - "name": "signer_id", - "in": "path" - }, { "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": false, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSignSessionRequest" - } - } - } - }, "responses": { - "201": { - "description": "The session, with its link.", + "200": { + "description": "The deleted template.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56627,7 +58986,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignSession" + "$ref": "#/components/schemas/DeletedSignTemplate" } } } @@ -56696,28 +59055,7 @@ } }, "404": { - "description": "No such signer on a signature request in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The signer signs by email (`signer_not_embedded`), already signed or declined (`signer_finished`), or the request isn't `sent` or has expired (`request_not_signable`).", + "description": "No template with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56786,7 +59124,7 @@ } }, "503": { - "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56809,22 +59147,65 @@ } } }, - "/v1/sign/settings": { - "get": { - "operationId": "getSignSettings", + "/v1/sign/templates/{id}/requests": { + "post": { + "operationId": "createSignRequestFromTemplate", "tags": [ - "Sign settings" + "Sign templates" ], - "summary": "Get the Sign settings", - "description": "The API key's environment's settings: which sites may embed the signing page, how it looks, and the consent text signers accept.", + "summary": "Create a request from a template", + "description": "A signature request with the template's documents and fields: name one signer for each role, and give its merge fields' values. Like creating a request, it is sent at once unless `send` is `false`, and an `Idempotency-Key` makes retries safe.", "security": [ { "bearerAuth": [] } ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The template's id.", + "examples": [ + "stpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The template's id.", + "name": "id", + "in": "path" + }, + { + "schema": { + "type": "string", + "minLength": 1, + "maxLength": 256, + "description": "Makes retries safe: a repeated request with the same key and body returns the original request (in its current state) instead of creating another, for 24 hours. 1-256 characters.", + "examples": [ + "welcome-user-123" + ] + }, + "required": false, + "description": "Makes retries safe: a repeated request with the same key and body returns the original request (in its current state) instead of creating another, for 24 hours. 1-256 characters.", + "name": "Idempotency-Key", + "in": "header" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSignRequestFromTemplateRequest" + } + } + } + }, "responses": { - "200": { - "description": "The settings.", + "201": { + "description": "The signature request.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56835,6 +59216,15 @@ ] } }, + "Idempotent-Replayed": { + "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", + "schema": { + "type": "string", + "enum": [ + "true" + ] + } + }, "Coss-Version": { "description": "The API version this response is rendered in.", "schema": { @@ -56848,13 +59238,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignSettings" + "$ref": "#/components/schemas/SignRequest" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56916,6 +59306,69 @@ } } }, + "404": { + "description": "No template with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Requests with this `Idempotency-Key` are racing (`request_in_progress`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The template isn't ready (`template_incomplete`), a role has no signer or two (`invalid_signers`), a merge field doesn't exist (`invalid_fields`), `expires_at` is out of range (`invalid_expiry`), or the `Idempotency-Key` was used with a different body (`idempotency_key_reused`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -56965,7 +59418,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -56985,38 +59438,53 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] - }, - "patch": { - "operationId": "updateSignSettings", + } + } + }, + "/v1/sign/templates/{id}/builder_sessions": { + "post": { + "operationId": "createSignBuilderSession", "tags": [ - "Sign settings" + "Sign templates" ], - "summary": "Update the Sign settings", - "description": "Changes the fields given; the others keep their values.", + "summary": "Create a builder session", + "description": "A short-lived link to the embedded builder for this template: upload documents, add roles, and drag fields onto pages. Embed it with `mountBuilder` from `coss/sign` (from an origin in your Sign settings' `allowed_origins`) for whoever edits the template.", "security": [ { "bearerAuth": [] } ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The template's id.", + "examples": [ + "stpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + }, + "required": true, + "description": "The template's id.", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], "requestBody": { - "required": true, + "required": false, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateSignSettingsRequest" + "$ref": "#/components/schemas/CreateSignBuilderSessionRequest" } } } }, "responses": { - "200": { - "description": "The settings.", + "201": { + "description": "The builder session, with its link.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57040,7 +59508,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignSettings" + "$ref": "#/components/schemas/SignBuilderSession" } } } @@ -57108,8 +59576,8 @@ } } }, - "422": { - "description": "The body failed validation (`validation_error`), or an origin isn't `https://host[:port]` (`invalid_origin`).", + "404": { + "description": "No template with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57178,7 +59646,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57198,40 +59666,55 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] + } } }, - "/v1/sign/templates": { + "/v1/verifications": { "post": { - "operationId": "createSignTemplate", + "operationId": "startVerification", "tags": [ - "Sign templates" + "Verifications" ], - "summary": "Create a template", - "description": "Documents with fields for roles (`client`, `company`) instead of named signers, made into requests by naming a signer per role. Fields by position or text anchor (resolved now). Can start empty and be built in the embedded builder (create a builder session).", + "summary": "Start a verification", + "description": "Sends a one-time code to a phone number (SMS) or an email address and returns the verification, `pending` until you check the code the end user typed (`POST /v1/verifications/check`). Starting again for the same destination while it is pending sends a new code (the earlier one stops working), up to 5 times. Before a new verification costs anything, the fraud guard checks it (your Risk lists, premium-rate numbers, Tor, and velocity per IP, user, number range and country, with how often their codes are entered): a blocked one is stored with its `reasons` and nothing is sent. Pass the end user's `ip` (and your `user_id`) so it can tell them apart. SMS codes come from coss.com's shared numbers unless the environment's Verify settings name one of your own; email codes from your sender, else coss.com's. Sandbox (`coss_test_…`) keys deliver nothing and the code is always zeros.", "security": [ { "bearerAuth": [] } ], + "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1, + "maxLength": 256, + "description": "Makes retries safe: a repeated request with the same key and body returns the original verification instead of sending another code, for 24 hours. 1-256 characters.", + "examples": [ + "welcome-user-123" + ] + }, + "required": false, + "description": "Makes retries safe: a repeated request with the same key and body returns the original verification instead of sending another code, for 24 hours. 1-256 characters.", + "name": "Idempotency-Key", + "in": "header" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateSignTemplateRequest" + "$ref": "#/components/schemas/StartVerificationRequest" } } } }, "responses": { "201": { - "description": "The template.", + "description": "The verification, `pending`, with the send that just went out.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57242,6 +59725,15 @@ ] } }, + "Idempotent-Replayed": { + "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", + "schema": { + "type": "string", + "enum": [ + "true" + ] + } + }, "Coss-Version": { "description": "The API version this response is rendered in.", "schema": { @@ -57255,13 +59747,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignTemplate" + "$ref": "#/components/schemas/Verification" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57302,6 +59794,27 @@ } } }, + "402": { + "description": "Live sending is paused for an overdue invoice or the spend limit (`billing_hold`) or a used-up budget (`budget_exceeded`), or the plan doesn't include Verify or the destination country isn't priced (`plan_feature_unavailable`) (`billing_error`). Never retried: it needs a plan change or a payment.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "403": { "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { @@ -57323,8 +59836,8 @@ } } }, - "413": { - "description": "The request body is larger than 40 MB (`payload_too_large`).", + "409": { + "description": "Requests with this `Idempotency-Key` are racing (`request_in_progress`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57334,6 +59847,12 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } + }, + "Retry-After": { + "description": "Seconds to wait before retrying.", + "schema": { + "type": "integer" + } } }, "content": { @@ -57345,7 +59864,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`), a document isn't a PDF coss.com can read (`invalid_document`) or isn't in the environment (`not_found`), a field doesn't fit or names an unknown role or anchor (`invalid_fields`), or a role is listed twice (`invalid_signers`).", + "description": "The body failed validation (`validation_error`, see `issues`); `to` isn't a valid number or address (`invalid_destination`) or its country isn't allowed (`country_not_allowed`); the fraud guard blocked it (`verification_blocked`: the verification is stored with its `reasons`); the code was already sent 5 times (`too_many_sends`); the recipient opted out or is suppressed (`recipient_suppressed`); the code couldn't be sent (`send_failed`, `sender_not_ready`…); or the `Idempotency-Key` was already used with a different body (`idempotency_key_reused`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57366,7 +59885,7 @@ } }, "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "description": "Too many requests with this API key (`rate_limited`), or too many codes to this destination or from coss.com's shared numbers today (`quota_exceeded`). Retry after `Retry-After` seconds.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57414,7 +59933,7 @@ } }, "503": { - "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", + "description": "coss.com's shared numbers aren't available for this destination (`shared_sender_unavailable`): name your own number in Verify's settings.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57434,26 +59953,51 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] + } }, "get": { - "operationId": "listSignTemplates", + "operationId": "listVerifications", "tags": [ - "Sign templates" + "Verifications" ], - "summary": "List templates", - "description": "Newest first. Pass the last `id` as `after` while `has_more` is true.", + "summary": "List verifications", + "description": "Verifications of the API key's environment, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", "security": [ { "bearerAuth": [] } ], "parameters": [ + { + "schema": { + "type": "string", + "minLength": 1, + "maxLength": 320, + "description": "Only verifications to this destination." + }, + "required": false, + "description": "Only verifications to this destination.", + "name": "to", + "in": "query" + }, + { + "schema": { + "type": "string", + "enum": [ + "pending", + "approved", + "expired", + "canceled", + "failed", + "blocked" + ], + "description": "Only verifications in this status." + }, + "required": false, + "description": "Only verifications in this status.", + "name": "status", + "in": "query" + }, { "schema": { "type": "integer", @@ -57483,7 +60027,7 @@ ], "responses": { "200": { - "description": "A page of templates.", + "description": "A page of verifications.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57507,7 +60051,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignTemplateList" + "$ref": "#/components/schemas/VerificationList" } } } @@ -57576,7 +60120,7 @@ } }, "422": { - "description": "A query parameter failed validation (`validation_error`).", + "description": "A query parameter failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57668,13 +60212,14 @@ } } }, - "/v1/sign/templates/{id}": { - "get": { - "operationId": "getSignTemplate", + "/v1/verifications/check": { + "post": { + "operationId": "checkVerification", "tags": [ - "Sign templates" + "Verifications" ], - "summary": "Retrieve a template", + "summary": "Check a code", + "description": "Checks the code the end user typed, by the verification's id or by the destination (its latest verification). `valid: true` approves it (`verification.approved`, billed once); a wrong code spends an attempt, and the last one fails it. Checking an approved verification again with its code stays valid until it expires, without being billed again.", "security": [ { "bearerAuth": [] @@ -57684,23 +60229,35 @@ { "schema": { "type": "string", - "description": "The template's id.", + "minLength": 1, + "maxLength": 256, + "description": "Makes retries safe: a repeated check with the same key returns the same answer without spending another attempt. 1-256 characters.", "examples": [ - "stpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + "welcome-user-123" ] }, - "required": true, - "description": "The template's id.", - "name": "id", - "in": "path" + "required": false, + "description": "Makes retries safe: a repeated check with the same key returns the same answer without spending another attempt. 1-256 characters.", + "name": "Idempotency-Key", + "in": "header" }, { "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CheckVerificationRequest" + } + } + } + }, "responses": { "200": { - "description": "The template.", + "description": "Whether the code is right, and the verification after the check.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57724,13 +60281,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignTemplate" + "$ref": "#/components/schemas/VerificationCheck" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57793,7 +60350,28 @@ } }, "404": { - "description": "No template with this id exists in the API key's environment (`not_found`).", + "description": "No such verification in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The body failed validation (`validation_error`, see `issues`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57814,7 +60392,7 @@ } }, "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", + "description": "Too many requests with this API key (`rate_limited`), or too many checks for this destination (`quota_exceeded`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57883,14 +60461,15 @@ } } } - }, - "patch": { - "operationId": "updateSignTemplate", + } + }, + "/v1/verifications/{id}": { + "get": { + "operationId": "getVerification", "tags": [ - "Sign templates" + "Verifications" ], - "summary": "Update a template", - "description": "Changes the fields given. `documents`, `roles` and `fields` each replace the whole list. Requests already made from it don't change.", + "summary": "Retrieve a verification", "security": [ { "bearerAuth": [] @@ -57900,13 +60479,13 @@ { "schema": { "type": "string", - "description": "The template's id.", + "description": "The verification's id.", "examples": [ - "stpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + "vrf_01k8e2m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The template's id.", + "description": "The verification's id.", "name": "id", "in": "path" }, @@ -57914,19 +60493,9 @@ "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateSignTemplateRequest" - } - } - } - }, "responses": { "200": { - "description": "The template.", + "description": "The verification.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -57950,13 +60519,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignTemplate" + "$ref": "#/components/schemas/Verification" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58019,49 +60588,7 @@ } }, "404": { - "description": "No template with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "413": { - "description": "The request body is larger than 40 MB (`payload_too_large`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The body failed validation (`validation_error`), a document isn't a PDF coss.com can read (`invalid_document`) or isn't in the environment (`not_found`), a field doesn't fit or names an unknown role or anchor (`invalid_fields`), or a role is listed twice (`invalid_signers`).", + "description": "No such verification in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58130,7 +60657,7 @@ } }, "503": { - "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58151,14 +60678,16 @@ } } } - }, - "delete": { - "operationId": "deleteSignTemplate", + } + }, + "/v1/verifications/{id}/cancel": { + "post": { + "operationId": "cancelVerification", "tags": [ - "Sign templates" + "Verifications" ], - "summary": "Delete a template", - "description": "Requests made from it, and its documents, stay.", + "summary": "Cancel a verification", + "description": "Cancels a pending verification: its code stops working. Canceling it again returns it as is.", "security": [ { "bearerAuth": [] @@ -58168,13 +60697,13 @@ { "schema": { "type": "string", - "description": "The template's id.", + "description": "The verification's id.", "examples": [ - "stpl_01k7c8m4q2f3e9v6t5r1n0p8yz" + "vrf_01k8e2m4q2f3e9v6t5r1n0p8yz" ] }, "required": true, - "description": "The template's id.", + "description": "The verification's id.", "name": "id", "in": "path" }, @@ -58184,7 +60713,7 @@ ], "responses": { "200": { - "description": "The deleted template.", + "description": "The canceled verification.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58208,7 +60737,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedSignTemplate" + "$ref": "#/components/schemas/Verification" } } } @@ -58277,7 +60806,28 @@ } }, "404": { - "description": "No template with this id exists in the API key's environment (`not_found`).", + "description": "No such verification in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The verification isn't pending (`verification_not_cancelable`): approved, failed, blocked or expired.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58369,65 +60919,22 @@ } } }, - "/v1/sign/templates/{id}/requests": { - "post": { - "operationId": "createSignRequestFromTemplate", + "/v1/verify/settings": { + "get": { + "operationId": "getVerifySettings", "tags": [ - "Sign templates" + "Verify settings" ], - "summary": "Create a request from a template", - "description": "A signature request with the template's documents and fields: name one signer for each role, and give its merge fields' values. Like creating a request, it is sent at once unless `send` is `false`, and an `Idempotency-Key` makes retries safe.", + "summary": "Get the Verify settings", + "description": "The API key's environment's settings, with defaults filled in: the name codes are sent for, code length, lifetime and attempts, the senders, and the countries SMS codes may go to.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The template's id.", - "examples": [ - "stpl_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The template's id.", - "name": "id", - "in": "path" - }, - { - "schema": { - "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "Makes retries safe: a repeated request with the same key and body returns the original request (in its current state) instead of creating another, for 24 hours. 1-256 characters.", - "examples": [ - "welcome-user-123" - ] - }, - "required": false, - "description": "Makes retries safe: a repeated request with the same key and body returns the original request (in its current state) instead of creating another, for 24 hours. 1-256 characters.", - "name": "Idempotency-Key", - "in": "header" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateSignRequestFromTemplateRequest" - } - } - } - }, "responses": { - "201": { - "description": "The signature request.", + "200": { + "description": "The settings.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58438,15 +60945,6 @@ ] } }, - "Idempotent-Replayed": { - "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", - "schema": { - "type": "string", - "enum": [ - "true" - ] - } - }, "Coss-Version": { "description": "The API version this response is rendered in.", "schema": { @@ -58460,13 +60958,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignRequest" + "$ref": "#/components/schemas/VerifySettings" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58528,69 +61026,6 @@ } } }, - "404": { - "description": "No template with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "409": { - "description": "Requests with this `Idempotency-Key` are racing (`request_in_progress`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The template isn't ready (`template_incomplete`), a role has no signer or two (`invalid_signers`), a merge field doesn't exist (`invalid_fields`), `expires_at` is out of range (`invalid_expiry`), or the `Idempotency-Key` was used with a different body (`idempotency_key_reused`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -58640,7 +61075,7 @@ } }, "503": { - "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58660,53 +61095,38 @@ } } } - } - } - }, - "/v1/sign/templates/{id}/builder_sessions": { - "post": { - "operationId": "createSignBuilderSession", + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] + }, + "patch": { + "operationId": "updateVerifySettings", "tags": [ - "Sign templates" + "Verify settings" ], - "summary": "Create a builder session", - "description": "A short-lived link to the embedded builder for this template: upload documents, add roles, and drag fields onto pages. Embed it with `mountBuilder` from `coss/sign` (from an origin in your Sign settings' `allowed_origins`) for whoever edits the template.", + "summary": "Update the Verify settings", + "description": "Changes the fields given; the others keep their values. `sms_from` must be one of the organization's numbers, and a live key's `email_from` must be on one of its verified domains.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The template's id.", - "examples": [ - "stpl_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - }, - "required": true, - "description": "The template's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], "requestBody": { - "required": false, + "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateSignBuilderSessionRequest" + "$ref": "#/components/schemas/UpdateVerifySettingsRequest" } } } }, "responses": { - "201": { - "description": "The builder session, with its link.", + "200": { + "description": "The settings.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58730,7 +61150,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SignBuilderSession" + "$ref": "#/components/schemas/VerifySettings" } } } @@ -58798,8 +61218,8 @@ } } }, - "404": { - "description": "No template with this id exists in the API key's environment (`not_found`).", + "422": { + "description": "The body failed validation (`validation_error`), or a sender isn't the organization's (`invalid_settings`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58868,7 +61288,7 @@ } }, "503": { - "description": "Sign isn't available in this deployment yet (`sign_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58888,55 +61308,40 @@ } } } - } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] } }, - "/v1/verifications": { + "/v1/forms": { "post": { - "operationId": "startVerification", + "operationId": "createForm", "tags": [ - "Verifications" + "Forms" ], - "summary": "Start a verification", - "description": "Sends a one-time code to a phone number (SMS) or an email address and returns the verification, `pending` until you check the code the end user typed (`POST /v1/verifications/check`). Starting again for the same destination while it is pending sends a new code (the earlier one stops working), up to 5 times. Before a new verification costs anything, the fraud guard checks it (your Risk lists, premium-rate numbers, Tor, and velocity per IP, user, number range and country, with how often their codes are entered): a blocked one is stored with its `reasons` and nothing is sent. Pass the end user's `ip` (and your `user_id`) so it can tell them apart. SMS codes come from coss.com's shared numbers unless the environment's Verify settings name one of your own; email codes from your sender, else coss.com's. Sandbox (`coss_test_…`) keys deliver nothing and the code is always zeros.", + "summary": "Create a form", + "description": "A hosted form endpoint: point an HTML `
` (or `coss/forms`) at its `endpoint`. Every submission is screened by Risk (the honeypot, captcha, email, IP, device, velocity and content) and accepted ones go to webhooks (`form.submission.received`), notification emails and contacts. Without `fields`, any field is accepted.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "Makes retries safe: a repeated request with the same key and body returns the original verification instead of sending another code, for 24 hours. 1-256 characters.", - "examples": [ - "welcome-user-123" - ] - }, - "required": false, - "description": "Makes retries safe: a repeated request with the same key and body returns the original verification instead of sending another code, for 24 hours. 1-256 characters.", - "name": "Idempotency-Key", - "in": "header" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/StartVerificationRequest" + "$ref": "#/components/schemas/CreateFormRequest" } } } }, "responses": { "201": { - "description": "The verification, `pending`, with the send that just went out.", + "description": "The form.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -58947,15 +61352,6 @@ ] } }, - "Idempotent-Replayed": { - "description": "`true` when this response replays an earlier request with the same `Idempotency-Key`.", - "schema": { - "type": "string", - "enum": [ - "true" - ] - } - }, "Coss-Version": { "description": "The API version this response is rendered in.", "schema": { @@ -58969,13 +61365,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Verification" + "$ref": "#/components/schemas/Form" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59016,27 +61412,6 @@ } } }, - "402": { - "description": "Live sending is paused for an overdue invoice or the spend limit (`billing_hold`) or a used-up budget (`budget_exceeded`), or the plan doesn't include Verify or the destination country isn't priced (`plan_feature_unavailable`) (`billing_error`). Never retried: it needs a plan change or a payment.", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "403": { "description": "The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).", "headers": { @@ -59058,8 +61433,8 @@ } } }, - "409": { - "description": "Requests with this `Idempotency-Key` are racing (`request_in_progress`).", + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59069,12 +61444,6 @@ "req_01k7c8m4q2f3e9v6t5r1n0p8yz" ] } - }, - "Retry-After": { - "description": "Seconds to wait before retrying.", - "schema": { - "type": "integer" - } } }, "content": { @@ -59086,7 +61455,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`, see `issues`); `to` isn't a valid number or address (`invalid_destination`) or its country isn't allowed (`country_not_allowed`); the fraud guard blocked it (`verification_blocked`: the verification is stored with its `reasons`); the code was already sent 5 times (`too_many_sends`); the recipient opted out or is suppressed (`recipient_suppressed`); the code couldn't be sent (`send_failed`, `sender_not_ready`…); or the `Idempotency-Key` was already used with a different body (`idempotency_key_reused`).", + "description": "The body failed validation (`validation_error`), or the form can't be saved: duplicate or misplaced fields (`invalid_fields`), an origin or redirect that isn't https (`invalid_origin`, `invalid_redirect`), a sender or recipient that isn't verified (`invalid_sender`, `invalid_recipient`), an unknown audience, topic or property (`invalid_contacts`), no captcha in the risk settings (`captcha_not_configured`), a hosted page without fields or asking for credentials (`hosted_needs_fields`, `hosted_content_refused`), or too many forms (`form_limit_reached`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59107,7 +61476,7 @@ } }, "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many codes to this destination or from coss.com's shared numbers today (`quota_exceeded`). Retry after `Retry-After` seconds.", + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59155,7 +61524,7 @@ } }, "503": { - "description": "coss.com's shared numbers aren't available for this destination (`shared_sender_unavailable`): name your own number in Verify's settings.", + "description": "Forms isn't available in this deployment yet (`forms_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59175,51 +61544,26 @@ } } } - } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] }, "get": { - "operationId": "listVerifications", + "operationId": "listForms", "tags": [ - "Verifications" + "Forms" ], - "summary": "List verifications", - "description": "Verifications of the API key's environment, newest first. Pass the last `id` as `after` to get the next page while `has_more` is true.", + "summary": "List forms", + "description": "The environment's forms, newest first.", "security": [ { "bearerAuth": [] } ], "parameters": [ - { - "schema": { - "type": "string", - "minLength": 1, - "maxLength": 320, - "description": "Only verifications to this destination." - }, - "required": false, - "description": "Only verifications to this destination.", - "name": "to", - "in": "query" - }, - { - "schema": { - "type": "string", - "enum": [ - "pending", - "approved", - "expired", - "canceled", - "failed", - "blocked" - ], - "description": "Only verifications in this status." - }, - "required": false, - "description": "Only verifications in this status.", - "name": "status", - "in": "query" - }, { "schema": { "type": "integer", @@ -59249,7 +61593,7 @@ ], "responses": { "200": { - "description": "A page of verifications.", + "description": "A page of forms.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59273,7 +61617,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VerificationList" + "$ref": "#/components/schemas/FormList" } } } @@ -59411,7 +61755,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Forms isn't available in this deployment yet (`forms_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59434,14 +61778,13 @@ } } }, - "/v1/verifications/check": { - "post": { - "operationId": "checkVerification", + "/v1/forms/{id}": { + "get": { + "operationId": "getForm", "tags": [ - "Verifications" + "Forms" ], - "summary": "Check a code", - "description": "Checks the code the end user typed, by the verification's id or by the destination (its latest verification). `valid: true` approves it (`verification.approved`, billed once); a wrong code spends an attempt, and the last one fails it. Checking an approved verification again with its code stays valid until it expires, without being billed again.", + "summary": "Get a form", "security": [ { "bearerAuth": [] @@ -59451,35 +61794,23 @@ { "schema": { "type": "string", - "minLength": 1, - "maxLength": 256, - "description": "Makes retries safe: a repeated check with the same key returns the same answer without spending another attempt. 1-256 characters.", + "description": "The form's id.", "examples": [ - "welcome-user-123" + "form_01kd2m8n3p4q5r6s7t8v9w0x1y" ] }, - "required": false, - "description": "Makes retries safe: a repeated check with the same key returns the same answer without spending another attempt. 1-256 characters.", - "name": "Idempotency-Key", - "in": "header" + "required": true, + "description": "The form's id.", + "name": "id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CheckVerificationRequest" - } - } - } - }, "responses": { "200": { - "description": "Whether the code is right, and the verification after the check.", + "description": "The form.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59503,13 +61834,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VerificationCheck" + "$ref": "#/components/schemas/Form" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`) or the `Idempotency-Key` header is invalid (`invalid_idempotency_key`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59572,28 +61903,7 @@ } }, "404": { - "description": "No such verification in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The body failed validation (`validation_error`, see `issues`).", + "description": "No form with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59614,7 +61924,7 @@ } }, "429": { - "description": "Too many requests with this API key (`rate_limited`), or too many checks for this destination (`quota_exceeded`).", + "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59662,7 +61972,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Forms isn't available in this deployment yet (`forms_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59683,15 +61993,14 @@ } } } - } - }, - "/v1/verifications/{id}": { - "get": { - "operationId": "getVerification", + }, + "patch": { + "operationId": "updateForm", "tags": [ - "Verifications" + "Forms" ], - "summary": "Retrieve a verification", + "summary": "Update a form", + "description": "Only the fields given change, within each group (`spam`, `contacts`, …) too.", "security": [ { "bearerAuth": [] @@ -59701,13 +62010,13 @@ { "schema": { "type": "string", - "description": "The verification's id.", + "description": "The form's id.", "examples": [ - "vrf_01k8e2m4q2f3e9v6t5r1n0p8yz" + "form_01kd2m8n3p4q5r6s7t8v9w0x1y" ] }, "required": true, - "description": "The verification's id.", + "description": "The form's id.", "name": "id", "in": "path" }, @@ -59715,9 +62024,19 @@ "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateFormRequest" + } + } + } + }, "responses": { "200": { - "description": "The verification.", + "description": "The form.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59741,13 +62060,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Verification" + "$ref": "#/components/schemas/Form" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59810,7 +62129,76 @@ } }, "404": { - "description": "No such verification in the API key's environment (`not_found`).", + "description": "No form with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "409": { + "description": "Other updates of this form kept racing this one (`form_conflict`). Retry after `Retry-After` seconds.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Retry-After": { + "description": "Seconds to wait.", + "schema": { + "type": "integer" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The body failed validation (`validation_error`), or the form can't be saved: duplicate or misplaced fields (`invalid_fields`), an origin or redirect that isn't https (`invalid_origin`, `invalid_redirect`), a sender or recipient that isn't verified (`invalid_sender`, `invalid_recipient`), an unknown audience, topic or property (`invalid_contacts`), no captcha in the risk settings (`captcha_not_configured`), a hosted page without fields or asking for credentials (`hosted_needs_fields`, `hosted_content_refused`), or too many forms (`form_limit_reached`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59879,7 +62267,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Forms isn't available in this deployment yet (`forms_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59900,16 +62288,14 @@ } } } - } - }, - "/v1/verifications/{id}/cancel": { - "post": { - "operationId": "cancelVerification", + }, + "delete": { + "operationId": "deleteForm", "tags": [ - "Verifications" + "Forms" ], - "summary": "Cancel a verification", - "description": "Cancels a pending verification: its code stops working. Canceling it again returns it as is.", + "summary": "Delete a form", + "description": "Deletes the form with every submission and uploaded file. Its endpoint answers 404 from then on.", "security": [ { "bearerAuth": [] @@ -59919,13 +62305,13 @@ { "schema": { "type": "string", - "description": "The verification's id.", + "description": "The form's id.", "examples": [ - "vrf_01k8e2m4q2f3e9v6t5r1n0p8yz" + "form_01kd2m8n3p4q5r6s7t8v9w0x1y" ] }, "required": true, - "description": "The verification's id.", + "description": "The form's id.", "name": "id", "in": "path" }, @@ -59935,7 +62321,7 @@ ], "responses": { "200": { - "description": "The canceled verification.", + "description": "The form was deleted.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -59959,7 +62345,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Verification" + "$ref": "#/components/schemas/DeletedForm" } } } @@ -60028,28 +62414,7 @@ } }, "404": { - "description": "No such verification in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The verification isn't pending (`verification_not_cancelable`): approved, failed, blocked or expired.", + "description": "No form with this id exists in the API key's environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -60118,7 +62483,7 @@ } }, "503": { - "description": "The API key could not be verified right now; retry (`service_unavailable`).", + "description": "Forms isn't available in this deployment yet (`forms_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -60141,22 +62506,73 @@ } } }, - "/v1/verify/settings": { + "/v1/forms/{id}/submissions": { "get": { - "operationId": "getVerifySettings", + "operationId": "listFormSubmissions", "tags": [ - "Verify settings" + "Form submissions" ], - "summary": "Get the Verify settings", - "description": "The API key's environment's settings, with defaults filled in: the name codes are sent for, code length, lifetime and attempts, the senders, and the countries SMS codes may go to.", + "summary": "List a form's submissions", + "description": "Newest first. `status` narrows them: `accepted` (delivered), `held` (Risk asked for a review), `spam` and `pending_confirmation` (waiting for the submitter's email link).", "security": [ { "bearerAuth": [] } ], + "parameters": [ + { + "schema": { + "type": "string", + "description": "The form's id.", + "examples": [ + "form_01kd2m8n3p4q5r6s7t8v9w0x1y" + ] + }, + "required": true, + "description": "The form's id.", + "name": "id", + "in": "path" + }, + { + "schema": { + "type": "string", + "description": "Only submissions in these statuses, comma-separated: `held,spam`." + }, + "required": false, + "description": "Only submissions in these statuses, comma-separated: `held,spam`.", + "name": "status", + "in": "query" + }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "description": "1-100, default 20." + }, + "required": false, + "description": "1-100, default 20.", + "name": "limit", + "in": "query" + }, + { + "schema": { + "type": "string", + "maxLength": 64, + "description": "Cursor: the `id` of the last item of the previous page." + }, + "required": false, + "description": "Cursor: the `id` of the last item of the previous page.", + "name": "after", + "in": "query" + }, + { + "$ref": "#/components/parameters/CossVersion" + } + ], "responses": { "200": { - "description": "The settings.", + "description": "A page of submissions.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -60180,7 +62596,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VerifySettings" + "$ref": "#/components/schemas/FormSubmissionList" } } } @@ -60248,6 +62664,48 @@ } } }, + "404": { + "description": "No form with this id exists in the API key's environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "429": { "description": "Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).", "headers": { @@ -60317,38 +62775,55 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] - }, - "patch": { - "operationId": "updateVerifySettings", + } + } + }, + "/v1/forms/{id}/submissions/{submission_id}": { + "get": { + "operationId": "getFormSubmission", "tags": [ - "Verify settings" + "Form submissions" ], - "summary": "Update the Verify settings", - "description": "Changes the fields given; the others keep their values. `sms_from` must be one of the organization's numbers, and a live key's `email_from` must be on one of its verified domains.", + "summary": "Get a submission", "security": [ { "bearerAuth": [] } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/UpdateVerifySettingsRequest" - } - } + "parameters": [ + { + "schema": { + "type": "string", + "description": "The form's id.", + "examples": [ + "form_01kd2m8n3p4q5r6s7t8v9w0x1y" + ] + }, + "required": true, + "description": "The form's id.", + "name": "id", + "in": "path" + }, + { + "schema": { + "type": "string", + "description": "The submission's id.", + "examples": [ + "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k" + ] + }, + "required": true, + "description": "The submission's id.", + "name": "submission_id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" } - }, + ], "responses": { "200": { - "description": "The settings.", + "description": "The submission.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -60372,7 +62847,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/VerifySettings" + "$ref": "#/components/schemas/FormSubmission" } } } @@ -60440,8 +62915,8 @@ } } }, - "422": { - "description": "The body failed validation (`validation_error`), or a sender isn't the organization's (`invalid_settings`).", + "404": { + "description": "No such form, or no submission with this id in it (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -60530,40 +63005,54 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] - } - }, - "/v1/forms": { - "post": { - "operationId": "createForm", + } + }, + "delete": { + "operationId": "deleteFormSubmission", "tags": [ - "Forms" + "Form submissions" ], - "summary": "Create a form", - "description": "A hosted form endpoint: point an HTML `` (or `coss/forms`) at its `endpoint`. Every submission is screened by Risk (the honeypot, captcha, email, IP, device, velocity and content) and accepted ones go to webhooks (`form.submission.received`), notification emails and contacts. Without `fields`, any field is accepted.", + "summary": "Delete a submission", + "description": "Deletes the submission and its files.", "security": [ { "bearerAuth": [] } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateFormRequest" - } - } + "parameters": [ + { + "schema": { + "type": "string", + "description": "The form's id.", + "examples": [ + "form_01kd2m8n3p4q5r6s7t8v9w0x1y" + ] + }, + "required": true, + "description": "The form's id.", + "name": "id", + "in": "path" + }, + { + "schema": { + "type": "string", + "description": "The submission's id.", + "examples": [ + "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k" + ] + }, + "required": true, + "description": "The submission's id.", + "name": "submission_id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" } - }, + ], "responses": { - "201": { - "description": "The form.", + "200": { + "description": "The submission was deleted.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -60587,13 +63076,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Form" + "$ref": "#/components/schemas/DeletedFormSubmission" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -60655,29 +63144,8 @@ } } }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The body failed validation (`validation_error`), or the form can't be saved: duplicate or misplaced fields (`invalid_fields`), an origin or redirect that isn't https (`invalid_origin`, `invalid_redirect`), a sender or recipient that isn't verified (`invalid_sender`, `invalid_recipient`), an unknown audience, topic or property (`invalid_contacts`), no captcha in the risk settings (`captcha_not_configured`), a hosted page without fields or asking for credentials (`hosted_needs_fields`, `hosted_content_refused`), or too many forms (`form_limit_reached`).", + "404": { + "description": "No such form, or no submission with this id in it (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -60746,7 +63214,7 @@ } }, "503": { - "description": "Forms isn't available in this deployment yet (`forms_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -60766,20 +63234,17 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] - }, - "get": { - "operationId": "listForms", + } + } + }, + "/v1/forms/{id}/submissions/{submission_id}/release": { + "post": { + "operationId": "releaseFormSubmission", "tags": [ - "Forms" + "Form submissions" ], - "summary": "List forms", - "description": "The environment's forms, newest first.", + "summary": "Release a submission", + "description": "Not spam: a `held` or `spam` submission becomes `accepted` and is delivered (webhooks, notifications, contacts), and Risk records its assessment as `legitimate`. Releasing an accepted submission returns it as is.", "security": [ { "bearerAuth": [] @@ -60788,26 +63253,29 @@ "parameters": [ { "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "description": "1-100, default 20." + "type": "string", + "description": "The form's id.", + "examples": [ + "form_01kd2m8n3p4q5r6s7t8v9w0x1y" + ] }, - "required": false, - "description": "1-100, default 20.", - "name": "limit", - "in": "query" + "required": true, + "description": "The form's id.", + "name": "id", + "in": "path" }, { "schema": { "type": "string", - "maxLength": 64, - "description": "Cursor: the `id` of the last item of the previous page." + "description": "The submission's id.", + "examples": [ + "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k" + ] }, - "required": false, - "description": "Cursor: the `id` of the last item of the previous page.", - "name": "after", - "in": "query" + "required": true, + "description": "The submission's id.", + "name": "submission_id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" @@ -60815,7 +63283,7 @@ ], "responses": { "200": { - "description": "A page of forms.", + "description": "The released submission.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -60839,7 +63307,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FormList" + "$ref": "#/components/schemas/FormSubmission" } } } @@ -60907,8 +63375,29 @@ } } }, + "404": { + "description": "No such form, or no submission with this id in it (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "description": "Only held and spam submissions can be released (`submission_not_releasable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -60977,7 +63466,7 @@ } }, "503": { - "description": "Forms isn't available in this deployment yet (`forms_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -61000,13 +63489,14 @@ } } }, - "/v1/forms/{id}": { + "/v1/forms/{id}/submissions/{submission_id}/files/{file_id}": { "get": { - "operationId": "getForm", + "operationId": "getFormSubmissionFile", "tags": [ - "Forms" + "Form submissions" ], - "summary": "Get a form", + "summary": "Download a file", + "description": "A file uploaded with the submission, as `application/octet-stream`: whatever its type, treat it as untrusted (a submitter chose it).", "security": [ { "bearerAuth": [] @@ -61026,13 +63516,39 @@ "name": "id", "in": "path" }, + { + "schema": { + "type": "string", + "description": "The submission's id.", + "examples": [ + "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k" + ] + }, + "required": true, + "description": "The submission's id.", + "name": "submission_id", + "in": "path" + }, + { + "schema": { + "type": "string", + "description": "The file's id (`files[].id` of the submission).", + "examples": [ + "ffile_01kd2m9a0b1c2d3e4f5g6h7j8m" + ] + }, + "required": true, + "description": "The file's id (`files[].id` of the submission).", + "name": "file_id", + "in": "path" + }, { "$ref": "#/components/parameters/CossVersion" } ], "responses": { "200": { - "description": "The form.", + "description": "The file's bytes.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -61054,9 +63570,10 @@ } }, "content": { - "application/json": { + "application/octet-stream": { "schema": { - "$ref": "#/components/schemas/Form" + "type": "string", + "format": "binary" } } } @@ -61125,7 +63642,7 @@ } }, "404": { - "description": "No form with this id exists in the API key's environment (`not_found`).", + "description": "No such form, submission or file (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -61215,50 +63732,34 @@ } } } - }, - "patch": { - "operationId": "updateForm", + } + }, + "/v1/scheduling/hosts": { + "post": { + "operationId": "createSchedulingHost", "tags": [ - "Forms" + "Scheduling hosts" ], - "summary": "Update a form", - "description": "Only the fields given change, within each group (`spam`, `contacts`, …) too.", + "summary": "Create a host", + "description": "A person who can be booked: one of your users, such as a doctor or a tutor.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The form's id.", - "examples": [ - "form_01kd2m8n3p4q5r6s7t8v9w0x1y" - ] - }, - "required": true, - "description": "The form's id.", - "name": "id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" - } - ], "requestBody": { "required": true, "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateFormRequest" + "$ref": "#/components/schemas/CreateHostRequest" } } } }, "responses": { - "200": { - "description": "The form.", + "201": { + "description": "The host.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -61282,7 +63783,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Form" + "$ref": "#/components/schemas/SchedulingHost" } } } @@ -61350,54 +63851,6 @@ } } }, - "404": { - "description": "No form with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "409": { - "description": "Other updates of this form kept racing this one (`form_conflict`). Retry after `Retry-After` seconds.", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - }, - "Retry-After": { - "description": "Seconds to wait.", - "schema": { - "type": "integer" - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, "415": { "description": "The body is not sent as `application/json` (`unsupported_media_type`).", "headers": { @@ -61420,7 +63873,7 @@ } }, "422": { - "description": "The body failed validation (`validation_error`), or the form can't be saved: duplicate or misplaced fields (`invalid_fields`), an origin or redirect that isn't https (`invalid_origin`, `invalid_redirect`), a sender or recipient that isn't verified (`invalid_sender`, `invalid_recipient`), an unknown audience, topic or property (`invalid_contacts`), no captcha in the risk settings (`captcha_not_configured`), a hosted page without fields or asking for credentials (`hosted_needs_fields`, `hosted_content_refused`), or too many forms (`form_limit_reached`).", + "description": "The request failed validation (`validation_error`, see `issues`), or can't be done: see `code`.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -61489,7 +63942,7 @@ } }, "503": { - "description": "Forms isn't available in this deployment yet (`forms_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -61509,33 +63962,46 @@ } } } - } + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] }, - "delete": { - "operationId": "deleteForm", + "get": { + "operationId": "listSchedulingHosts", "tags": [ - "Forms" + "Scheduling hosts" ], - "summary": "Delete a form", - "description": "Deletes the form with every submission and uploaded file. Its endpoint answers 404 from then on.", + "summary": "List hosts", + "description": "The environment's hosts, newest first.", "security": [ { "bearerAuth": [] } ], "parameters": [ + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20 + }, + "required": false, + "name": "limit", + "in": "query" + }, { "schema": { "type": "string", - "description": "The form's id.", - "examples": [ - "form_01kd2m8n3p4q5r6s7t8v9w0x1y" - ] + "description": "The last id of the previous page." }, - "required": true, - "description": "The form's id.", - "name": "id", - "in": "path" + "required": false, + "description": "The last id of the previous page.", + "name": "after", + "in": "query" }, { "$ref": "#/components/parameters/CossVersion" @@ -61543,7 +64009,7 @@ ], "responses": { "200": { - "description": "The form was deleted.", + "description": "A page of hosts.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -61567,7 +64033,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedForm" + "$ref": "#/components/schemas/SchedulingHostList" } } } @@ -61635,8 +64101,8 @@ } } }, - "404": { - "description": "No form with this id exists in the API key's environment (`not_found`).", + "422": { + "description": "The request failed validation (`validation_error`, see `issues`), or can't be done: see `code`.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -61705,7 +64171,7 @@ } }, "503": { - "description": "Forms isn't available in this deployment yet (`forms_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -61728,14 +64194,14 @@ } } }, - "/v1/forms/{id}/submissions": { + "/v1/scheduling/hosts/{host}": { "get": { - "operationId": "listFormSubmissions", + "operationId": "getSchedulingHost", "tags": [ - "Form submissions" + "Scheduling hosts" ], - "summary": "List a form's submissions", - "description": "Newest first. `status` narrows them: `accepted` (delivered), `held` (Risk asked for a review), `spam` and `pending_confirmation` (waiting for the submitter's email link).", + "summary": "Retrieve a host", + "description": "A host by its id or your uid.", "security": [ { "bearerAuth": [] @@ -61745,56 +64211,23 @@ { "schema": { "type": "string", - "description": "The form's id.", + "description": "The host's id or uid.", "examples": [ - "form_01kd2m8n3p4q5r6s7t8v9w0x1y" + "host_01kd2m9a0b1c2d3e4f5g6h7j8m" ] }, "required": true, - "description": "The form's id.", - "name": "id", + "description": "The host's id or uid.", + "name": "host", "in": "path" }, - { - "schema": { - "type": "string", - "description": "Only submissions in these statuses, comma-separated: `held,spam`." - }, - "required": false, - "description": "Only submissions in these statuses, comma-separated: `held,spam`.", - "name": "status", - "in": "query" - }, - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "description": "1-100, default 20." - }, - "required": false, - "description": "1-100, default 20.", - "name": "limit", - "in": "query" - }, - { - "schema": { - "type": "string", - "maxLength": 64, - "description": "Cursor: the `id` of the last item of the previous page." - }, - "required": false, - "description": "Cursor: the `id` of the last item of the previous page.", - "name": "after", - "in": "query" - }, { "$ref": "#/components/parameters/CossVersion" } ], "responses": { "200": { - "description": "A page of submissions.", + "description": "The host.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -61818,7 +64251,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FormSubmissionList" + "$ref": "#/components/schemas/SchedulingHost" } } } @@ -61887,28 +64320,7 @@ } }, "404": { - "description": "No form with this id exists in the API key's environment (`not_found`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "A query parameter failed validation (`validation_error`, see `issues`).", + "description": "Nothing with this id or uid exists in the environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -61998,15 +64410,14 @@ } } } - } - }, - "/v1/forms/{id}/submissions/{submission_id}": { - "get": { - "operationId": "getFormSubmission", + }, + "patch": { + "operationId": "updateSchedulingHost", "tags": [ - "Form submissions" + "Scheduling hosts" ], - "summary": "Get a submission", + "summary": "Update a host", + "description": "Changes what's given. A `disabled` host keeps its bookings but gets no new ones.", "security": [ { "bearerAuth": [] @@ -62016,36 +64427,33 @@ { "schema": { "type": "string", - "description": "The form's id.", - "examples": [ - "form_01kd2m8n3p4q5r6s7t8v9w0x1y" - ] - }, - "required": true, - "description": "The form's id.", - "name": "id", - "in": "path" - }, - { - "schema": { - "type": "string", - "description": "The submission's id.", + "description": "The host's id or uid.", "examples": [ - "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k" + "host_01kd2m9a0b1c2d3e4f5g6h7j8m" ] }, "required": true, - "description": "The submission's id.", - "name": "submission_id", + "description": "The host's id or uid.", + "name": "host", "in": "path" }, { "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateHostRequest" + } + } + } + }, "responses": { "200": { - "description": "The submission.", + "description": "The host.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62069,13 +64477,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FormSubmission" + "$ref": "#/components/schemas/SchedulingHost" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62138,7 +64546,49 @@ } }, "404": { - "description": "No such form, or no submission with this id in it (`not_found`).", + "description": "Nothing with this id or uid exists in the environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The request failed validation (`validation_error`, see `issues`), or can't be done: see `code`.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62230,12 +64680,12 @@ } }, "delete": { - "operationId": "deleteFormSubmission", + "operationId": "deleteSchedulingHost", "tags": [ - "Form submissions" + "Scheduling hosts" ], - "summary": "Delete a submission", - "description": "Deletes the submission and its files.", + "summary": "Delete a host", + "description": "Removes the host and its schedules and calendars. Refused while bookings are still to come (`host_has_live_bookings`): cancel them, or set the host's status to `disabled`.", "security": [ { "bearerAuth": [] @@ -62245,27 +64695,14 @@ { "schema": { "type": "string", - "description": "The form's id.", - "examples": [ - "form_01kd2m8n3p4q5r6s7t8v9w0x1y" - ] - }, - "required": true, - "description": "The form's id.", - "name": "id", - "in": "path" - }, - { - "schema": { - "type": "string", - "description": "The submission's id.", + "description": "The host's id or uid.", "examples": [ - "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k" + "host_01kd2m9a0b1c2d3e4f5g6h7j8m" ] }, "required": true, - "description": "The submission's id.", - "name": "submission_id", + "description": "The host's id or uid.", + "name": "host", "in": "path" }, { @@ -62274,7 +64711,7 @@ ], "responses": { "200": { - "description": "The submission was deleted.", + "description": "Deleted.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62298,7 +64735,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedFormSubmission" + "$ref": "#/components/schemas/DeletedSchedulingHost" } } } @@ -62367,7 +64804,28 @@ } }, "404": { - "description": "No such form, or no submission with this id in it (`not_found`).", + "description": "Nothing with this id or uid exists in the environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The request failed validation (`validation_error`, see `issues`), or can't be done: see `code`.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62459,53 +64917,32 @@ } } }, - "/v1/forms/{id}/submissions/{submission_id}/release": { + "/v1/scheduling/out_of_office": { "post": { - "operationId": "releaseFormSubmission", + "operationId": "createSchedulingOutOfOffice", "tags": [ - "Form submissions" + "Scheduling out of office" ], - "summary": "Release a submission", - "description": "Not spam: a `held` or `spam` submission becomes `accepted` and is delivered (webhooks, notifications, contacts), and Risk records its assessment as `legitimate`. Releasing an accepted submission returns it as is.", + "summary": "Create out of office entries", + "description": "Marks one host, a list of hosts or everyone matching some attributes as away, for part of a day or for whole dates. They aren't offered during it. Existing bookings stay as they are: list them with the entry's conflicts.", "security": [ { "bearerAuth": [] } ], - "parameters": [ - { - "schema": { - "type": "string", - "description": "The form's id.", - "examples": [ - "form_01kd2m8n3p4q5r6s7t8v9w0x1y" - ] - }, - "required": true, - "description": "The form's id.", - "name": "id", - "in": "path" - }, - { - "schema": { - "type": "string", - "description": "The submission's id.", - "examples": [ - "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k" - ] - }, - "required": true, - "description": "The submission's id.", - "name": "submission_id", - "in": "path" - }, - { - "$ref": "#/components/parameters/CossVersion" + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateSchedulingOutOfOfficeRequest" + } + } } - ], + }, "responses": { - "200": { - "description": "The released submission.", + "201": { + "description": "An entry per host.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62529,13 +64966,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/FormSubmission" + "$ref": "#/components/schemas/SchedulingOutOfOfficeList" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62598,7 +65035,28 @@ } }, "404": { - "description": "No such form, or no submission with this id in it (`not_found`).", + "description": "Nothing with this id or uid exists in the environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62619,7 +65077,7 @@ } }, "422": { - "description": "Only held and spam submissions can be released (`submission_not_releasable`).", + "description": "The request failed validation (`validation_error`, see `issues`), or can't be done: see `code`.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62708,61 +65166,92 @@ } } } - } - } - }, - "/v1/forms/{id}/submissions/{submission_id}/files/{file_id}": { + }, + "parameters": [ + { + "$ref": "#/components/parameters/CossVersion" + } + ] + }, "get": { - "operationId": "getFormSubmissionFile", + "operationId": "listSchedulingOutOfOffice", "tags": [ - "Form submissions" + "Scheduling out of office" ], - "summary": "Download a file", - "description": "A file uploaded with the submission, as `application/octet-stream`: whatever its type, treat it as untrusted (a submitter chose it).", + "summary": "List out of office entries", + "description": "The environment's entries, newest first.", "security": [ { "bearerAuth": [] } ], "parameters": [ + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 20 + }, + "required": false, + "name": "limit", + "in": "query" + }, { "schema": { "type": "string", - "description": "The form's id.", - "examples": [ - "form_01kd2m8n3p4q5r6s7t8v9w0x1y" - ] + "description": "The last id of the previous page." }, - "required": true, - "description": "The form's id.", - "name": "id", - "in": "path" + "required": false, + "description": "The last id of the previous page.", + "name": "after", + "in": "query" }, { "schema": { "type": "string", - "description": "The submission's id.", + "description": "One host's entries, by id or uid." + }, + "required": false, + "description": "One host's entries, by id or uid.", + "name": "host", + "in": "query" + }, + { + "schema": { + "type": "string", + "description": "Entries ending after this.", "examples": [ - "fsub_01kd2m9a0b1c2d3e4f5g6h7j8k" + "2027-01-04T15:00:00.000Z" ] }, - "required": true, - "description": "The submission's id.", - "name": "submission_id", - "in": "path" + "required": false, + "description": "Entries ending after this.", + "name": "start_after", + "in": "query" }, { "schema": { "type": "string", - "description": "The file's id (`files[].id` of the submission).", + "description": "Entries starting before this.", "examples": [ - "ffile_01kd2m9a0b1c2d3e4f5g6h7j8m" + "2027-01-04T15:00:00.000Z" ] }, - "required": true, - "description": "The file's id (`files[].id` of the submission).", - "name": "file_id", - "in": "path" + "required": false, + "description": "Entries starting before this.", + "name": "start_before", + "in": "query" + }, + { + "schema": { + "type": "string", + "description": "The entries one request made." + }, + "required": false, + "description": "The entries one request made.", + "name": "group", + "in": "query" }, { "$ref": "#/components/parameters/CossVersion" @@ -62770,7 +65259,7 @@ ], "responses": { "200": { - "description": "The file's bytes.", + "description": "A page of entries.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62792,10 +65281,9 @@ } }, "content": { - "application/octet-stream": { + "application/json": { "schema": { - "type": "string", - "format": "binary" + "$ref": "#/components/schemas/SchedulingOutOfOfficeList" } } } @@ -62864,7 +65352,28 @@ } }, "404": { - "description": "No such form, submission or file (`not_found`).", + "description": "Nothing with this id or uid exists in the environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "422": { + "description": "The request failed validation (`validation_error`, see `issues`), or can't be done: see `code`.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62933,7 +65442,7 @@ } }, "503": { - "description": "Forms isn't available in this deployment yet (`forms_unavailable`).", + "description": "The API key could not be verified right now; retry (`service_unavailable`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -62956,32 +65465,40 @@ } } }, - "/v1/scheduling/hosts": { - "post": { - "operationId": "createSchedulingHost", + "/v1/scheduling/out_of_office/{id}": { + "get": { + "operationId": "getSchedulingOutOfOffice", "tags": [ - "Scheduling hosts" + "Scheduling out of office" ], - "summary": "Create a host", - "description": "A person who can be booked: one of your users, such as a doctor or a tutor.", + "summary": "Retrieve an out of office entry", + "description": "One entry.", "security": [ { "bearerAuth": [] } ], - "requestBody": { - "required": true, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CreateHostRequest" - } - } + "parameters": [ + { + "schema": { + "type": "string", + "description": "The entry's id.", + "examples": [ + "ooo_01kd2m9a0b1c2d3e4f5g6h7j8m" + ] + }, + "required": true, + "description": "The entry's id.", + "name": "id", + "in": "path" + }, + { + "$ref": "#/components/parameters/CossVersion" } - }, + ], "responses": { - "201": { - "description": "The host.", + "200": { + "description": "The entry.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -63005,13 +65522,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SchedulingHost" + "$ref": "#/components/schemas/SchedulingOutOfOffice" } } } }, "400": { - "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -63073,29 +65590,8 @@ } } }, - "415": { - "description": "The body is not sent as `application/json` (`unsupported_media_type`).", - "headers": { - "X-Request-Id": { - "description": "Unique id of this request. Include it when contacting support.", - "schema": { - "type": "string", - "examples": [ - "req_01k7c8m4q2f3e9v6t5r1n0p8yz" - ] - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/Error" - } - } - } - }, - "422": { - "description": "The request failed validation (`validation_error`, see `issues`), or can't be done: see `code`.", + "404": { + "description": "Nothing with this id or uid exists in the environment (`not_found`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -63184,54 +65680,51 @@ } } } - }, - "parameters": [ - { - "$ref": "#/components/parameters/CossVersion" - } - ] + } }, - "get": { - "operationId": "listSchedulingHosts", + "patch": { + "operationId": "updateSchedulingOutOfOffice", "tags": [ - "Scheduling hosts" + "Scheduling out of office" ], - "summary": "List hosts", - "description": "The environment's hosts, newest first.", + "summary": "Update an out of office entry", + "description": "Changes what's given. An entry stays with its host.", "security": [ { "bearerAuth": [] } ], "parameters": [ - { - "schema": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "default": 20 - }, - "required": false, - "name": "limit", - "in": "query" - }, { "schema": { "type": "string", - "description": "The last id of the previous page." + "description": "The entry's id.", + "examples": [ + "ooo_01kd2m9a0b1c2d3e4f5g6h7j8m" + ] }, - "required": false, - "description": "The last id of the previous page.", - "name": "after", - "in": "query" + "required": true, + "description": "The entry's id.", + "name": "id", + "in": "path" }, { "$ref": "#/components/parameters/CossVersion" } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSchedulingOutOfOfficeRequest" + } + } + } + }, "responses": { "200": { - "description": "A page of hosts.", + "description": "The entry.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -63255,13 +65748,13 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SchedulingHostList" + "$ref": "#/components/schemas/SchedulingOutOfOffice" } } } }, "400": { - "description": "The `Coss-Version` header names an unknown API version (`invalid_api_version`).", + "description": "The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -63323,6 +65816,48 @@ } } }, + "404": { + "description": "Nothing with this id or uid exists in the environment (`not_found`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, + "415": { + "description": "The body is not sent as `application/json` (`unsupported_media_type`).", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + }, "422": { "description": "The request failed validation (`validation_error`, see `issues`), or can't be done: see `code`.", "headers": { @@ -63414,16 +65949,14 @@ } } } - } - }, - "/v1/scheduling/hosts/{host}": { - "get": { - "operationId": "getSchedulingHost", + }, + "delete": { + "operationId": "deleteSchedulingOutOfOffice", "tags": [ - "Scheduling hosts" + "Scheduling out of office" ], - "summary": "Retrieve a host", - "description": "A host by its id or your uid.", + "summary": "Delete an out of office entry", + "description": "The host can be booked in that time again, and any calendar event for it goes.", "security": [ { "bearerAuth": [] @@ -63433,14 +65966,14 @@ { "schema": { "type": "string", - "description": "The host's id or uid.", + "description": "The entry's id.", "examples": [ - "host_01kd2m9a0b1c2d3e4f5g6h7j8m" + "ooo_01kd2m9a0b1c2d3e4f5g6h7j8m" ] }, "required": true, - "description": "The host's id or uid.", - "name": "host", + "description": "The entry's id.", + "name": "id", "in": "path" }, { @@ -63449,7 +65982,7 @@ ], "responses": { "200": { - "description": "The host.", + "description": "Deleted.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -63473,7 +66006,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SchedulingHost" + "$ref": "#/components/schemas/DeletedSchedulingOutOfOffice" } } } @@ -63632,14 +66165,16 @@ } } } - }, - "patch": { - "operationId": "updateSchedulingHost", + } + }, + "/v1/scheduling/out_of_office/by_external_id/{external_id}": { + "put": { + "operationId": "putSchedulingOutOfOffice", "tags": [ - "Scheduling hosts" + "Scheduling out of office" ], - "summary": "Update a host", - "description": "Changes what's given. A `disabled` host keeps its bookings but gets no new ones.", + "summary": "Create or replace an entry by your own id", + "description": "For syncing from a system of record such as an HR tool: send what it says, as often as you like, and there's one entry for it. Give every field you want to keep.", "security": [ { "bearerAuth": [] @@ -63649,14 +66184,14 @@ { "schema": { "type": "string", - "description": "The host's id or uid.", + "description": "Your own id for the entry.", "examples": [ - "host_01kd2m9a0b1c2d3e4f5g6h7j8m" + "hr_leave_4471" ] }, "required": true, - "description": "The host's id or uid.", - "name": "host", + "description": "Your own id for the entry.", + "name": "external_id", "in": "path" }, { @@ -63668,14 +66203,14 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpdateHostRequest" + "$ref": "#/components/schemas/PutSchedulingOutOfOfficeRequest" } } } }, "responses": { "200": { - "description": "The host.", + "description": "The entry, replaced.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -63699,7 +66234,37 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SchedulingHost" + "$ref": "#/components/schemas/SchedulingOutOfOffice" + } + } + } + }, + "201": { + "description": "The entry, new.", + "headers": { + "X-Request-Id": { + "description": "Unique id of this request. Include it when contacting support.", + "schema": { + "type": "string", + "examples": [ + "req_01k7c8m4q2f3e9v6t5r1n0p8yz" + ] + } + }, + "Coss-Version": { + "description": "The API version this response is rendered in.", + "schema": { + "type": "string", + "examples": [ + "2026-10-10" + ] + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SchedulingOutOfOffice" } } } @@ -63900,14 +66465,16 @@ } } } - }, - "delete": { - "operationId": "deleteSchedulingHost", + } + }, + "/v1/scheduling/out_of_office/{id}/conflicts": { + "get": { + "operationId": "listSchedulingOutOfOfficeConflicts", "tags": [ - "Scheduling hosts" + "Scheduling out of office" ], - "summary": "Delete a host", - "description": "Removes the host and its schedules and calendars. Refused while bookings are still to come (`host_has_live_bookings`): cancel them, or set the host's status to `disabled`.", + "summary": "List an entry's conflicts", + "description": "Live bookings of the host that fall in the entry, soonest first. Entries never change them.", "security": [ { "bearerAuth": [] @@ -63917,23 +66484,34 @@ { "schema": { "type": "string", - "description": "The host's id or uid.", + "description": "The entry's id.", "examples": [ - "host_01kd2m9a0b1c2d3e4f5g6h7j8m" + "ooo_01kd2m9a0b1c2d3e4f5g6h7j8m" ] }, "required": true, - "description": "The host's id or uid.", - "name": "host", + "description": "The entry's id.", + "name": "id", "in": "path" }, + { + "schema": { + "type": "integer", + "minimum": 1, + "maximum": 500, + "default": 100 + }, + "required": false, + "name": "limit", + "in": "query" + }, { "$ref": "#/components/parameters/CossVersion" } ], "responses": { "200": { - "description": "Deleted.", + "description": "The bookings.", "headers": { "X-Request-Id": { "description": "Unique id of this request. Include it when contacting support.", @@ -63957,7 +66535,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeletedSchedulingHost" + "$ref": "#/components/schemas/SchedulingOutOfOfficeConflictList" } } } diff --git a/apps/api/src/routes/scheduling-client.ts b/apps/api/src/routes/scheduling-client.ts index 651da3f39..853421ca0 100644 --- a/apps/api/src/routes/scheduling-client.ts +++ b/apps/api/src/routes/scheduling-client.ts @@ -10,12 +10,15 @@ import { approveBooking, attendeeEmailedOnConfirm, authenticateSchedulingSession, + awayNoticeOf, cancelBooking, connectCaldav, connectSimulated, createBooking, + createOutOfOffice, createSchedule, declineBooking, + deleteOutOfOffice, disconnectCalendar, fixedAttendee, getBooking, @@ -26,6 +29,8 @@ import { listBookingSlots, listConnections, listEventTypeSlots, + listOutOfOffice, + listOutOfOfficeConflicts, listSchedules, listUpcomingHostBookings, logoDataUrl, @@ -37,14 +42,19 @@ import { startCalendarAuthorization, toConnectionObject, updateCalendar, + updateOutOfOffice, updateSchedule, } from "@coss/scheduling"; import { AuthorizeCalendarRequest, CreateBookingRequest, CreateCalendarConnectionRequest, + HostOutOfOfficeRequest, + OUT_OF_OFFICE_PRESET_REASONS, + OUT_OF_OFFICE_REASON_LABELS, RescheduleBookingRequest, UpdateCalendarRequest, + UpdateOutOfOfficeRequest, UpsertScheduleRequest, } from "@coss/scheduling/schemas"; import { type Context, Hono, type MiddlewareHandler } from "hono"; @@ -257,6 +267,20 @@ export function createSchedulingClientRoutes(opts: { return c.json(base); }); + /** Only when one person can be booked here: "they're away" can't be said of a pool. */ + const awayNoticeFor = async ( + env: AuthenticatedSession["env"], + eventType: string, + pinnedHost: string | null, + ) => { + const now = deps.now?.() ?? new Date(); + if (pinnedHost) return awayNoticeOf(env, pinnedHost, now); + const { hosts, kind } = await getEventType(env, eventType); + const [only] = hosts; + if (kind === "pool" || hosts.length !== 1 || !only) return null; + return awayNoticeOf(env, only.host, now); + }; + const slotQueryOf = (c: Context) => { const query = SlotQuery.safeParse({ start: c.req.query("start"), @@ -282,16 +306,18 @@ export function createSchedulingClientRoutes(opts: { router.get("/slots", async (c) => { // The session's kind first: the wrong one is a 404, whatever the query says. const eventTypeRef = eventTypeOf(c); - return c.json( - slotList( - await listEventTypeSlots(c.var.session.env, { - ...slotQueryOf(c), - eventTypeRef, - hostRefs: c.var.session.session.hostId ? [c.var.session.session.hostId] : undefined, - attributes: sessionAttributes(c.var.session.session, deps), - }), - ), - ); + const { env, session } = c.var.session; + const hostRefs = session.hostId ? [session.hostId] : undefined; + const slots = await listEventTypeSlots(env, { + ...slotQueryOf(c), + eventTypeRef, + hostRefs, + attributes: sessionAttributes(session, deps), + }); + return c.json({ + ...slotList(slots), + away: await awayNoticeFor(env, eventTypeRef, session.hostId), + }); }); router.post("/bookings", async (c) => { @@ -473,6 +499,73 @@ export function createSchedulingClientRoutes(opts: { return c.json({ object: "list" as const, data, has_more: false }); }); + // A host's own time away. Whose it is comes from the session, so it never needs saying. + router.get("/host/out_of_office", async (c) => { + const hostId = hostOf(c); + const { env } = c.var.session; + const page = await listOutOfOffice( + env, + { hostIds: [hostId], fromMs: (deps.now?.() ?? new Date()).getTime(), limit: 100 }, + deps, + ); + const settings = await getSettingsRow(env); + return c.json({ + object: "list" as const, + data: page.data, + has_more: page.hasMore, + reasons: [ + ...OUT_OF_OFFICE_PRESET_REASONS.map((key) => ({ + key, + label: OUT_OF_OFFICE_REASON_LABELS[key], + })), + ...(settings?.outOfOfficeReasons ?? []), + ], + }); + }); + + router.post("/host/out_of_office", async (c) => { + const hostId = writableHost(c); + const [entry] = await createOutOfOffice( + c.var.session.env, + { ...(await parsed(c, HostOutOfOfficeRequest)), host: hostId }, + deps, + sessionActor(c.var.session.session), + "host", + ); + return c.json(entry, 201); + }); + + router.patch("/host/out_of_office/:id", async (c) => { + const hostId = writableHost(c); + const entry = await updateOutOfOffice( + c.var.session.env, + c.req.param("id"), + await parsed(c, UpdateOutOfOfficeRequest), + deps, + sessionActor(c.var.session.session), + { hostId }, + ); + return c.json(entry); + }); + + router.delete("/host/out_of_office/:id", async (c) => { + const hostId = writableHost(c); + await deleteOutOfOffice(c.var.session.env, c.req.param("id"), deps, { hostId }); + return c.body(null, 204); + }); + + router.get("/host/out_of_office/:id/conflicts", async (c) => { + const hostId = hostOf(c); + const page = await listOutOfOfficeConflicts( + c.var.session.env, + c.req.param("id"), + { limit: 200 }, + deps, + { hostId }, + ); + return c.json({ object: "list" as const, data: page.data, has_more: page.hasMore }); + }); + /** A host's own bookings, with attendee names but not their answers. */ router.get("/host/bookings", async (c) => { const page = await listUpcomingHostBookings( diff --git a/apps/api/src/routes/scheduling.ts b/apps/api/src/routes/scheduling.ts index ddad6dfe0..fb614a3e3 100644 --- a/apps/api/src/routes/scheduling.ts +++ b/apps/api/src/routes/scheduling.ts @@ -2,6 +2,8 @@ * Scheduling over the public API (`/v1/scheduling/*`): hosts, their schedules, event types, slots, * bookings, holds and series. Tenancy comes only from the API key. */ + +import { db } from "@coss/db"; import { approveBooking, type BookingActor, @@ -18,17 +20,20 @@ import { createHost, createHostSession, createManageSession, + createOutOfOffice, createSchedule, createSeries, declineBooking, deleteHold, deleteHost, + deleteOutOfOffice, deleteSchedule, disconnectCalendar, eraseAttendee, getBooking, getEventType, getHost, + getOutOfOffice, getSchedule, getSettings, getSettingsRow, @@ -37,10 +42,14 @@ import { listEventTypeSlots, listEventTypes, listHosts, + listOutOfOffice, + listOutOfOfficeConflicts, listSchedules, markNoShow, previewSeries, + putOutOfOffice, rescheduleBooking, + resolveHost, type SchedulingDeps, SchedulingError, searchAvailability, @@ -51,6 +60,7 @@ import { updateCalendar, updateEventType, updateHost, + updateOutOfOffice, updateSchedule, updateSettings, } from "@coss/scheduling"; @@ -66,14 +76,17 @@ import { CancelledSeries, CancelSeriesRequest, ConfirmHoldRequest, + ConflictsQuery, CreateBookingRequest, CreateCalendarConnectionRequest, CreateEventTypeRequest, CreateHoldRequest, CreateHostRequest, + CreateOutOfOfficeRequest, CreateSeriesRequest, DeletedCalendarConnection, DeletedHost, + DeletedOutOfOffice, DeletedSchedule, ErasedAttendee, EventTypeList, @@ -81,7 +94,12 @@ import { HostList, HostObject, ListBookingsQuery, + ListOutOfOfficeQuery, + OutOfOfficeConflictList, + OutOfOfficeList, + OutOfOfficeObject, PageQuery, + PutOutOfOfficeRequest, RescheduleBookingRequest, ScheduleList, ScheduleObject, @@ -95,6 +113,7 @@ import { UpdateCalendarRequest, UpdateEventTypeRequest, UpdateHostRequest, + UpdateOutOfOfficeRequest, UpdateSettingsRequest, UpsertScheduleRequest, } from "@coss/scheduling/schemas"; @@ -118,6 +137,7 @@ const TAG_BOOKINGS = "Scheduling bookings"; const TAG_SERIES = "Scheduling series"; const TAG_SETTINGS = "Scheduling settings"; const TAG_CALENDARS = "Scheduling calendars"; +const TAG_OUT_OF_OFFICE = "Scheduling out of office"; const read = () => [requireApiKey({ scheduling: ["read"] }), rateLimit("api.read")]; const writing = ( @@ -157,6 +177,12 @@ const CalendarParams = HostParams.extend({ calendar_id: param("The calendar's id.", "cal_01kd2m9a0b1c2d3e4f5g6h7j8m"), }); const AttendeeParams = z.object({ uid: param("Your id for the attendee.", "patient_77") }); +const OutOfOfficeParams = z.object({ + id: param("The entry's id.", "ooo_01kd2m9a0b1c2d3e4f5g6h7j8m"), +}); +const ExternalOutOfOfficeParams = z.object({ + external_id: param("Your own id for the entry.", "hr_leave_4471"), +}); const bodyErrors = { 400: errorDoc("The body is not valid JSON (`invalid_json`)."), @@ -1068,6 +1094,140 @@ export const createManageSessionRoute = createRoute({ }, }); +export const createOutOfOfficeRoute = createRoute({ + method: "post", + path: "/scheduling/out_of_office", + operationId: "createSchedulingOutOfOffice", + tags: [TAG_OUT_OF_OFFICE], + summary: "Create out of office entries", + description: + "Marks one host, a list of hosts or everyone matching some attributes as away, for part of a " + + "day or for whole dates. They aren't offered during it. Existing bookings stay as they are: " + + "list them with the entry's conflicts.", + security: [{ bearerAuth: [] }], + middleware: writing("create", "POST /v1/scheduling/out_of_office"), + request: { + body: { required: true, content: { "application/json": { schema: CreateOutOfOfficeRequest } } }, + }, + responses: { + 201: jsonDoc("An entry per host.", OutOfOfficeList), + ...commonErrors, + ...bodyErrors, + 404: notFound, + 422: invalid, + }, +}); + +export const listOutOfOfficeRoute = createRoute({ + method: "get", + path: "/scheduling/out_of_office", + operationId: "listSchedulingOutOfOffice", + tags: [TAG_OUT_OF_OFFICE], + summary: "List out of office entries", + description: "The environment's entries, newest first.", + security: [{ bearerAuth: [] }], + middleware: read(), + request: { query: ListOutOfOfficeQuery }, + responses: { + 200: jsonDoc("A page of entries.", OutOfOfficeList), + ...commonErrors, + 404: notFound, + 422: invalid, + }, +}); + +export const getOutOfOfficeRoute = createRoute({ + method: "get", + path: "/scheduling/out_of_office/{id}", + operationId: "getSchedulingOutOfOffice", + tags: [TAG_OUT_OF_OFFICE], + summary: "Retrieve an out of office entry", + description: "One entry.", + security: [{ bearerAuth: [] }], + middleware: read(), + request: { params: OutOfOfficeParams }, + responses: { 200: jsonDoc("The entry.", OutOfOfficeObject), ...commonErrors, 404: notFound }, +}); + +export const updateOutOfOfficeRoute = createRoute({ + method: "patch", + path: "/scheduling/out_of_office/{id}", + operationId: "updateSchedulingOutOfOffice", + tags: [TAG_OUT_OF_OFFICE], + summary: "Update an out of office entry", + description: "Changes what's given. An entry stays with its host.", + security: [{ bearerAuth: [] }], + middleware: writing("update", "PATCH /v1/scheduling/out_of_office/{id}"), + request: { + params: OutOfOfficeParams, + body: { required: true, content: { "application/json": { schema: UpdateOutOfOfficeRequest } } }, + }, + responses: { + 200: jsonDoc("The entry.", OutOfOfficeObject), + ...commonErrors, + ...bodyErrors, + 404: notFound, + 422: invalid, + }, +}); + +export const putOutOfOfficeRoute = createRoute({ + method: "put", + path: "/scheduling/out_of_office/by_external_id/{external_id}", + operationId: "putSchedulingOutOfOffice", + tags: [TAG_OUT_OF_OFFICE], + summary: "Create or replace an entry by your own id", + description: + "For syncing from a system of record such as an HR tool: send what it says, as often as you " + + "like, and there's one entry for it. Give every field you want to keep.", + security: [{ bearerAuth: [] }], + middleware: writing("update", "PUT /v1/scheduling/out_of_office/by_external_id/{external_id}"), + request: { + params: ExternalOutOfOfficeParams, + body: { required: true, content: { "application/json": { schema: PutOutOfOfficeRequest } } }, + }, + responses: { + 200: jsonDoc("The entry, replaced.", OutOfOfficeObject), + 201: jsonDoc("The entry, new.", OutOfOfficeObject), + ...commonErrors, + ...bodyErrors, + 404: notFound, + 422: invalid, + }, +}); + +export const deleteOutOfOfficeRoute = createRoute({ + method: "delete", + path: "/scheduling/out_of_office/{id}", + operationId: "deleteSchedulingOutOfOffice", + tags: [TAG_OUT_OF_OFFICE], + summary: "Delete an out of office entry", + description: "The host can be booked in that time again, and any calendar event for it goes.", + security: [{ bearerAuth: [] }], + middleware: acting("delete"), + request: { params: OutOfOfficeParams }, + responses: { 200: jsonDoc("Deleted.", DeletedOutOfOffice), ...commonErrors, 404: notFound }, +}); + +export const listOutOfOfficeConflictsRoute = createRoute({ + method: "get", + path: "/scheduling/out_of_office/{id}/conflicts", + operationId: "listSchedulingOutOfOfficeConflicts", + tags: [TAG_OUT_OF_OFFICE], + summary: "List an entry's conflicts", + description: + "Live bookings of the host that fall in the entry, soonest first. Entries never change them.", + security: [{ bearerAuth: [] }], + middleware: read(), + request: { params: OutOfOfficeParams, query: ConflictsQuery }, + responses: { + 200: jsonDoc("The bookings.", OutOfOfficeConflictList), + ...commonErrors, + 404: notFound, + 422: invalid, + }, +}); + export const getSettingsRoute = createRoute({ method: "get", path: "/scheduling/settings", @@ -1205,6 +1365,94 @@ export function createSchedulingRoutes(configured: SchedulingDeps | null): OpenA return c.json({ object: "scheduling.host" as const, id, deleted: true as const }, 200); }); + router.openapi(createOutOfOfficeRoute, async (c) => { + const data = await createOutOfOffice( + c.var.auth, + c.req.valid("json"), + deps, + actorOf(c.var.auth), + "api", + ); + for (const entry of data) { + await recordApiAudit(c, { + action: "scheduling_out_of_office.created", + target: { type: "scheduling_out_of_office", id: entry.id }, + }); + } + return c.json({ object: "list" as const, data, has_more: false }, 201); + }); + + router.openapi(listOutOfOfficeRoute, async (c) => { + const query = c.req.valid("query"); + const host = query.host ? await resolveHost(db, c.var.auth, query.host) : null; + const page = await listOutOfOffice( + c.var.auth, + { + hostIds: host ? [host.id] : undefined, + fromMs: query.start_after ? instant(query.start_after, "start_after") : undefined, + toMs: query.start_before ? instant(query.start_before, "start_before") : undefined, + group: query.group, + limit: query.limit, + after: query.after, + }, + deps, + ); + return c.json({ object: "list" as const, data: page.data, has_more: page.hasMore }, 200); + }); + + router.openapi(getOutOfOfficeRoute, async (c) => + c.json(await getOutOfOffice(c.var.auth, c.req.valid("param").id, deps), 200), + ); + + router.openapi(updateOutOfOfficeRoute, async (c) => { + const entry = await updateOutOfOffice( + c.var.auth, + c.req.valid("param").id, + c.req.valid("json"), + deps, + actorOf(c.var.auth), + ); + await recordApiAudit(c, { + action: "scheduling_out_of_office.updated", + target: { type: "scheduling_out_of_office", id: entry.id }, + }); + return c.json(entry, 200); + }); + + router.openapi(putOutOfOfficeRoute, async (c) => { + const { entry, created } = await putOutOfOffice( + c.var.auth, + c.req.valid("param").external_id, + c.req.valid("json"), + deps, + actorOf(c.var.auth), + ); + await recordApiAudit(c, { + action: created ? "scheduling_out_of_office.created" : "scheduling_out_of_office.updated", + target: { type: "scheduling_out_of_office", id: entry.id }, + }); + return created ? c.json(entry, 201) : c.json(entry, 200); + }); + + router.openapi(deleteOutOfOfficeRoute, async (c) => { + const { id } = await deleteOutOfOffice(c.var.auth, c.req.valid("param").id, deps); + await recordApiAudit(c, { + action: "scheduling_out_of_office.deleted", + target: { type: "scheduling_out_of_office", id }, + }); + return c.json({ object: "scheduling.out_of_office" as const, id, deleted: true as const }, 200); + }); + + router.openapi(listOutOfOfficeConflictsRoute, async (c) => { + const page = await listOutOfOfficeConflicts( + c.var.auth, + c.req.valid("param").id, + c.req.valid("query"), + deps, + ); + return c.json({ object: "list" as const, data: page.data, has_more: page.hasMore }, 200); + }); + router.openapi(createScheduleRoute, async (c) => c.json(await createSchedule(c.var.auth, c.req.valid("param").host, c.req.valid("json")), 201), ); diff --git a/apps/api/src/webhook-events.ts b/apps/api/src/webhook-events.ts index 8d8e0597a..3a58b6086 100644 --- a/apps/api/src/webhook-events.ts +++ b/apps/api/src/webhook-events.ts @@ -13,6 +13,7 @@ import { RiskWebhookEvent } from "@coss/risk/schemas"; import { SchedulingBookingWebhookEvent, SchedulingCalendarWebhookEvent, + SchedulingOutOfOfficeWebhookEvent, } from "@coss/scheduling/schemas"; import { SignRequestWebhookEvent } from "@coss/sign/schemas"; import { ReceivedSmsWebhookEvent, SmsWebhookEvent } from "@coss/sms/schemas"; @@ -41,6 +42,7 @@ const WEBHOOK_EVENTS = { FormSubmissionWebhookEvent, SchedulingBookingWebhookEvent, SchedulingCalendarWebhookEvent, + SchedulingOutOfOfficeWebhookEvent, }; export function registerWebhookEvents(app: OpenAPIHono): void { diff --git a/apps/api/test/app.test.ts b/apps/api/test/app.test.ts index 6fe787f55..2145ce49b 100644 --- a/apps/api/test/app.test.ts +++ b/apps/api/test/app.test.ts @@ -306,6 +306,10 @@ describe("GET /openapi.json", () => { "/v1/scheduling/hosts/{host}/schedules/{schedule_id}", "/v1/scheduling/hosts/{host}/sessions", "/v1/scheduling/hosts/{host}/simulated_busy", + "/v1/scheduling/out_of_office", + "/v1/scheduling/out_of_office/by_external_id/{external_id}", + "/v1/scheduling/out_of_office/{id}", + "/v1/scheduling/out_of_office/{id}/conflicts", "/v1/scheduling/series", "/v1/scheduling/series/preview", "/v1/scheduling/series/{id}/cancel", diff --git a/apps/api/test/contract-types.ts b/apps/api/test/contract-types.ts index 0c3a67855..79bd1b173 100644 --- a/apps/api/test/contract-types.ts +++ b/apps/api/test/contract-types.ts @@ -226,14 +226,20 @@ import type { CreateEventTypeRequest, CreateHoldRequest, CreateHostRequest, + CreateOutOfOfficeRequest, CreateSeriesRequest, ErasedAttendee, EventTypeObject, HostObject, + ListOutOfOfficeQuery, + OutOfOfficeConflict, + OutOfOfficeObject, + PutOutOfOfficeRequest, RescheduleBookingRequest, ScheduleObject, SchedulingBookingWebhookEvent, SchedulingCalendarWebhookEvent, + SchedulingOutOfOfficeWebhookEvent, SeriesPreview, SeriesResult, SetSimulatedBusyRequest, @@ -244,6 +250,7 @@ import type { UpdateCalendarRequest, UpdateEventTypeRequest, UpdateHostRequest, + UpdateOutOfOfficeRequest, UpdateSettingsRequest, UpsertScheduleRequest, } from "@coss/scheduling/schemas"; @@ -306,6 +313,7 @@ import type { CreateSchedulingEventTypeParams, CreateSchedulingHoldParams, CreateSchedulingHostParams, + CreateSchedulingOutOfOfficeParams, CreateSchedulingSeriesParams, CreateSegmentParams, CreateSubaccountParams, @@ -338,6 +346,7 @@ import type { ListReceivedEmailsParams, ListRiskAssessmentsParams, ListRiskListEntriesParams, + ListSchedulingOutOfOfficeParams, ListSchedulingSlotsParams, ListSubaccountsParams, ListSuppressionsParams, @@ -351,6 +360,7 @@ import type { LogDrainSource, PollWebhookListenerParams, PublishEmailTemplateParams, + PutSchedulingOutOfOfficeParams, RecoverWebhookEndpointParams, RenderEmailTemplateParams, RescheduleEmailParams, @@ -365,6 +375,8 @@ import type { SchedulingCancelledSeries, SchedulingEventType, SchedulingHost, + SchedulingOutOfOffice, + SchedulingOutOfOfficeConflict, SchedulingSchedule, SchedulingSeries, SchedulingSeriesPreview, @@ -498,6 +510,7 @@ import type { UpdateSchedulingCalendarParams, UpdateSchedulingEventTypeParams, UpdateSchedulingHostParams, + UpdateSchedulingOutOfOfficeParams, UpdateSchedulingSettingsParams, UpdateSegmentParams, UpdateStorageSettingsParams, @@ -757,7 +770,8 @@ export type Contract = [ | z.output | z.output | z.output - | z.output, + | z.output + | z.output, WebhookEvent > >, @@ -1058,6 +1072,21 @@ export type SubaccountContract = [ Assert, CreateSchedulingHostParams>>, Assert, UpdateSchedulingHostParams>>, Assert, SchedulingHost>>, + Assert< + MutuallyAssignable, CreateSchedulingOutOfOfficeParams> + >, + Assert, PutSchedulingOutOfOfficeParams>>, + Assert< + MutuallyAssignable, UpdateSchedulingOutOfOfficeParams> + >, + Assert, SchedulingOutOfOffice>>, + Assert, SchedulingOutOfOfficeConflict>>, + Assert< + MutuallyAssignable< + Omit, "limit">, + Omit + > + >, Assert, UpsertSchedulingScheduleParams>>, Assert, SchedulingSchedule>>, Assert< diff --git a/apps/api/test/scheduling.test.ts b/apps/api/test/scheduling.test.ts index 2e96219ac..b2e0f870f 100644 --- a/apps/api/test/scheduling.test.ts +++ b/apps/api/test/scheduling.test.ts @@ -732,3 +732,148 @@ describe("Zoom's events", () => { expect((await post(body, signature, timestamp)).status).toBe(200); }); }); + +describe("out of office", () => { + async function booker() { + const tenant = await createTestTenant(); + const { app } = createTestApp(); + const key = tenant.sandboxKey; + const send = (path: string, method: string, body?: unknown, auth = key) => + app.request(`/v1/scheduling${path}`, { + method, + headers: { authorization: `Bearer ${auth}`, "content-type": "application/json" }, + ...(body === undefined ? {} : { body: JSON.stringify(body) }), + }); + const host = (await ( + await send("/hosts", "POST", { name: "Dr. Reyes", time_zone: "UTC", uid: "doctor_1" }) + ).json()) as { id: string }; + await send("/hosts/doctor_1/schedules", "POST", { + rules: [{ days: [0, 1, 2, 3, 4, 5, 6], start: "09:00", end: "17:00" }], + }); + const eventType = (await ( + await send("/event_types", "POST", { + title: "Consultation", + duration_minutes: 30, + hosts: [{ host: "doctor_1" }], + }) + ).json()) as { id: string }; + const tokenFor = async (path: string, body: unknown) => + ((await (await send(path, "POST", body)).json()) as { token: string }).token; + const client = + (token: string) => + (path: string, method = "GET", body?: unknown) => + app.request(`/scheduling/client${path}`, { + method, + headers: { authorization: `Bearer ${token}`, "content-type": "application/json" }, + ...(body === undefined ? {} : { body: JSON.stringify(body) }), + }); + return { app, send, host, eventType, tokenFor, client }; + } + + const FAR = { start: "2031-01-06T00:00:00.000Z", end: "2031-01-07T00:00:00.000Z" }; + + test("needs the right permissions, and a bad window is a 422", async () => { + const { send } = await booker(); + const refused = await send("/out_of_office", "POST", { host: "doctor_1" }); + expect(refused.status).toBe(422); + expect((await errorOf(refused)).code).toBe("invalid_time"); + const anonymous = await send("/out_of_office", "GET", undefined, "coss_test_nope"); + expect(anonymous.status).toBe(401); + }); + + test("a host session manages only its own time, and can't name another host", async () => { + const { send, host, tokenFor, client } = await booker(); + const other = (await ( + await send("/hosts", "POST", { name: "Dr. Chen", time_zone: "UTC" }) + ).json()) as { id: string }; + const mine = client(await tokenFor(`/hosts/${host.id}/sessions`, {})); + const theirs = client(await tokenFor(`/hosts/${other.id}/sessions`, {})); + + const created = await mine("/host/out_of_office", "POST", { + start_date: "2031-01-06", + end_date: "2031-01-06", + reason: "vacation", + }); + expect(created.status).toBe(201); + const entry = (await created.json()) as { id: string; host: string; source: string }; + expect(entry.host).toBe(host.id); + expect(entry.source).toBe("host"); + + const naming = await mine("/host/out_of_office", "POST", { + host: other.id, + start_date: "2031-01-06", + end_date: "2031-01-06", + }); + expect(naming.status).toBe(422); + + const list = (await (await mine("/host/out_of_office")).json()) as { + data: { id: string }[]; + reasons: { key: string }[]; + }; + expect(list.data.map((row) => row.id)).toEqual([entry.id]); + expect(list.reasons.map((reason) => reason.key)).toContain("vacation"); + expect( + ((await (await theirs("/host/out_of_office")).json()) as { data: unknown[] }).data, + ).toEqual([]); + expect((await theirs(`/host/out_of_office/${entry.id}`, "DELETE")).status).toBe(404); + expect((await theirs(`/host/out_of_office/${entry.id}`, "PATCH", { notes: "x" })).status).toBe( + 404, + ); + expect((await theirs(`/host/out_of_office/${entry.id}/conflicts`)).status).toBe(404); + expect((await mine(`/host/out_of_office/${entry.id}`, "DELETE")).status).toBe(204); + }); + + test("a read-only host session can look but not change anything", async () => { + const { host, tokenFor, client } = await booker(); + const session = client(await tokenFor(`/hosts/${host.id}/sessions`, { read_only: true })); + expect((await session("/host/out_of_office")).status).toBe(200); + const refused = await session("/host/out_of_office", "POST", { + start_date: "2031-01-06", + end_date: "2031-01-06", + }); + expect(refused.status).toBe(403); + }); + + test("other kinds of session can't reach a host's time", async () => { + const { eventType, tokenFor, client } = await booker(); + const session = client(await tokenFor("/booker_sessions", { event_type: eventType.id })); + expect((await session("/host/out_of_office")).status).toBe(404); + expect( + ( + await session("/host/out_of_office", "POST", { + start_date: "2031-01-06", + end_date: "2031-01-06", + }) + ).status, + ).toBe(404); + }); + + test("a booker sees a message and a return date while the only host is away, never why", async () => { + const { send, eventType, tokenFor, client } = await booker(); + const now = Date.now(); + await send("/out_of_office", "POST", { + host: "doctor_1", + start: new Date(now - 3_600_000).toISOString(), + end: new Date(now + 3_600_000).toISOString(), + reason: "sick", + notes: "Recovering from surgery", + public_message: "Back this afternoon.", + }); + const session = client(await tokenFor("/booker_sessions", { event_type: eventType.id })); + const query = new URLSearchParams(FAR).toString(); + const response = await session(`/slots?${query}`); + const body = await response.text(); + expect(response.status).toBe(200); + const parsed = JSON.parse(body) as { away: { until: string; message: string } | null }; + expect(parsed.away?.message).toBe("Back this afternoon."); + expect(body).not.toContain("sick"); + expect(body).not.toContain("surgery"); + }); + + test("a booker gets no notice when nobody's away", async () => { + const { eventType, tokenFor, client } = await booker(); + const session = client(await tokenFor("/booker_sessions", { event_type: eventType.id })); + const response = await session(`/slots?${new URLSearchParams(FAR).toString()}`); + expect(((await response.json()) as { away: unknown }).away).toBeNull(); + }); +}); diff --git a/apps/api/test/sdk-contract.test.ts b/apps/api/test/sdk-contract.test.ts index 410a5bdc0..3e166f250 100644 --- a/apps/api/test/sdk-contract.test.ts +++ b/apps/api/test/sdk-contract.test.ts @@ -1966,6 +1966,94 @@ describe("coss.risk checkouts, devices and calibration against the API", () => { }); }); +describe("coss.scheduling.outOfOffice against the API", () => { + test("marks a host away, stops offering them, shows conflicts and takes it back", async () => { + const tenant = await createTestTenant(); + const { app } = createTestApp(); + const { scheduling } = clientFor(app, tenant.sandboxKey); + const host = must( + (await scheduling.hosts.create({ uid: "doctor_1", name: "Dr. Reyes", time_zone: "UTC" })) + .data, + ); + await scheduling.schedules.create("doctor_1", { + rules: [{ days: [0, 1, 2, 3, 4, 5, 6], start: "09:00", end: "17:00" }], + }); + const eventType = must( + ( + await scheduling.eventTypes.create({ + title: "Consultation", + duration_minutes: 30, + hosts: [{ host: "doctor_1" }], + }) + ).data, + ); + const booking = must( + ( + await scheduling.bookings.create({ + event_type: eventType.id, + start: "2031-01-06T10:00:00.000Z", + attendee: { name: "Sam", email: "sam@example.com", time_zone: "UTC" }, + }) + ).data, + ); + + const created = must( + ( + await scheduling.outOfOffice.create({ + host: "doctor_1", + start_date: "2031-01-06", + end_date: "2031-01-06", + reason: "vacation", + notes: "Lisbon", + public_message: "Back on Tuesday.", + }) + ).data, + ); + const entry = must(created.data[0]); + expect(entry).toMatchObject({ + object: "scheduling.out_of_office", + host: host.id, + reason: "vacation", + notes: "Lisbon", + source: "api", + all_day: { start_date: "2031-01-06", end_date: "2031-01-06", time_zone: "UTC" }, + }); + expect((await scheduling.outOfOffice.get(entry.id)).data?.id).toBe(entry.id); + expect((await scheduling.outOfOffice.list({ host: "doctor_1" })).data?.data.length).toBe(1); + const slots = await scheduling.slots.list(eventType.id, { + start: "2031-01-06T00:00:00.000Z", + end: "2031-01-07T00:00:00.000Z", + }); + expect(slots.data?.data).toEqual([]); + const conflicts = await scheduling.outOfOffice.conflicts(entry.id); + expect(conflicts.data?.data.map((conflict) => conflict.booking)).toEqual([booking.id]); + expect((await scheduling.bookings.get(booking.id)).data?.status).toBe("confirmed"); + + const moved = await scheduling.outOfOffice.update(entry.id, { end_date: "2031-01-07" }); + expect(moved.data?.all_day?.end_date).toBe("2031-01-07"); + const synced = await scheduling.outOfOffice.put("leave_1", { + host: "doctor_1", + start_date: "2031-02-03", + end_date: "2031-02-03", + }); + expect(synced.data?.external_id).toBe("leave_1"); + const again = await scheduling.outOfOffice.put("leave_1", { + host: "doctor_1", + start_date: "2031-02-04", + end_date: "2031-02-04", + }); + expect(again.data?.id).toBe(must(synced.data).id); + + const removed = await scheduling.outOfOffice.remove(entry.id); + expect(removed.data).toEqual({ + object: "scheduling.out_of_office", + id: entry.id, + deleted: true, + }); + expect((await scheduling.outOfOffice.get(entry.id)).error?.code).toBe("not_found"); + }); +}); + describe("coss.scheduling against the API", () => { test("host, schedule, event type, slots, a booking's life, a hold, a session", async () => { const tenant = await createTestTenant(); diff --git a/apps/scheduling/src/app/h/[sessionId]/host-portal.tsx b/apps/scheduling/src/app/h/[sessionId]/host-portal.tsx index 0ab894849..3436e0b27 100644 --- a/apps/scheduling/src/app/h/[sessionId]/host-portal.tsx +++ b/apps/scheduling/src/app/h/[sessionId]/host-portal.tsx @@ -16,6 +16,7 @@ import { postToHost, reportHeight } from "@/lib/embed"; import { Bookings } from "./bookings"; import { Calendars } from "./calendars"; import { Availability } from "./hours"; +import { TimeOff } from "./time-off"; import type { HostSession } from "./types"; export function HostPortal({ sessionId, apiUrl }: { sessionId: string; apiUrl: string }) { @@ -55,6 +56,7 @@ export function HostPortal({ sessionId, apiUrl }: { sessionId: string; apiUrl: s
Hours + Time off Calendars Bookings @@ -62,6 +64,9 @@ export function HostPortal({ sessionId, apiUrl }: { sessionId: string; apiUrl: s + + + diff --git a/apps/scheduling/src/app/h/[sessionId]/time-off.tsx b/apps/scheduling/src/app/h/[sessionId]/time-off.tsx new file mode 100644 index 000000000..92c45df64 --- /dev/null +++ b/apps/scheduling/src/app/h/[sessionId]/time-off.tsx @@ -0,0 +1,340 @@ +"use client"; + +import { + AlertDialog, + AlertDialogClose, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogPopup, + AlertDialogTitle, + AlertDialogTrigger, +} from "@coss/ui/components/alert-dialog"; +import { Badge } from "@coss/ui/components/badge"; +import { Button } from "@coss/ui/components/button"; +import { Input } from "@coss/ui/components/input"; +import { Label } from "@coss/ui/components/label"; +import { + Select, + SelectItem, + SelectPopup, + SelectTrigger, + SelectValue, +} from "@coss/ui/components/select"; +import { Skeleton } from "@coss/ui/components/skeleton"; +import { Spinner } from "@coss/ui/components/spinner"; +import { Switch } from "@coss/ui/components/switch"; +import { Textarea } from "@coss/ui/components/textarea"; +import { type FormEvent, useCallback, useEffect, useMemo, useState } from "react"; +import type { ClientCall } from "@/lib/client-api"; +import type { HostSession } from "./types"; + +type Entry = { + id: string; + start: string; + end: string; + all_day: { start_date: string; end_date: string; time_zone: string } | null; + reason: string; + public_message: string | null; + notes: string | null; + source: string; +}; + +type EntryList = { data: Entry[]; reasons: { key: string; label: string }[] }; + +function Conflicts(props: { call: ClientCall; entryId: string }) { + const { call, entryId } = props; + const [count, setCount] = useState(null); + useEffect(() => { + call<{ data: unknown[]; has_more: boolean }>(`/host/out_of_office/${entryId}/conflicts`) + .then((response) => setCount(response.data.length)) + // Only a hint: the entry and the bookings tab are what matter if this fails. + .catch(() => setCount(null)); + }, [call, entryId]); + if (!count) return null; + return ( + {count === 1 ? "1 booking in this time" : `${count} bookings`} + ); +} + +function NewEntry(props: { call: ClientCall; reasons: EntryList["reasons"]; onSaved: () => void }) { + const { call, reasons, onSaved } = props; + const [wholeDays, setWholeDays] = useState(true); + const [startDate, setStartDate] = useState(""); + const [endDate, setEndDate] = useState(""); + const [start, setStart] = useState(""); + const [end, setEnd] = useState(""); + const [reason, setReason] = useState("unspecified"); + const [message, setMessage] = useState(""); + const [notes, setNotes] = useState(""); + const [onCalendar, setOnCalendar] = useState(true); + const [saving, setSaving] = useState(false); + const [problem, setProblem] = useState(null); + + const submit = async (event: FormEvent) => { + event.preventDefault(); + setSaving(true); + setProblem(null); + try { + await call("/host/out_of_office", { + method: "POST", + body: { + ...(wholeDays + ? { start_date: startDate, end_date: endDate || startDate } + : { start: new Date(start).toISOString(), end: new Date(end).toISOString() }), + reason, + show_on_calendar: onCalendar, + ...(message.trim() ? { public_message: message.trim() } : {}), + ...(notes.trim() ? { notes: notes.trim() } : {}), + }, + }); + setStartDate(""); + setEndDate(""); + setStart(""); + setEnd(""); + setMessage(""); + setNotes(""); + onSaved(); + } catch (error) { + setProblem((error as Error).message); + } finally { + setSaving(false); + } + }; + + return ( + +
+ + +
+ {wholeDays ? ( +
+
+ + setStartDate(event.target.value)} + required + type="date" + value={startDate} + /> +
+
+ + setEndDate(event.target.value)} + type="date" + value={endDate} + /> +
+
+ ) : ( +
+
+ + setStart(event.target.value)} + required + type="datetime-local" + value={start} + /> +
+
+ + setEnd(event.target.value)} + required + type="datetime-local" + value={end} + /> +
+
+ )} +
+ + +

+ Only people who manage your bookings see this. +

+
+
+ + setMessage(event.target.value)} + placeholder="Back on the 16th." + value={message} + /> +

Optional. Can't contain a link.

+
+
+ +