fix(chat): keep rectification sessions findable and keep the delivery card
Independent Staging Quality Gate / validate (push) Failing after 6m45s
Independent Staging Quality Gate / publish (push) Skipped

Rectification answers now advance chat_sessions.updated_at (BUG-704).
A ?c= id missing from the loaded page is fetched before anyone may call
it deleted (BUG-705). The range card no longer has a post-card tie-break
button; live questions leave the card visible with adopt locked
(BUG-706/708). Spoken copy bans 相对支持度 (BUG-709).

Task docs assigned 700-704; qizheng already took 700-703.
This commit is contained in:
jesse-ux
2026-09-15 17:10:53 +08:00
parent d3a2c48ba5
commit f51e494c5a
37 changed files with 799 additions and 177 deletions
@@ -2,7 +2,7 @@ import pg from "pg";
const { Client } = pg;
const MATCH_SQL = `
const TITLE_MATCH_SQL = `
session_type = 'birth_time_rectification'
and title ~ '^[0-9]{1,2}月[0-9]{1,2}日[[:space:]]*·[[:space:]]*生时校正([[:space:]]+[0-9]{2}:[0-9]{2})?$'
and (
@@ -14,9 +14,9 @@ and (
)
`;
const COUNT_SQL = `select count(*)::int as n from public.chat_sessions where ${MATCH_SQL}`;
const TITLE_COUNT_SQL = `select count(*)::int as n from public.chat_sessions where ${TITLE_MATCH_SQL}`;
const APPLY_SQL = `
const TITLE_APPLY_SQL = `
update public.chat_sessions
set title = case
when created_at is null then '生时校正'
@@ -25,7 +25,37 @@ set title = case
|| to_char(created_at at time zone 'Asia/Shanghai', 'FMDD')
|| '日 · 生时校正'
end
where ${MATCH_SQL}
where ${TITLE_MATCH_SQL}
`;
const ACTIVITY_COUNT_SQL = `
select count(*)::int as n
from public.chat_sessions as session
join public.agentic_rectification_cases as case_row
on case_row.session_id = session.id
and case_row.user_id = session.user_id
left join lateral (
select max(turn.created_at) as last_turn_at
from public.agentic_rectification_turns as turn
where turn.case_id = case_row.id
) as turns on true
where session.session_type = 'birth_time_rectification'
and session.updated_at < coalesce(turns.last_turn_at, case_row.last_activity_at)
`;
const ACTIVITY_APPLY_SQL = `
update public.chat_sessions as session
set updated_at = coalesce(turns.last_turn_at, case_row.last_activity_at)
from public.agentic_rectification_cases as case_row
left join lateral (
select max(turn.created_at) as last_turn_at
from public.agentic_rectification_turns as turn
where turn.case_id = case_row.id
) as turns on true
where case_row.session_id = session.id
and case_row.user_id = session.user_id
and session.session_type = 'birth_time_rectification'
and session.updated_at < coalesce(turns.last_turn_at, case_row.last_activity_at)
`;
function connectionString() {
@@ -44,14 +74,19 @@ async function main() {
const client = new Client({ connectionString: connectionString() });
await client.connect();
try {
const before = await client.query(COUNT_SQL);
const n = before.rows[0]?.n ?? 0;
console.log(`mismatched_dated_rectification_titles=${n}`);
const titlesBefore = await client.query(TITLE_COUNT_SQL);
const activityBefore = await client.query(ACTIVITY_COUNT_SQL);
console.log(`mismatched_dated_rectification_titles=${titlesBefore.rows[0]?.n ?? 0}`);
console.log(`stale_rectification_updated_at=${activityBefore.rows[0]?.n ?? 0}`);
if (!apply) return;
const updated = await client.query(APPLY_SQL);
const after = await client.query(COUNT_SQL);
console.log(`updated_rows=${updated.rowCount ?? 0}`);
console.log(`mismatched_after=${after.rows[0]?.n ?? 0}`);
const titlesUpdated = await client.query(TITLE_APPLY_SQL);
const activityUpdated = await client.query(ACTIVITY_APPLY_SQL);
const titlesAfter = await client.query(TITLE_COUNT_SQL);
const activityAfter = await client.query(ACTIVITY_COUNT_SQL);
console.log(`updated_title_rows=${titlesUpdated.rowCount ?? 0}`);
console.log(`updated_activity_rows=${activityUpdated.rowCount ?? 0}`);
console.log(`mismatched_after=${titlesAfter.rows[0]?.n ?? 0}`);
console.log(`stale_updated_at_after=${activityAfter.rows[0]?.n ?? 0}`);
} finally {
await client.end();
}