fix(page-data): deliver MindSpace workspace URLs instead of /u/.../pages/ routes.

Page Data questionnaires were returning publication slugs to users; password-mode
pages always fell back to /u/ routes. Prefer MindSpace paths at publish time and
rewrite mistaken delivery links in WeChat and Portal chat.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-07-12 13:54:24 +08:00
parent 048f25f580
commit 294e331a03
12 changed files with 1224 additions and 24 deletions
+107
View File
@@ -29,6 +29,13 @@ import {
} from './wechat/prompts/page-generate.mjs';
import { selectSendableHtmlArtifacts } from './wechat/verify/page-artifact.mjs';
import { resolveBillingTokenState } from './billing-token-state.mjs';
import {
buildPageDataCollectFailureText,
buildPageDataDeliveryArtifactsFromBindResult,
maybeAutoBindPageDataHtmlPages,
resolvePageDataCollectOutcome,
rewritePageDataDeliveryLinks,
} from './mindspace-page-data-finish-guard.mjs';
export { buildWechatAgentPrompt };
@@ -1039,6 +1046,61 @@ function markWechatUserNotified(err) {
return err;
}
async function enforcePageDataCollectDelivery({
reply,
intent,
workingDir,
userId,
pageDataFinishGuard,
publicBaseUrl,
requestStartedAt = 0,
notifyFailure,
}) {
let outcome = resolvePageDataCollectOutcome({
reply,
intent,
publishDir: workingDir,
requestStartedAt,
});
let autoBind = null;
if (outcome.action === 'skip') return outcome;
if (pageDataFinishGuard?.pool) {
autoBind = await maybeAutoBindPageDataHtmlPages({
pool: pageDataFinishGuard.pool,
userId,
publishDir: workingDir,
h5Root: pageDataFinishGuard.h5Root,
storageRoot: pageDataFinishGuard.storageRoot,
});
outcome = resolvePageDataCollectOutcome({
reply,
intent,
publishDir: workingDir,
requestStartedAt,
});
}
if (outcome.action === 'retry') {
throw new Error('stale_session_poisoned_completion');
}
if (outcome.action === 'fail') {
const text = outcome.failureText ?? buildPageDataCollectFailureText();
if (typeof notifyFailure === 'function') {
await notifyFailure(text);
}
throw markWechatUserNotified(new Error(text));
}
const deliveryArtifacts = buildPageDataDeliveryArtifactsFromBindResult(autoBind, workingDir, {
publicBaseUrl,
});
if (deliveryArtifacts.length > 0 && reply && typeof reply.text === 'string') {
reply.text = rewritePageDataDeliveryLinks(reply.text, deliveryArtifacts);
}
return { ...outcome, deliveryArtifacts, autoBind };
}
function wasWechatUserNotified(err) {
return Boolean(err && typeof err === 'object' && err.wechatUserNotified);
}
@@ -1299,6 +1361,7 @@ export function createWechatMpService({
llmProviderService = null,
applySessionLlmProvider = null,
refreshSessionSnapshot = null,
pageDataFinishGuard = null,
wechatFetch = undiciFetch,
linkExists = defaultPublicHtmlLinkExists,
logger = console,
@@ -1926,6 +1989,28 @@ export function createWechatMpService({
} else if (htmlGenerationNeedsRetry || suspiciousPublishClaim) {
throw new Error('stale_session_poisoned_completion');
}
const pageDataOutcome = await enforcePageDataCollectDelivery({
reply,
intent,
workingDir,
userId: user.userId,
pageDataFinishGuard,
publicBaseUrl: config.publicBaseUrl,
requestStartedAt,
notifyFailure: async (text) => {
try {
await sendCustomerServiceText(inbound.fromUserName, text, user);
} catch (sendErr) {
logger.error?.('WeChat MP page data failure notice failed:', sendErr);
}
},
});
if (pageDataOutcome?.deliveryArtifacts?.length) {
publishArtifacts = uniqueArtifactsByUrl([
...pageDataOutcome.deliveryArtifacts,
...publishArtifacts,
]);
}
if (reply.tokenState) {
const tokenState = await resolveWechatBillingTokenState(sessionId, reply.tokenState);
await userAuth.billSessionUsage(user.userId, sessionId, tokenState, requestId);
@@ -2039,6 +2124,28 @@ export function createWechatMpService({
} else if (htmlGenerationNeedsRetry || suspiciousPublishClaim) {
throw new Error(buildHtmlPublishFailureText());
}
const pageDataOutcome = await enforcePageDataCollectDelivery({
reply,
intent,
workingDir,
userId: user.userId,
pageDataFinishGuard,
publicBaseUrl: config.publicBaseUrl,
requestStartedAt: retryStartedAt,
notifyFailure: async (text) => {
try {
await sendCustomerServiceText(inbound.fromUserName, text, user);
} catch (sendErr) {
logger.error?.('WeChat MP page data retry failure notice failed:', sendErr);
}
},
});
if (pageDataOutcome?.deliveryArtifacts?.length) {
publishArtifacts = uniqueArtifactsByUrl([
...pageDataOutcome.deliveryArtifacts,
...publishArtifacts,
]);
}
if (reply.tokenState) {
const tokenState = await resolveWechatBillingTokenState(sessionId, reply.tokenState);
await userAuth.billSessionUsage(user.userId, sessionId, tokenState, retryId);