task ep.1.4
This commit is contained in:
167
src/db/schema.ts
167
src/db/schema.ts
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
boolean,
|
||||
doublePrecision,
|
||||
index,
|
||||
integer,
|
||||
jsonb,
|
||||
pgTable,
|
||||
@@ -451,6 +452,172 @@ export const appNotificationDeliveries = pgTable('app_notification_deliveries',
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull()
|
||||
});
|
||||
|
||||
export const businessEventOutbox = pgTable(
|
||||
'business_event_outbox',
|
||||
{
|
||||
id: text('id').primaryKey(),
|
||||
organizationId: text('organization_id').notNull(),
|
||||
eventType: text('event_type').notNull(),
|
||||
schemaVersion: integer('schema_version').notNull(),
|
||||
entityType: text('entity_type').notNull(),
|
||||
entityId: text('entity_id').notNull(),
|
||||
correlationId: text('correlation_id').notNull(),
|
||||
causationId: text('causation_id'),
|
||||
eventEnvelope: jsonb('event_envelope').notNull(),
|
||||
deliveryStatus: text('delivery_status').default('pending').notNull(),
|
||||
attemptCount: integer('attempt_count').default(0).notNull(),
|
||||
availableAt: timestamp('available_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
processingStartedAt: timestamp('processing_started_at', { withTimezone: true }),
|
||||
dispatchedAt: timestamp('dispatched_at', { withTimezone: true }),
|
||||
failedAt: timestamp('failed_at', { withTimezone: true }),
|
||||
deadLetteredAt: timestamp('dead_lettered_at', { withTimezone: true }),
|
||||
lastErrorCode: text('last_error_code'),
|
||||
lastErrorMessage: text('last_error_message'),
|
||||
occurredAt: timestamp('occurred_at', { withTimezone: true }).notNull(),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull()
|
||||
},
|
||||
(table) => ({
|
||||
statusAvailableIdx: index('business_event_outbox_status_available_idx').on(
|
||||
table.deliveryStatus,
|
||||
table.availableAt
|
||||
),
|
||||
organizationEventIdx: index('business_event_outbox_org_event_idx').on(
|
||||
table.organizationId,
|
||||
table.eventType
|
||||
)
|
||||
})
|
||||
);
|
||||
|
||||
export const projectionConsumerCheckpoints = pgTable(
|
||||
'projection_consumer_checkpoints',
|
||||
{
|
||||
id: text('id').primaryKey(),
|
||||
organizationId: text('organization_id').notNull(),
|
||||
consumerName: text('consumer_name').notNull(),
|
||||
projectionName: text('projection_name').notNull(),
|
||||
eventId: text('event_id').notNull(),
|
||||
eventType: text('event_type').notNull(),
|
||||
schemaVersion: integer('schema_version').notNull(),
|
||||
processingStatus: text('processing_status').default('pending').notNull(),
|
||||
attemptCount: integer('attempt_count').default(0).notNull(),
|
||||
firstAttemptedAt: timestamp('first_attempted_at', { withTimezone: true }),
|
||||
lastAttemptedAt: timestamp('last_attempted_at', { withTimezone: true }),
|
||||
completedAt: timestamp('completed_at', { withTimezone: true }),
|
||||
nextRetryAt: timestamp('next_retry_at', { withTimezone: true }),
|
||||
errorCode: text('error_code'),
|
||||
errorMessage: text('error_message'),
|
||||
processingDurationMs: integer('processing_duration_ms'),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull()
|
||||
},
|
||||
(table) => ({
|
||||
consumerEventIdx: uniqueIndex('projection_checkpoints_consumer_event_idx').on(
|
||||
table.consumerName,
|
||||
table.eventId
|
||||
),
|
||||
statusRetryIdx: index('projection_checkpoints_status_retry_idx').on(
|
||||
table.processingStatus,
|
||||
table.nextRetryAt
|
||||
)
|
||||
})
|
||||
);
|
||||
|
||||
export const projectionDeadLetters = pgTable(
|
||||
'projection_dead_letters',
|
||||
{
|
||||
id: text('id').primaryKey(),
|
||||
organizationId: text('organization_id').notNull(),
|
||||
consumerName: text('consumer_name').notNull(),
|
||||
projectionName: text('projection_name').notNull(),
|
||||
eventId: text('event_id').notNull(),
|
||||
eventType: text('event_type').notNull(),
|
||||
schemaVersion: integer('schema_version').notNull(),
|
||||
attemptCount: integer('attempt_count').notNull(),
|
||||
errorCode: text('error_code').notNull(),
|
||||
errorMessage: text('error_message').notNull(),
|
||||
failureMetadata: jsonb('failure_metadata'),
|
||||
status: text('status').default('open').notNull(),
|
||||
resolvedAt: timestamp('resolved_at', { withTimezone: true }),
|
||||
resolvedBy: text('resolved_by'),
|
||||
resolutionReason: text('resolution_reason'),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull()
|
||||
},
|
||||
(table) => ({
|
||||
consumerEventIdx: uniqueIndex('projection_dead_letters_consumer_event_idx').on(
|
||||
table.consumerName,
|
||||
table.eventId
|
||||
),
|
||||
organizationStatusIdx: index('projection_dead_letters_org_status_idx').on(
|
||||
table.organizationId,
|
||||
table.status
|
||||
)
|
||||
})
|
||||
);
|
||||
|
||||
export const projectionRebuildRuns = pgTable(
|
||||
'projection_rebuild_runs',
|
||||
{
|
||||
id: text('id').primaryKey(),
|
||||
organizationId: text('organization_id').notNull(),
|
||||
projectionName: text('projection_name').notNull(),
|
||||
entityType: text('entity_type'),
|
||||
entityId: text('entity_id'),
|
||||
occurredFrom: timestamp('occurred_from', { withTimezone: true }),
|
||||
occurredTo: timestamp('occurred_to', { withTimezone: true }),
|
||||
dryRun: boolean('dry_run').default(true).notNull(),
|
||||
resetExisting: boolean('reset_existing').default(false).notNull(),
|
||||
sourceStrategy: text('source_strategy').notNull(),
|
||||
status: text('status').default('pending').notNull(),
|
||||
processedCount: integer('processed_count').default(0).notNull(),
|
||||
skippedCount: integer('skipped_count').default(0).notNull(),
|
||||
failedCount: integer('failed_count').default(0).notNull(),
|
||||
errorCode: text('error_code'),
|
||||
errorMessage: text('error_message'),
|
||||
requestedBy: text('requested_by').notNull(),
|
||||
startedAt: timestamp('started_at', { withTimezone: true }),
|
||||
completedAt: timestamp('completed_at', { withTimezone: true }),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull()
|
||||
},
|
||||
(table) => ({
|
||||
organizationProjectionIdx: index('projection_rebuild_runs_org_projection_idx').on(
|
||||
table.organizationId,
|
||||
table.projectionName
|
||||
)
|
||||
})
|
||||
);
|
||||
|
||||
export const projectionHealthSnapshots = pgTable(
|
||||
'projection_health_snapshots',
|
||||
{
|
||||
id: text('id').primaryKey(),
|
||||
organizationId: text('organization_id').notNull(),
|
||||
projectionName: text('projection_name').notNull(),
|
||||
consumerName: text('consumer_name').notNull(),
|
||||
status: text('status').default('healthy').notNull(),
|
||||
lastProcessedEventId: text('last_processed_event_id'),
|
||||
lastSuccessfulProcessingAt: timestamp('last_successful_processing_at', { withTimezone: true }),
|
||||
pendingCount: integer('pending_count').default(0).notNull(),
|
||||
retryCount: integer('retry_count').default(0).notNull(),
|
||||
deadLetterCount: integer('dead_letter_count').default(0).notNull(),
|
||||
unsupportedVersionCount: integer('unsupported_version_count').default(0).notNull(),
|
||||
processingLagMs: integer('processing_lag_ms').default(0).notNull(),
|
||||
averageProcessingDurationMs: integer('average_processing_duration_ms').default(0).notNull(),
|
||||
lastRebuildAt: timestamp('last_rebuild_at', { withTimezone: true }),
|
||||
rebuildSource: text('rebuild_source'),
|
||||
createdAt: timestamp('created_at', { withTimezone: true }).defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at', { withTimezone: true }).defaultNow().notNull()
|
||||
},
|
||||
(table) => ({
|
||||
organizationConsumerIdx: uniqueIndex('projection_health_org_consumer_idx').on(
|
||||
table.organizationId,
|
||||
table.consumerName
|
||||
)
|
||||
})
|
||||
);
|
||||
|
||||
export const crmCustomers = pgTable(
|
||||
'crm_customers',
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user