Files
memind/server/portal-mindspace-agent-operation-routes.mjs

120 lines
3.6 KiB
JavaScript

function assertRouter(api) {
if (!api || typeof api.post !== 'function') {
throw new Error(
'attachPortalMindSpaceAgentOperationRoutes requires an Express-compatible router',
);
}
}
export function attachPortalMindSpaceAgentOperationRoutes(
api,
{
getMindSpacePageLiveEdit = () => null,
getMindSpaceAssetAgent = () => null,
getMindSpaceAudit = () => null,
sendData = (res, _req, data, status = 200) =>
res.status(status).json({ data }),
sendError = (res, _req, status, code, message) =>
res.status(status).json({ error: { code, message } }),
handleMindSpaceError = (_res, _req, error) => {
throw error;
},
} = {},
) {
assertRouter(api);
api.post('/agent/mindspace_page_patch', async (req, res) => {
const pageLiveEdit = getMindSpacePageLiveEdit();
if (!pageLiveEdit) {
return res.status(503).json({ message: 'MindSpace 未启用' });
}
try {
const result = await pageLiveEdit.applyAgentPatch(req.body ?? {});
return res.json({
data: {
pageId: result.page.id,
title: result.page.title,
summary: result.page.summary,
versionNo: result.page.versionNo,
updatedAt: result.page.updatedAt,
liveRevision: result.liveRevision,
},
});
} catch (error) {
if (
error?.code === 'forbidden' ||
error?.code === 'page_binding_mismatch'
) {
return sendError(res, req, 403, error.code, error.message);
}
if (error?.code === 'invalid_request') {
return sendError(res, req, 400, error.code, error.message);
}
return handleMindSpaceError(res, req, error);
}
});
api.post('/agent/mindspace_asset_delete', async (req, res) => {
const assetAgent = getMindSpaceAssetAgent();
if (!assetAgent) {
return res.status(503).json({ message: 'MindSpace 未启用' });
}
try {
const result = await assetAgent.applyAgentDelete(req.body ?? {});
await getMindSpaceAudit()?.write({
userId: result.userId ?? null,
action: 'asset.delete',
objectType: 'asset',
objectId: result.assetId,
ip: req.ip,
metadata: { via: 'agent' },
});
return sendData(res, req, result);
} catch (error) {
if (error?.code === 'forbidden') {
return sendError(res, req, 403, error.code, error.message);
}
if (
error?.code === 'invalid_request' ||
error?.code === 'confirmation_required'
) {
return sendError(res, req, 400, error.code, error.message);
}
return handleMindSpaceError(res, req, error);
}
});
api.post('/agent/mindspace_asset_download', async (req, res) => {
const assetAgent = getMindSpaceAssetAgent();
if (!assetAgent) {
return res.status(503).json({ message: 'MindSpace 未启用' });
}
try {
const result = await assetAgent.applyAgentDownload(req.body ?? {});
await getMindSpaceAudit()?.write({
userId: result.userId ?? null,
action: 'asset.download',
objectType: 'asset',
objectId: result.assetId,
ip: req.ip,
metadata: {
via: 'agent',
relativePath: result.relativePath ?? null,
},
});
return sendData(res, req, result);
} catch (error) {
if (error?.code === 'forbidden') {
return sendError(res, req, 403, error.code, error.message);
}
if (
error?.code === 'invalid_request' ||
error?.code === 'asset_not_found'
) {
return sendError(res, req, 400, error.code, error.message);
}
return handleMindSpaceError(res, req, error);
}
});
}