Task template messages were posting to project_id=1 when local session cache lacked projectId, causing 403 on POST /api/v1/tasks/runs. Parse sess-p{id}-u{user} encoding as fallback and surface HTTP status on task failures.
Co-authored-by: Cursor <cursoragent@cursor.com>
90 lines
2.4 KiB
TypeScript
90 lines
2.4 KiB
TypeScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import {
|
|
mapServerSessionToProjectSession,
|
|
mergeSessionLists,
|
|
parseProjectIdFromSessionId,
|
|
resolveSessionProjectId,
|
|
} from './sessionAdapter';
|
|
import { ProjectInfo, ProjectSession } from '../types/workbench';
|
|
|
|
const projects: ProjectInfo[] = [
|
|
{
|
|
id: 42,
|
|
title: '便携超声',
|
|
deviceType: '超声设备',
|
|
description: '',
|
|
creatorId: 2,
|
|
creatorName: '张工',
|
|
createdAt: '2026-01-01',
|
|
members: [],
|
|
},
|
|
];
|
|
|
|
test('parseProjectIdFromSessionId decodes sess-p{id}-u{user}', () => {
|
|
assert.equal(parseProjectIdFromSessionId('sess-p143-u9'), 143);
|
|
assert.equal(parseProjectIdFromSessionId('sess-neuropulse-u1'), undefined);
|
|
});
|
|
|
|
test('resolveSessionProjectId prefers explicit id then session id encoding', () => {
|
|
assert.equal(
|
|
resolveSessionProjectId({ sessionId: 'sess-p143-u9', projectId: 0 }),
|
|
143,
|
|
);
|
|
assert.equal(
|
|
resolveSessionProjectId({ sessionId: 'sess-p143-u9', projectId: 143 }),
|
|
143,
|
|
);
|
|
});
|
|
|
|
test('mapServerSessionToProjectSession fills project metadata', () => {
|
|
const mapped = mapServerSessionToProjectSession(
|
|
{
|
|
session_id: 'sess-p42-u2',
|
|
title: '便携超声',
|
|
user_id: 2,
|
|
project_id: 42,
|
|
message_count: 3,
|
|
updated_at: new Date().toISOString(),
|
|
},
|
|
projects
|
|
);
|
|
assert.equal(mapped.sessionId, 'sess-p42-u2');
|
|
assert.equal(mapped.deviceType, '超声设备');
|
|
assert.equal(mapped.messageCount, 3);
|
|
});
|
|
|
|
test('mergeSessionLists keeps local stage while applying server counts', () => {
|
|
const local: ProjectSession[] = [
|
|
{
|
|
sessionId: 'sess-p42-u2',
|
|
userId: 2,
|
|
projectId: 42,
|
|
title: '旧标题',
|
|
deviceType: '超声设备',
|
|
stage: 'V0.5',
|
|
stageLabel: 'V0.5 可行性',
|
|
messageCount: 1,
|
|
updatedAt: '昨天',
|
|
},
|
|
];
|
|
const fromServer: ProjectSession[] = [
|
|
{
|
|
sessionId: 'sess-p42-u2',
|
|
userId: 2,
|
|
projectId: 42,
|
|
title: '便携超声',
|
|
deviceType: '超声设备',
|
|
stage: 'V0.1',
|
|
stageLabel: 'V0.1 需求摸底',
|
|
messageCount: 5,
|
|
updatedAt: '刚刚',
|
|
},
|
|
];
|
|
const merged = mergeSessionLists(local, fromServer);
|
|
assert.equal(merged.length, 1);
|
|
assert.equal(merged[0].title, '便携超声');
|
|
assert.equal(merged[0].stage, 'V0.5');
|
|
assert.equal(merged[0].messageCount, 5);
|
|
});
|