import { mergeMindSpacePagePatch, normalizeMindSpacePagePatchInput } from './mindspace-page-patch.mjs'; export function createPageLiveEditService({ pageService, resolveUserIdForAgentSession }) { /** @type {Map} */ const sessionBindings = new Map(); /** @type {Map} */ const liveRevisions = new Map(); const bumpRevision = (pageId) => { liveRevisions.set(pageId, (liveRevisions.get(pageId) ?? 0) + 1); }; return { bindSession({ userId, sessionId, pageId, parentSessionId = null }) { if (!userId || !sessionId || !pageId) { throw Object.assign(new Error('缺少绑定参数'), { code: 'invalid_request' }); } sessionBindings.set(String(sessionId), { userId: String(userId), pageId: String(pageId), parentSessionId: parentSessionId ? String(parentSessionId) : null, boundAt: Date.now(), }); return { sessionId: String(sessionId), pageId: String(pageId), ...(parentSessionId ? { parentSessionId: String(parentSessionId) } : {}), }; }, unbindSession(sessionId) { sessionBindings.delete(String(sessionId)); }, getBinding(sessionId) { return sessionBindings.get(String(sessionId)) ?? null; }, getLiveRevision(pageId) { return liveRevisions.get(String(pageId)) ?? 0; }, async applyAgentPatch(input) { const sessionId = String(input?.sessionId ?? input?.session_id ?? '').trim(); const pageId = String(input?.pageId ?? input?.page_id ?? '').trim(); if (!sessionId || !pageId) { throw Object.assign(new Error('缺少 session_id 或 page_id'), { code: 'invalid_request' }); } const userId = await resolveUserIdForAgentSession(sessionId); if (!userId) { throw Object.assign(new Error('无效的 Agent 会话'), { code: 'forbidden' }); } const binding = sessionBindings.get(sessionId); if (binding && binding.pageId !== pageId) { throw Object.assign(new Error('当前会话未绑定该页面'), { code: 'page_binding_mismatch' }); } if (binding && binding.userId !== userId) { throw Object.assign(new Error('会话与用户不匹配'), { code: 'forbidden' }); } const patch = normalizeMindSpacePagePatchInput(input); if (!patch) { throw Object.assign(new Error('缺少 title / summary / content 变更'), { code: 'invalid_request' }); } const page = await pageService.getPage(userId, pageId); const merged = mergeMindSpacePagePatch( { title: page.title, summary: page.summary ?? '', content: page.content ?? '', }, patch, ); const updated = await pageService.updatePage(userId, pageId, { expectedVersion: input?.expectedVersion ?? input?.expected_version ?? page.versionNo, title: merged.title, summary: merged.summary, content: merged.content, templateId: page.templateId, changeNote: String(input?.changeNote ?? input?.change_note ?? 'Agent 对话修改').slice(0, 255), }); bumpRevision(pageId); return { page: updated, liveRevision: liveRevisions.get(pageId) ?? 0, }; }, async getRevisionSnapshot(userId, pageId) { const page = await pageService.getPage(userId, pageId); return { pageId: page.id, versionNo: page.versionNo, updatedAt: page.updatedAt, liveRevision: liveRevisions.get(pageId) ?? 0, }; }, }; }