feat(mindspace): enforce PostgreSQL user data delivery

This commit is contained in:
john
2026-07-13 15:29:29 +08:00
parent b33c943b69
commit a6620fb719
57 changed files with 2779 additions and 164 deletions
+33 -2
View File
@@ -171,6 +171,16 @@ function assertRegisteredDatasetTables(userDataSpace, registryDatasets, usage) {
}
}
async function assertRegisteredDatasetTablesAsync(userDataSpace, registryDatasets, usage) {
for (const dataset of registryDatasets) {
const adapter = {
listTableColumns: () => userDataSpace.listTableColumns(dataset.table),
};
const columns = await adapter.listTableColumns();
assertRegisteredDatasetTables({ listTableColumns: () => columns }, [dataset], usage);
}
}
/**
* Page Data policy must be derived from a registered SQLite dataset, never
* accepted solely from an Agent-supplied policy. This runs before page or
@@ -213,6 +223,27 @@ export function resolveRegisteredPageDataPolicy({
};
}
export async function resolveRegisteredPageDataPolicyAsync(options = {}) {
const { html, userId, accessMode, pageDataPolicy = null, userDataSpace } = options;
const usage = detectPageDataDatasetUsageFromHtml(html);
if (!usage.size) return null;
if (!userDataSpace) throw new Error('缺少 Page Data 数据空间');
if (pageDataPolicy?.datasets) assertPolicyMatchesHtmlDatasets(html, pageDataPolicy.datasets);
const registryDatasets = await userDataSpace.listDatasets();
const datasets = buildPageDataPolicyDatasetsFromRegistry({ html, registryDatasets, usage });
await assertRegisteredDatasetTablesAsync(
userDataSpace,
registryDatasets.filter((dataset) => datasets[dataset.name]),
usage,
);
return {
...pageDataPolicy,
ownerUserId: String(pageDataPolicy?.ownerUserId ?? userId).trim(),
accessMode: pageDataPolicy?.accessMode ?? accessMode,
datasets,
};
}
export async function bindWorkspaceHtmlForPageData({
pool,
h5Root,
@@ -236,8 +267,8 @@ export async function bindWorkspaceHtmlForPageData({
const normalizedAccessMode = resolvePageDataBindAccess(accessMode);
const resolvedPassword = resolvePageDataBindPassword(normalizedAccessMode, password);
const userDataSpace = createUserDataSpaceService({ workspaceRoot });
const resolvedPageDataPolicy = resolveRegisteredPageDataPolicy({
const userDataSpace = createUserDataSpaceService({ workspaceRoot, userId, query: pool });
const resolvedPageDataPolicy = await resolveRegisteredPageDataPolicyAsync({
html: content,
userId,
accessMode: normalizedAccessMode,