export const merkleRoots = pgTable('merkle_roots', {
id: uuid('id').primaryKey().defaultRandom(),
tenantId: uuid('tenant_id').notNull(),
rootHash: varchar('root_hash', { length: 64 }).notNull(), // SHA-256 hex
leafCount: integer('leaf_count').notNull(),
treeDepth: integer('tree_depth').notNull(),
windowStart: timestamp('window_start').notNull(),
windowEnd: timestamp('window_end').notNull(),
status: varchar('status', { length: 20 }).notNull().default('pending'),
// pending → anchored → verified → failed
createdAt: timestamp('created_at').defaultNow(),
});
export const merkleLeaves = pgTable('merkle_leaves', {
id: uuid('id').primaryKey().defaultRandom(),
tenantId: uuid('tenant_id').notNull(),
rootId: uuid('root_id').notNull().references(() => merkleRoots.id),
leafIndex: integer('leaf_index').notNull(),
eventHash: varchar('event_hash', { length: 64 }).notNull(), // SHA-256 of audit event
eventType: varchar('event_type', { length: 100 }).notNull(),
eventTimestamp: timestamp('event_timestamp').notNull(),
siblingHashes: jsonb('sibling_hashes'), // proof path for verification
createdAt: timestamp('created_at').defaultNow(),
});
export const blockchainAnchors = pgTable('blockchain_anchors', {
id: uuid('id').primaryKey().defaultRandom(),
tenantId: uuid('tenant_id').notNull(),
rootId: uuid('root_id').notNull().references(() => merkleRoots.id),
chainType: varchar('chain_type', { length: 30 }).notNull(),
// ethereum | polygon | hyperledger | rfc3161
transactionHash: varchar('transaction_hash', { length: 128 }),
blockNumber: bigint('block_number', { mode: 'number' }),
chainId: integer('chain_id'),
confirmationStatus: varchar('confirmation_status', { length: 20 }).notNull().default('pending'),
// pending → confirmed → failed
confirmedAt: timestamp('confirmed_at'),
anchoredAt: timestamp('anchored_at').defaultNow(),
retryCount: integer('retry_count').default(0),
lastError: text('last_error'),
createdAt: timestamp('created_at').defaultNow(),
});
export const verificationRequests = pgTable('verification_requests', {
id: uuid('id').primaryKey().defaultRandom(),
tenantId: uuid('tenant_id').notNull(),
requestedBy: uuid('requested_by').notNull(),
eventHash: varchar('event_hash', { length: 64 }).notNull(),
rootId: uuid('root_id'),
verificationResult: varchar('verification_result', { length: 20 }),
// verified | not_found | tampered | pending
proofData: jsonb('proof_data'), // Merkle proof + blockchain anchor data
createdAt: timestamp('created_at').defaultNow(),
});
audit.merkle.tree.built → { rootId, rootHash, leafCount, windowStart, windowEnd }
audit.blockchain.anchored → { rootId, chainType, txHash, blockNumber }
audit.blockchain.confirmed → { rootId, chainType, txHash, confirmations }
audit.blockchain.failed → { rootId, chainType, error, retryCount }
audit.verification.requested → { requestId, eventHash, requestedBy }
audit.verification.completed → { requestId, result, rootId }
audit.integrity.check.passed → { rootId, verifiedLeafCount }
audit.integrity.check.failed → { rootId, failedLeafCount, details }