Files
AIclinicalresearch/backend/scripts/analyze_missing_equery_context.ts
HaHafeng a666649fd4 feat(iit): harden QC pipeline consistency and release artifacts
Implement IIT quality workflow hardening across eQuery deduplication, guard metadata validation, timeline/readability improvements, and chat evidence fallbacks, then synchronize release and development documentation for deployment handoff.

Includes migration/scripts for open eQuery dedupe guards, orchestration/status semantics, report/tool readability fixes, and updated module status plus deployment checklist.

Made-with: Cursor
2026-03-08 21:54:35 +08:00

98 lines
2.7 KiB
TypeScript

import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
const projectId = process.argv[2];
if (!projectId) {
throw new Error('Usage: npx tsx scripts/analyze_missing_equery_context.ts <projectId>');
}
const reasonStats = await prisma.$queryRawUnsafe<Array<{ reason: string; cnt: bigint }>>(`
WITH missing AS (
SELECT
e.id,
e.record_id,
e.category,
e.field_name,
e.event_id,
e.form_name,
e.created_at
FROM iit_schema.equery e
WHERE e.project_id = $1
AND (COALESCE(e.event_id, '') = '' OR COALESCE(e.form_name, '') = '')
),
flags AS (
SELECT
m.*,
EXISTS (
SELECT 1
FROM iit_schema.qc_field_status fs
WHERE fs.project_id = $1
AND fs.record_id = m.record_id
) AS has_record_match,
EXISTS (
SELECT 1
FROM iit_schema.qc_field_status fs
WHERE fs.project_id = $1
AND fs.record_id = m.record_id
AND COALESCE(fs.rule_name, '') = COALESCE(m.category, '')
) AS has_rule_match,
EXISTS (
SELECT 1
FROM iit_schema.qc_field_status fs
WHERE fs.project_id = $1
AND fs.record_id = m.record_id
AND COALESCE(fs.rule_name, '') = COALESCE(m.category, '')
AND COALESCE(fs.field_name, '') = COALESCE(m.field_name, '')
) AS has_rule_field_match
FROM missing m
)
SELECT
CASE
WHEN has_rule_field_match THEN 'A_RULE_FIELD_MATCH_BUT_EVENT_FORM_EMPTY'
WHEN has_rule_match THEN 'B_RULE_MATCH_FIELD_MISMATCH'
WHEN has_record_match THEN 'C_RECORD_MATCH_ONLY'
ELSE 'D_NO_RECORD_MATCH'
END AS reason,
COUNT(*)::bigint AS cnt
FROM flags
GROUP BY 1
ORDER BY 2 DESC
`, projectId);
const sample = await prisma.$queryRawUnsafe<Array<{
id: string;
record_id: string;
category: string | null;
field_name: string | null;
event_id: string | null;
form_name: string | null;
created_at: Date;
}>>(`
SELECT
id, record_id, category, field_name, event_id, form_name, created_at
FROM iit_schema.equery
WHERE project_id = $1
AND (COALESCE(event_id, '') = '' OR COALESCE(form_name, '') = '')
ORDER BY created_at DESC
LIMIT 20
`, projectId);
console.log(JSON.stringify({
projectId,
reasonStats: reasonStats.map((r) => ({ reason: r.reason, cnt: Number(r.cnt) })),
sample,
}, null, 2));
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});