feat(billing): enforce image generation quota with admin API and user display
Memind CI / Test, build, and release guards (push) Failing after 3s

Add period_images_bonus and ledger tracking, gate image_make on remaining quota,
expose admin image-quota routes, show remaining image quota in the balance popover,
and document that admin UI must live in memind_adm (5174) not ops.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-03 14:58:38 +08:00
parent 36d8e74784
commit 946d8756c8
14 changed files with 639 additions and 23 deletions
+11 -2
View File
@@ -12,7 +12,11 @@
// The same factory functions imported here are the ones server.mjs uses, so the
// domain logic has a single source of truth; only the wiring differs.
import path from 'node:path';
import { createSubscriptionService } from './billing-subscription.mjs';
import {
createPlanCatalogService,
createSubscriptionService,
ensurePlanCatalogSchema,
} from './billing-subscription.mjs';
import { createDbPool, ensureAssetGatewaySchema, isDatabaseConfigured } from './db.mjs';
import { createUserAuth } from './user-auth.mjs';
import { createLlmProviderService } from './llm-providers.mjs';
@@ -69,6 +73,7 @@ export async function createAdminServices(env = {}) {
// The back-office process can boot before the public Portal. Create only the
// optional control-plane tables here instead of requiring the public boot path.
await ensureAssetGatewaySchema(pool);
await ensurePlanCatalogSchema(pool);
// --- plaza graph (review queue, reports, featured, analytics, creators) ---
const plazaRedis = createNoopPlazaRedis();
@@ -96,7 +101,11 @@ export async function createAdminServices(env = {}) {
});
// --- platform super-admin services ---
const subscriptionService = createSubscriptionService(pool);
const planCatalogService = createPlanCatalogService(pool);
const subscriptionService = createSubscriptionService(pool, {
getPlanAsync: (planType) => planCatalogService.getPlan(planType),
});
subscriptionService._planCatalogService = planCatalogService;
const userAuth = createUserAuth(pool, {
usersRoot,
h5Root,