优化任务状态投影和部署文档

This commit is contained in:
yml
2026-05-28 11:12:40 +08:00
parent 9709643583
commit ccc350cfea
15 changed files with 759 additions and 55 deletions
@@ -0,0 +1,111 @@
import { query } from '../db/client.js'
import { maskCode } from '../utils/masking.js'
import { parseTaskContext } from '../utils/task-json.js'
type QueryExecutor = (text: string, params?: unknown[]) => Promise<{ rows: unknown[] }>
type JsonRecord = Record<string, any>
export type KuaishouCloudTaskStateSyncInput = {
taskId: number | string
executorKey?: unknown
contextJson?: unknown
updatedAt?: unknown
}
export async function syncKuaishouCloudTaskStateForTask(
input: KuaishouCloudTaskStateSyncInput,
executor: QueryExecutor = query,
): Promise<void> {
const taskId = Number(input.taskId || 0)
if (!Number.isFinite(taskId) || taskId <= 0) {
return
}
if (String(input.executorKey || '').trim() !== 'kuaishou_ct_assisted') {
await executor('DELETE FROM kuaishou_cloud_task_states WHERE task_id = $1', [taskId])
return
}
const flow = resolveKuaishouCloudFlow(input.contextJson)
if (!flow) {
await executor('DELETE FROM kuaishou_cloud_task_states WHERE task_id = $1', [taskId])
return
}
const ticket = asRecord(flow.ticket)
const binding = asRecord(flow.binding)
const role = asRecord(flow.role)
const dispatch = asRecord(flow.dispatch)
const consume = asRecord(flow.consume)
const roleName = pickFirstNonEmpty([role.name, binding.roleName])
const roleId = pickFirstNonEmpty([role.rid, binding.roleId])
const updatedAt = String(input.updatedAt || '').trim() || new Date().toISOString()
await executor(
`
INSERT INTO kuaishou_cloud_task_states (
task_id,
ticket_status,
ticket_code_masked,
bind_url,
vn_phone,
role_name,
role_id,
dispatch_status,
consume_status,
source_key,
updated_at
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
ON CONFLICT (task_id) DO UPDATE
SET
ticket_status = EXCLUDED.ticket_status,
ticket_code_masked = EXCLUDED.ticket_code_masked,
bind_url = EXCLUDED.bind_url,
vn_phone = EXCLUDED.vn_phone,
role_name = EXCLUDED.role_name,
role_id = EXCLUDED.role_id,
dispatch_status = EXCLUDED.dispatch_status,
consume_status = EXCLUDED.consume_status,
source_key = EXCLUDED.source_key,
updated_at = EXCLUDED.updated_at
`,
[
taskId,
normalizeStatus(ticket.status),
maskCode(ticket.code),
String(binding.bindUrl || '').trim(),
String(binding.vnPhone || '').trim(),
roleName,
roleId,
normalizeStatus(dispatch.status),
normalizeStatus(consume.status),
String(binding.resolvedSourceKey || '').trim(),
updatedAt,
],
)
}
function resolveKuaishouCloudFlow(contextJson: unknown): JsonRecord | null {
const context = parseTaskContext({ context_json: contextJson })
const flow = asRecord(context.kuaishouCloudFulfillment)
return Object.keys(flow).length > 0 ? flow : null
}
function asRecord(value: unknown): JsonRecord {
return value && typeof value === 'object' && !Array.isArray(value) ? value as JsonRecord : {}
}
function normalizeStatus(value: unknown): string {
return String(value || 'pending').trim() || 'pending'
}
function pickFirstNonEmpty(values: unknown[]): string {
for (const value of values) {
const normalized = String(value || '').trim()
if (normalized) {
return normalized
}
}
return ''
}