feat(iit): Implement real-time quality control system

Summary:

- Add 4 new database tables: iit_field_metadata, iit_qc_logs, iit_record_summary, iit_qc_project_stats

- Implement pg-boss debounce mechanism in WebhookController

- Refactor QC Worker for dual output: QC logs + record summary

- Enhance HardRuleEngine to support form-based rule filtering

- Create QcService for QC data queries

- Optimize ChatService with new intents: query_enrollment, query_qc_status

- Add admin batch operations: one-click full QC + one-click full summary

- Create IIT Admin management module: project config, QC rules, user mapping

Status: Code complete, pending end-to-end testing
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-07 21:56:11 +08:00
parent 0c590854b5
commit 5db4a7064c
74 changed files with 13383 additions and 2129 deletions

View File

@@ -147,19 +147,29 @@ export class PgBossQueue implements JobQueue {
// 避免每次 push 都尝试 createQueue 导致重复定义
// 发送任务到pg-boss
// ✅ 使用 singletonKey 防止同一任务被重复入队
const singletonKey = (data as any).taskId || jobId
// ✅ 支持自定义 singletonKey 和 options通过 data 中的特殊字段)
// 特殊字段__singletonKey, __singletonSeconds, __expireInSeconds
const dataObj = data as any
const singletonKey = dataObj.__singletonKey || dataObj.taskId || jobId
const singletonSeconds = dataObj.__singletonSeconds || 3600 // 默认 1 小时
const expireInSeconds = dataObj.__expireInSeconds || 6 * 60 * 60 // 默认 6 小时
// 移除特殊字段,不传入 pg-boss
const cleanData = { ...dataObj }
delete cleanData.__singletonKey
delete cleanData.__singletonSeconds
delete cleanData.__expireInSeconds
const bossJobId = await this.boss.send(type, {
...data,
...cleanData,
__jobId: jobId, // 嵌入我们的jobId
__createdAt: now.toISOString()
}, {
retryLimit: 3,
retryDelay: 60,
expireInSeconds: 6 * 60 * 60, // 6小时过期更适合长批次任务
expireInSeconds,
singletonKey, // ✅ 防止同一任务重复入队
singletonSeconds: 3600, // 1小时内不允许重复
singletonSeconds,
})
console.log(`[PgBossQueue] Job pushed: ${jobId} -> pg-boss:${bossJobId} (type: ${type})`)