Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
P
pac
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ai-tools
pac
Commits
69561c3a
Commit
69561c3a
authored
Aug 29, 2026
by
luoqi
Browse files
Options
Browse Files
Download
Plain Diff
merge: 召回场景 SQL dump 开关 → test
parents
3077902e
38e59329
Pipeline
#3609
failed in 0 seconds
Changes
2
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
28 additions
and
3 deletions
+28
-3
apps/pac-service/src/modules/plan/engine/scenarios/treatment-initiation-recall.scenario.ts
+16
-1
apps/pac-service/tests/recall-future-return-visit-gate.spec.ts
+12
-2
No files found.
apps/pac-service/src/modules/plan/engine/scenarios/treatment-initiation-recall.scenario.ts
View file @
69561c3a
...
@@ -374,7 +374,7 @@ export class TreatmentInitiationRecallScenario implements PlanScenarioPlugin {
...
@@ -374,7 +374,7 @@ export class TreatmentInitiationRecallScenario implements PlanScenarioPlugin {
// ║ 输出:每个命中 (patient × sig) 一行,后段 byPatient Map 去重 ║
// ║ 输出:每个命中 (patient × sig) 一行,后段 byPatient Map 去重 ║
// ║ 只留 daysSince 最大那条(最早诊断 = 最有召回价值) ║
// ║ 只留 daysSince 最大那条(最早诊断 = 最有召回价值) ║
// ╚═════════════════════════════════════════════════════════════════════╝
// ╚═════════════════════════════════════════════════════════════════════╝
const
rows
:
HitRow
[]
=
await
this
.
prisma
.
$queryRaw
`
const
scenarioSql
=
Prisma
.
sql
`
SELECT
SELECT
p.id AS patient_id,
p.id AS patient_id,
p.external_id AS patient_external_id,
p.external_id AS patient_external_id,
...
@@ -466,6 +466,21 @@ export class TreatmentInitiationRecallScenario implements PlanScenarioPlugin {
...
@@ -466,6 +466,21 @@ export class TreatmentInitiationRecallScenario implements PlanScenarioPlugin {
)
)
`
;
`
;
// ⚡ 调试开关:PAC_RECALL_DUMP_SQL=1 时把本子场景的完整 SQL 打出来。
// 为什么需要:pg_stat_activity.query 被 track_activity_query_size(默认 1024 字节)截断,
// 而本查询远超这个长度 —— 线上抓到"某条子场景查询跑了 6.7 分钟"却拿不到全文做 EXPLAIN,
// 2026-08-29 排查 plan 段耗时就卡在这一步。开关默认关,零开销。
// 用法:PAC_RECALL_DUMP_SQL=1 pnpm recompute-plans:prod -- --host=jvs-dw
// 然后把打出来的 SQL 喂给 EXPLAIN (ANALYZE, BUFFERS)。
if
(
process
.
env
.
PAC_RECALL_DUMP_SQL
===
'1'
)
{
this
.
logger
.
log
(
`[dump-sql] subKey=
${
subKey
}
primaryCode=
${
cfg
.
primaryCode
}
len=
${
scenarioSql
.
sql
.
length
}
\n`
+
`
${
scenarioSql
.
sql
}
\n`
+
`[dump-sql-params]
${
JSON
.
stringify
(
scenarioSql
.
values
)}
`
,
);
}
const
rows
:
HitRow
[]
=
await
this
.
prisma
.
$queryRaw
(
scenarioSql
);
// ⭐ 同 patient 同 sub_scenario 的多 sig 按 tooth-overlap 合并(union-find)
// ⭐ 同 patient 同 sub_scenario 的多 sig 按 tooth-overlap 合并(union-find)
// 跟 chain-composer 的 bucket 合并口径一致 → reason 与 chain 1:1 对齐
// 跟 chain-composer 的 bucket 合并口径一致 → reason 与 chain 1:1 对齐
// 场景:王燕桦 K01 3 个 sig(38 / 48;38 / 18;28;38)牙位重叠 → 1 个临床 episode
// 场景:王燕桦 K01 3 个 sig(38 / 48;38 / 18;28;38)牙位重叠 → 1 个临床 episode
...
...
apps/pac-service/tests/recall-future-return-visit-gate.spec.ts
View file @
69561c3a
...
@@ -47,8 +47,18 @@ function flatten(frag: Prisma.Sql | SqlLike | unknown): string {
...
@@ -47,8 +47,18 @@ function flatten(frag: Prisma.Sql | SqlLike | unknown): string {
/// 返回 [] 让调用方走空结果短路,不需要再 mock 后续查询。
/// 返回 [] 让调用方走空结果短路,不需要再 mock 后续查询。
function
makeSqlCapturingPrisma
():
{
prisma
:
PrismaService
;
sql
:
()
=>
string
}
{
function
makeSqlCapturingPrisma
():
{
prisma
:
PrismaService
;
sql
:
()
=>
string
}
{
const
captured
:
string
[]
=
[];
const
captured
:
string
[]
=
[];
const
queryRaw
=
(
strings
:
TemplateStringsArray
,
...
values
:
unknown
[])
=>
{
const
queryRaw
=
(
strings
:
TemplateStringsArray
|
{
sql
?:
string
},
...
values
:
unknown
[])
=>
{
const
parts
=
Array
.
isArray
(
strings
?.
raw
)
?
strings
.
raw
:
[
String
(
strings
)];
// 两种调用形态都要认:
// ① 标签模板 `$queryRaw`...`` → strings 是 TemplateStringsArray
// ② 传 Prisma.sql 对象 `$queryRaw(sql)` → strings 是 Sql,已摊平好的 .sql 直接用
// (2026-08-29 起主查询走 ② —— 先建 Prisma.sql 对象才能在 PAC_RECALL_DUMP_SQL=1 时
// 打出完整 SQL 做 EXPLAIN;pg_stat_activity 会把它截断在 1024 字节。)
if
(
typeof
(
strings
as
{
sql
?:
string
})?.
sql
===
'string'
)
{
captured
.
push
((
strings
as
{
sql
:
string
}).
sql
);
return
Promise
.
resolve
([]);
}
const
t
=
strings
as
TemplateStringsArray
;
const
parts
=
Array
.
isArray
(
t
?.
raw
)
?
t
.
raw
:
[
String
(
strings
)];
captured
.
push
(
parts
.
map
((
s
,
i
)
=>
s
+
(
i
<
values
.
length
?
flatten
(
values
[
i
])
:
''
)).
join
(
''
));
captured
.
push
(
parts
.
map
((
s
,
i
)
=>
s
+
(
i
<
values
.
length
?
flatten
(
values
[
i
])
:
''
)).
join
(
''
));
return
Promise
.
resolve
([]);
return
Promise
.
resolve
([]);
};
};
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment