// @ts-check import { query } from '../db/client.js' /** @typedef {import('../types/repository-inputs.js').WebhookEventCreateInput} WebhookEventCreateInput */ /** @typedef {import('../types/repository-inputs.js').WebhookEventListQueryInput} WebhookEventListQueryInput */ /** @typedef {import('../types/repository-inputs.js').WebhookEventUpdatePatch} WebhookEventUpdatePatch */ /** @typedef {import('../types/repository-rows.js').WebhookEventListQueryResult} WebhookEventListQueryResult */ /** @typedef {import('../types/repository-rows.js').WebhookEventRow} WebhookEventRow */ /** @returns {Promise} */ /** @param {WebhookEventCreateInput} input */ export async function createWebhookEvent(input) { const result = await query( ` INSERT INTO webhook_events ( provider, platform, shop_id, shop_name, event_type, event_key, signature_valid, headers_json, query_json, body_json, processed, process_error, related_order_id, created_at ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8::jsonb, $9::jsonb, $10::jsonb, $11, $12, $13, $14) RETURNING * `, [ input.provider, input.platform, input.shopId || '', input.shopName || '', input.eventType, input.eventKey, Boolean(input.signatureValid), input.headersJson || '{}', input.queryJson || '{}', input.bodyJson || '{}', Boolean(input.processed), input.processError || '', input.relatedOrderId || null, input.createdAt, ], ) return /** @type {WebhookEventRow | null} */ (result.rows[0] || null) } /** @returns {Promise} */ /** @param {WebhookEventUpdatePatch} patch */ export async function updateWebhookEvent(eventId, patch) { const current = await getWebhookEventById(eventId) if (!current) { return null } const next = { ...current, ...patch } const result = await query( ` UPDATE webhook_events SET processed = $1, process_error = $2, related_order_id = $3 WHERE id = $4 RETURNING * `, [Boolean(next.processed), next.process_error || '', next.related_order_id || null, Number(eventId)], ) return /** @type {WebhookEventRow | null} */ (result.rows[0] || null) } /** @returns {Promise} */ export async function getWebhookEventById(eventId) { const result = await query('SELECT * FROM webhook_events WHERE id = $1 LIMIT 1', [Number(eventId)]) return /** @type {WebhookEventRow | null} */ (result.rows[0] || null) } /** @returns {Promise} */ /** @param {WebhookEventListQueryInput} [queryInput] */ export async function listWebhookEvents({ page = 1, pageSize = 20, provider = '', platform = '', platformOrderId = '', processed = '', visibility = 'important', relatedOrderId = '', dateFrom = '', dateTo = '', } = /** @type {WebhookEventListQueryInput} */ ({})) { const offset = (page - 1) * pageSize const filters = [] const params = [] if (provider) { params.push(provider) filters.push(`provider = $${params.length}`) } if (platform) { params.push(platform) filters.push(`platform = $${params.length}`) } if (platformOrderId) { params.push(`%${platformOrderId}%`) filters.push(`(event_key ILIKE $${params.length} OR body_json::text ILIKE $${params.length})`) } if (processed === '0' || processed === '1') { params.push(processed === '1') filters.push(`processed = $${params.length}`) } if (visibility === 'ignored') { filters.push(`process_error LIKE 'ignored_%'`) } else if (visibility === 'important') { filters.push(`(process_error = '' OR process_error NOT LIKE 'ignored_%')`) } if (relatedOrderId) { params.push(Number(relatedOrderId)) filters.push(`related_order_id = $${params.length}`) } if (dateFrom) { params.push(dateFrom) filters.push(`created_at >= $${params.length}`) } if (dateTo) { params.push(dateTo) filters.push(`created_at <= $${params.length}`) } const whereClause = filters.length > 0 ? `WHERE ${filters.join(' AND ')}` : '' const totalResult = await query(`SELECT COUNT(*)::int AS total FROM webhook_events ${whereClause}`, params) params.push(pageSize) params.push(offset) const itemsResult = await query( ` SELECT * FROM webhook_events ${whereClause} ORDER BY id DESC LIMIT $${params.length - 1} OFFSET $${params.length} `, params, ) return { items: /** @type {WebhookEventRow[]} */ (itemsResult.rows), total: Number(totalResult.rows[0]?.total || 0), } } /** @returns {Promise} */ export async function listWebhookEventsByOrderId(orderId) { const result = await query( ` SELECT * FROM webhook_events WHERE related_order_id = $1 ORDER BY id DESC `, [Number(orderId)], ) return /** @type {WebhookEventRow[]} */ (result.rows) }