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.
99 lines
3.5 KiB
JavaScript
99 lines
3.5 KiB
JavaScript
import pg from "pg";
|
|
|
|
const { Client } = pg;
|
|
|
|
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 (
|
|
created_at is null
|
|
or (substring(title from '^([0-9]{1,2})月'))::int
|
|
is distinct from extract(month from created_at at time zone 'Asia/Shanghai')::int
|
|
or (substring(title from '月([0-9]{1,2})日'))::int
|
|
is distinct from extract(day from created_at at time zone 'Asia/Shanghai')::int
|
|
)
|
|
`;
|
|
|
|
const TITLE_COUNT_SQL = `select count(*)::int as n from public.chat_sessions where ${TITLE_MATCH_SQL}`;
|
|
|
|
const TITLE_APPLY_SQL = `
|
|
update public.chat_sessions
|
|
set title = case
|
|
when created_at is null then '生时校正'
|
|
else to_char(created_at at time zone 'Asia/Shanghai', 'FMMM')
|
|
|| '月'
|
|
|| to_char(created_at at time zone 'Asia/Shanghai', 'FMDD')
|
|
|| '日 · 生时校正'
|
|
end
|
|
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() {
|
|
const value = process.env.SCHEMA_DATABASE_URL?.trim();
|
|
if (!value) {
|
|
throw new Error("SCHEMA_DATABASE_URL is required");
|
|
}
|
|
if (!/^postgres(ql)?:\/\//.test(value)) {
|
|
throw new Error("SCHEMA_DATABASE_URL must be a PostgreSQL URL");
|
|
}
|
|
return value;
|
|
}
|
|
|
|
async function main() {
|
|
const apply = process.argv.includes("--apply");
|
|
const client = new Client({ connectionString: connectionString() });
|
|
await client.connect();
|
|
try {
|
|
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 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();
|
|
}
|
|
}
|
|
|
|
main().catch((error) => {
|
|
console.error(error instanceof Error ? error.message : error);
|
|
process.exit(1);
|
|
});
|