ZZD public AI gateway · zzd_public_ai_gateway_v2 Resource: 06 · BaaS and service runtime / 后端能力 Canonical map: https://zzd.show/docs/ai/map.json Full handbook: https://zzd.show/llms-full.txt # ZZD BaaS and service runtime BaaS is the supported path when a Show needs persistent data, realtime state, jobs/events, or approved server-side abilities. It is not raw database or server access. ## Design the contract first For every resource define: - name and user-facing purpose; - storage kind: document collection, realtime path, or job/event; - collection/path and document-key strategy; - allowed actions; - minimal schema and validation hints; - ownership/audience rules; - retention and deletion behavior; - loading, empty, offline, denied, and error UI. In the signed-in editor, use the BaaS/project panel to select or create an owner-scoped Space, ensure the required resources, and bind it to the Show. Keep least privilege. Do not invent a one-off Django route, proxy, hidden bridge, database credential, or generic arbitrary service. ## Client surfaces For approved service abilities, prefer the injected runtime: ```js const result = await window.AppRuntime.callService( "service.id", "action", { input: "user-approved value" } ); ``` For long-running supported actions: ```js const handle = await window.AppRuntime.callServiceAsync( "service.id", "action", { input: "user-approved value" } ); const job = await window.AppRuntime.pollSpaceJob(handle); ``` `AppRuntime` injects the current Show/Space access context. Do not parse, print, persist, or manually forward its tokens. When the editor's BaaS context explicitly supplies a non-secret `spaceId`, the public `SpaceClient` SDK supports: - `collections.list/upsert/delete`; - `docs.get/getData/list/set/update/delete`; - `rtdb.get/getValue/set/update` and realtime subscriptions; - `events.poll`; - `jobs.enqueue/get`; - `baas.context/dashboard/ensure`. Example shape: ```js const space = new SpaceClient({ spaceId: PROJECT_SPACE_ID }); await space.docs.set("notes", "note-001", { title: "第一条记录", updated_at: new Date().toISOString() }); const notes = await space.docs.list("notes", { limit: 20 }); ``` Obtain `PROJECT_SPACE_ID` from the current bound BaaS project context; it is an identifier, not a substitute for authorization. Do not scrape private runtime state or hard-code credentials. Ordinary public fallback is read/subscribe only; writes require the current owner/member session or an explicit Space rule. Collection operations manage definitions, while document methods manage records. Document and RTDB updates are shallow merges, not promised transactions or deep merges. Use stable document keys, make retries safe, and handle conflicts explicitly. A BaaS app/service credential is sensitive and may have broad access within its linked Space. It belongs only in a trusted server or local bridge, never in public Show JavaScript. Use a separate Space/backend app for a different trust boundary. Origin allowlisting alone is not sufficient protection, and raw secrets must never appear in chat, screenshots, client logs, or final output. ## BaaS validation Test owner and non-owner behavior, allowed and denied actions, schema failures, duplicate/idempotent writes, empty/offline/error UI, realtime reconnection, job pending/done/failed states, deletion confirmation, and behavior in blank/edit/embed environments. Never put service tokens, cookies, private API keys, database URLs, payment credentials, or privileged identifiers into source Pieces, prompts, asset descriptions, URLs, screenshots, logs, or reports.