中性化运行上下文字段

This commit is contained in:
yml
2026-05-25 22:13:45 +08:00
parent 2103416c7b
commit 245089d871
9 changed files with 39 additions and 19 deletions
@@ -209,7 +209,7 @@ CREATE INDEX IF NOT EXISTS idx_task_events_task_created_at ON task_events(task_i
CREATE TABLE IF NOT EXISTS task_runtime_contexts (
id BIGSERIAL PRIMARY KEY,
task_id BIGINT NOT NULL UNIQUE REFERENCES fulfillment_tasks(id) ON DELETE CASCADE,
browser_session_id TEXT NOT NULL DEFAULT '',
runtime_session_id TEXT NOT NULL DEFAULT '',
login_type TEXT NOT NULL DEFAULT '',
nickname TEXT NOT NULL DEFAULT '',
role_id TEXT NOT NULL DEFAULT '',
@@ -0,0 +1,20 @@
DO $$
BEGIN
IF to_regclass('public.task_runtime_contexts') IS NOT NULL
AND EXISTS (
SELECT 1
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'task_runtime_contexts'
AND column_name = 'browser_session_id'
)
AND NOT EXISTS (
SELECT 1
FROM information_schema.columns
WHERE table_schema = 'public'
AND table_name = 'task_runtime_contexts'
AND column_name = 'runtime_session_id'
) THEN
ALTER TABLE task_runtime_contexts RENAME COLUMN browser_session_id TO runtime_session_id;
END IF;
END $$;
+9 -9
View File
@@ -15,7 +15,7 @@ import type {
type TaskQueryExecutor = (text: string, params?: unknown[]) => Promise<{ rows: unknown[] }>
type TaskRuntimeContextRow = {
browser_session_id: string
runtime_session_id: string
login_type: string
nickname: string
role_id: string
@@ -33,7 +33,7 @@ const TASK_FIELDS = `
ct.token AS primary_claim_token,
ct.status AS primary_claim_token_status,
ct.expired_at AS primary_claim_expires_at,
ctx.browser_session_id,
ctx.runtime_session_id,
ctx.login_type,
ctx.nickname,
ctx.role_id,
@@ -222,7 +222,7 @@ export async function updateTask(taskId: number | string, patch: TaskUpdatePatch
if (containsRuntimeContextPatch(patch)) {
await upsertTaskRuntimeContextWithClient(client, Number(taskId), {
runtimeSessionId: patch.browser_session_id,
runtimeSessionId: patch.runtime_session_id,
loginType: patch.login_type,
nickname: patch.nickname,
roleId: patch.role_id,
@@ -346,7 +346,7 @@ async function upsertTaskRuntimeContextWithClient(
const current = currentResult.rows[0] || null
const next = {
browser_session_id: patch.runtimeSessionId ?? current?.browser_session_id ?? '',
runtime_session_id: patch.runtimeSessionId ?? current?.runtime_session_id ?? '',
login_type: patch.loginType ?? current?.login_type ?? '',
nickname: patch.nickname ?? current?.nickname ?? '',
role_id: patch.roleId ?? current?.role_id ?? '',
@@ -364,7 +364,7 @@ async function upsertTaskRuntimeContextWithClient(
`
INSERT INTO task_runtime_contexts (
task_id,
browser_session_id,
runtime_session_id,
login_type,
nickname,
role_id,
@@ -380,7 +380,7 @@ async function upsertTaskRuntimeContextWithClient(
`,
[
Number(taskId),
next.browser_session_id,
next.runtime_session_id,
next.login_type,
next.nickname,
next.role_id,
@@ -401,7 +401,7 @@ async function upsertTaskRuntimeContextWithClient(
`
UPDATE task_runtime_contexts
SET
browser_session_id = $1,
runtime_session_id = $1,
login_type = $2,
nickname = $3,
role_id = $4,
@@ -415,7 +415,7 @@ async function upsertTaskRuntimeContextWithClient(
WHERE task_id = $12
`,
[
next.browser_session_id,
next.runtime_session_id,
next.login_type,
next.nickname,
next.role_id,
@@ -446,7 +446,7 @@ async function getTaskByIdWithExecutor(
function containsRuntimeContextPatch(patch: TaskUpdatePatch = {}): boolean {
return [
'browser_session_id',
'runtime_session_id',
'login_type',
'nickname',
'role_id',
@@ -11,7 +11,7 @@ test('resolveAdminTaskScreenshotUrl lets support view final redeemed screenshot'
const task = {
id: 12,
screenshot_path: '/tmp/redeemed-12.png',
browser_session_id: '',
runtime_session_id: '',
}
const screenshotUrl = await resolveAdminTaskScreenshotUrl(task, createAdminViewerContext({ role: 'support' }))
@@ -19,11 +19,11 @@ test('resolveAdminTaskScreenshotUrl lets support view final redeemed screenshot'
assert.equal(screenshotUrl, '/api/v1/admin/tasks/12/screenshot')
})
test('resolveAdminTaskScreenshotUrl falls back to review screenshot when only browser session exists', async () => {
test('resolveAdminTaskScreenshotUrl falls back to review screenshot when runtime session exists', async () => {
const task = {
id: 13,
screenshot_path: '',
browser_session_id: 'browser-session-13',
runtime_session_id: 'runtime-session-13',
}
const screenshotUrl = await resolveAdminTaskScreenshotUrl(task, createAdminViewerContext({ role: 'support' }))
@@ -197,7 +197,7 @@ export async function resolveAdminTaskScreenshotUrl(
task: TaskLike,
viewerContext: AdminViewerContext,
): Promise<string> {
if (task.screenshot_path || task.browser_session_id) {
if (task.screenshot_path || task.runtime_session_id) {
return `/api/v1/admin/tasks/${task.id}/screenshot`
}
@@ -59,7 +59,7 @@ export function mapAdminTaskSummary(
systemBindingStatus: binding.systemBindingStatus,
userBindingStatus: binding.userBindingStatus,
loginType: task.login_type,
runtimeSessionId: task.browser_session_id,
runtimeSessionId: task.runtime_session_id,
claimedAt: task.claimed_at,
roleConfirmedAt: task.role_confirmed_at,
redeemedAt: task.redeemed_at,
@@ -125,7 +125,7 @@ export function mapAdminTaskListItem(
loginType: task.login_type,
roleName: task.role_name,
roleId: task.role_id,
runtimeSessionId: task.browser_session_id,
runtimeSessionId: task.runtime_session_id,
claimedAt: task.claimed_at,
roleConfirmedAt: task.role_confirmed_at,
redeemedAt: task.redeemed_at,
@@ -96,7 +96,7 @@ export function buildClaimDetailPayload({ claimToken, task, order, orderItem })
redeemedAt: task.redeemed_at,
loginType: task.login_type,
lastError: task.last_error,
runtimeSessionId: task.browser_session_id,
runtimeSessionId: task.runtime_session_id,
},
order: {
orderId: order.id,
+1 -1
View File
@@ -118,7 +118,7 @@ export type TaskUpdatePatch = {
role_confirmed_at?: string | null
redeemed_at?: string | null
updated_at?: string
browser_session_id?: string
runtime_session_id?: string
login_type?: string
nickname?: string
role_id?: string
+1 -1
View File
@@ -51,7 +51,7 @@ export type TaskRow = {
requires_claim: boolean
user_action_status: string
attempt_count: number
browser_session_id: string
runtime_session_id: string
login_type: string
nickname: string
role_name: string