Extract memind_adm admin server, add local dev tooling, and remove image-generation.

Split platform admin and ops APIs into standalone admin-server.mjs with network guards; simplify billing to RMB token pricing, refactor user auth, and add rsync deploy plus local-test scripts and docs.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Your Name
2026-06-17 16:39:39 -07:00
parent ab0718938e
commit b0f5d6a51c
98 changed files with 5394 additions and 3010 deletions
+4 -51
View File
@@ -451,30 +451,6 @@ export function isModernFeedThumbnail(svg) {
return /width="540" height="720"/.test(svg) && /filter id="grain"/.test(svg);
}
export function thumbnailHasEmbeddedPhoto(svg) {
return /href="data:image\//.test(String(svg ?? ''));
}
export function resolveWorkspaceHtmlContentBaseDir(workspacePublishDir, workspaceHtmlRelativePath) {
if (!workspacePublishDir || !workspaceHtmlRelativePath) return undefined;
const dir = path.posix.dirname(String(workspaceHtmlRelativePath).replace(/^\/+/, ''));
return dir === '.' ? workspacePublishDir : path.join(workspacePublishDir, dir);
}
async function shouldRegenerateThumbnailForCover(storageRoot, html, meta, existing) {
if (!existing || !isModernFeedThumbnail(existing) || meta.force) return Boolean(meta.force);
const signals = extractCoverSignals(html, meta);
if (!signals.image) return false;
if (thumbnailHasEmbeddedPhoto(existing)) return false;
const coverDataUri = await resolveCoverDataUri({
storageRoot,
contentStorageKey: meta.contentStorageKey,
contentBaseDir: meta.contentBaseDir,
imageUrl: signals.image,
});
return Boolean(coverDataUri);
}
export async function generateHtmlThumbnail(storageRoot, storageKey, html, meta = {}) {
const signals = extractCoverSignals(html, meta);
const coverDataUri = await resolveCoverDataUri({
@@ -491,13 +467,7 @@ export async function generateHtmlThumbnail(storageRoot, storageKey, html, meta
export async function ensureHtmlThumbnail(storageRoot, storageKey, html, meta = {}) {
const existing = await readThumbnailIfExists(storageRoot, storageKey);
if (existing && isModernFeedThumbnail(existing) && !meta.force) {
const needsCoverRefresh = await shouldRegenerateThumbnailForCover(
storageRoot,
html,
meta,
existing,
);
if (!needsCoverRefresh) return existing;
return existing;
}
return generateHtmlThumbnail(storageRoot, storageKey, html, meta);
}
@@ -510,34 +480,17 @@ export async function ensurePageThumbnail({
workspacePublishDir = null,
workspaceHtmlRelativePath = null,
}) {
const contentBaseDir =
meta.contentBaseDir ??
resolveWorkspaceHtmlContentBaseDir(workspacePublishDir, workspaceHtmlRelativePath);
const enrichedMeta = contentBaseDir ? { ...meta, contentBaseDir } : meta;
if (workspacePublishDir && workspaceHtmlRelativePath) {
const sidecar = await readThumbnailIfExists(
workspacePublishDir,
workspaceThumbnailRelativePath(workspaceHtmlRelativePath),
);
if (sidecar && isModernFeedThumbnail(sidecar)) {
if (thumbnailHasEmbeddedPhoto(sidecar)) {
await writeThumbnail(storageRoot, pageThumbnailStorageKey, sidecar);
return sidecar;
}
const needsCoverRefresh = await shouldRegenerateThumbnailForCover(
workspacePublishDir,
html,
enrichedMeta,
sidecar,
);
if (!needsCoverRefresh) {
await writeThumbnail(storageRoot, pageThumbnailStorageKey, sidecar);
return sidecar;
}
await writeThumbnail(storageRoot, pageThumbnailStorageKey, sidecar);
return sidecar;
}
}
return ensureHtmlThumbnail(storageRoot, pageThumbnailStorageKey, html, enrichedMeta);
return ensureHtmlThumbnail(storageRoot, pageThumbnailStorageKey, html, meta);
}
export async function readThumbnailIfExists(storageRoot, storageKey) {