fix: add session origin tracking + idle rotation foundation (schema/auth/config)

Backend infrastructure for WeChat/H5 session unification:

- schema.sql: h5_user_sessions adds origin ENUM('h5','wechat') column
- db.mjs: idempotent migration for origin column (adds after user_id)
- user-auth.mjs:
  - setSessionOrigin(sessionId, origin) - tag where session was created
  - getSessionOrigins(sessionIds) - batch lookup for history labeling
  - touchWechatAgentRoute(appId, openid) - refresh activity timestamp
- wechat-mp.mjs:
  - DEFAULT_SESSION_IDLE_ROTATE_MS = 30min (env-configurable)
  - loadWechatMpConfig includes sessionIdleRotateMs

Tests: 50/50 pass ✓

Still TODO:
- ensureWechatAgentSession idle rotation check + setSessionOrigin call
- runIntentMessage grantedSkills flow + touchWechatAgentRoute calls
- Frontend type/UI component updates
- Integration test for idle rotation

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
john
2026-07-01 21:10:56 +08:00
parent ec375b1402
commit 4fc59729ee
4 changed files with 41 additions and 0 deletions
+29
View File
@@ -764,6 +764,24 @@ export function createUserAuth(pool, options = {}) {
return new Set(rows.map((row) => row.agent_session_id));
};
const setSessionOrigin = async (agentSessionId, origin) => {
if (!agentSessionId || (origin !== 'h5' && origin !== 'wechat')) return;
await pool.query(
`UPDATE h5_user_sessions SET origin = ? WHERE agent_session_id = ?`,
[origin, agentSessionId],
);
};
const getSessionOrigins = async (agentSessionIds = []) => {
const ids = [...new Set(agentSessionIds)].filter(Boolean);
if (ids.length === 0) return new Map();
const [rows] = await pool.query(
`SELECT agent_session_id, origin FROM h5_user_sessions WHERE agent_session_id IN (?)`,
[ids],
);
return new Map(rows.map((row) => [row.agent_session_id, row.origin]));
};
const unregisterAgentSession = async (userId, agentSessionId) => {
await pool.query(
`DELETE FROM h5_user_sessions WHERE agent_session_id = ? AND user_id = ?`,
@@ -2221,6 +2239,14 @@ export function createUserAuth(pool, options = {}) {
]);
};
const touchWechatAgentRoute = async (appId, openid, now = Date.now()) => {
if (!appId || !openid) return;
await pool.query(
`UPDATE h5_wechat_agent_routes SET updated_at = ? WHERE app_id = ? AND openid = ?`,
[now, appId, openid],
);
};
const recordWechatMpMessage = async ({
appId,
openid,
@@ -2806,6 +2832,7 @@ export function createUserAuth(pool, options = {}) {
getWechatAgentRoute,
upsertWechatAgentRoute,
clearWechatAgentRoute,
touchWechatAgentRoute,
recordWechatMpMessage,
finishWechatMpMessage,
insertWechatMpMessageDetail,
@@ -2825,6 +2852,8 @@ export function createUserAuth(pool, options = {}) {
unregisterAgentSession,
ownsSession,
listOwnedSessionIds,
setSessionOrigin,
getSessionOrigins,
canUseChat,
getUserById,
getUserPublic,