feat(mindspace): add SEO/GEO delivery, page template catalog, and admin hooks
Memind CI / Test, build, and release guards (push) Has been cancelled

Enable optional SEO/GEO injection and discovery routes for confirmed public pages while keeping private pages noindex. Add premium page template skills, portal catalog API, template shop UI, and Baidu push gated by memind_adm config.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-10 08:06:12 +08:00
parent 7c65540366
commit fde6503bdf
158 changed files with 9194 additions and 270 deletions
+76
View File
@@ -0,0 +1,76 @@
import { loadMindSpaceConfig } from './mindspace-config.mjs';
import { isPublicationIndexable } from './mindspace-index-policy.mjs';
import { createPlazaSeoService } from './plaza-seo.mjs';
import { resolvePublicBaseUrl } from './user-publish.mjs';
export function buildPublicationAbsoluteUrl(publicUrl, env = process.env) {
const raw = String(publicUrl ?? '').trim();
if (!raw) return null;
if (/^https?:\/\//i.test(raw)) return raw.split('#')[0];
const base = resolvePublicBaseUrl(env);
if (raw.startsWith('/')) return `${base}${raw}`.split('#')[0];
return `${base}/${raw.replace(/^\/+/, '')}`.split('#')[0];
}
export function resolveMindspaceBaiduSite(env = process.env) {
const explicit = String(env.MINDSPACE_BAIDU_SITE ?? '').trim();
if (explicit) return explicit;
try {
return new URL(resolvePublicBaseUrl(env)).hostname;
} catch {
return 'm.tkmind.cn';
}
}
export function createMindspaceSeoNotifyService(
pool,
{
env = process.env,
plazaSeoFactory = createPlazaSeoService,
loadMindSpaceConfigFn = loadMindSpaceConfig,
} = {},
) {
const pingBaidu = async (urls) => {
const seo = plazaSeoFactory(pool, {
siteBase: resolvePublicBaseUrl(env),
baiduToken: env.MINDSPACE_BAIDU_PUSH_TOKEN ?? env.PLAZA_BAIDU_PUSH_TOKEN ?? '',
baiduSite: resolveMindspaceBaiduSite(env),
});
return seo.pingBaidu(urls);
};
const notifyPublicationSearchEngines = async (publication) => {
const config = await loadMindSpaceConfigFn(pool, { env }).catch(() => null);
if (!config?.seoGeo?.enabled || !config.seoGeo.seo?.baiduPush) {
return { pushed: false, reason: 'disabled' };
}
if (!isPublicationIndexable(publication)) {
return { pushed: false, reason: 'not_indexable' };
}
const url = buildPublicationAbsoluteUrl(
publication?.publicUrl ?? publication?.public_url,
env,
);
if (!url) return { pushed: false, reason: 'missing_url' };
try {
return await pingBaidu([url]);
} catch (error) {
return { pushed: false, reason: error?.message || 'baidu_push_failed' };
}
};
return {
buildPublicationAbsoluteUrl: (publicUrl) => buildPublicationAbsoluteUrl(publicUrl, env),
notifyPublicationSearchEngines,
pingBaidu,
};
}
export async function notifyPublicationSearchEngines(
pool,
publication,
options = {},
) {
const service = createMindspaceSeoNotifyService(pool, options);
return service.notifyPublicationSearchEngines(publication);
}