Files
pig/packages/db/src/schema/integrations.ts
T
2026-08-13 01:39:01 -07:00

45 lines
1.9 KiB
TypeScript

import { index, integer, jsonb, pgTable, text, timestamp, uniqueIndex, uuid } from 'drizzle-orm/pg-core';
import { channelLinks } from './crm';
import { users } from './identity';
/**
* External delivery is a separate durable concern from the CRM transaction.
* A deal write only adds a row here; a provider-specific worker owns network
* failure, retry and completion without holding the request thread open.
*/
export const notificationOutbox = pgTable(
'notification_outbox',
{
id: uuid('id').primaryKey().defaultRandom(),
provider: text('provider').notNull(),
kind: text('kind').notNull(),
linkId: uuid('link_id').references(() => channelLinks.id, { onDelete: 'set null' }),
workspaceId: text('workspace_id'),
destination: text('destination').notNull(),
payload: jsonb('payload').$type<Record<string, unknown>>().notNull(),
idempotencyKey: text('idempotency_key').notNull(),
status: text('status').notNull().default('pending'),
attempts: integer('attempts').notNull().default(0),
maxAttempts: integer('max_attempts').notNull().default(5),
dueAt: timestamp('due_at', { withTimezone: true }).notNull().defaultNow(),
leasedUntil: timestamp('leased_until', { withTimezone: true }),
leasedBy: text('leased_by'),
deliveredAt: timestamp('delivered_at', { withTimezone: true }),
externalId: text('external_id'),
error: text('error'),
requestedByUserId: uuid('requested_by_user_id').references(() => users.id, {
onDelete: 'set null',
}),
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
},
(t) => [
uniqueIndex('notification_outbox_idempotency_key').on(t.idempotencyKey),
index('notification_outbox_claimable_idx').on(t.provider, t.status, t.dueAt),
index('notification_outbox_link_idx').on(t.linkId),
],
);
export type NotificationOutboxItem = typeof notificationOutbox.$inferSelect;