67 lines
4.4 KiB
JavaScript
67 lines
4.4 KiB
JavaScript
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
|
|
// The modules that deploy to the Convex backend on this profile, derived from the app's one
|
|
// module list (modules/index.ts) -- named exclusions, not a second list.
|
|
//
|
|
// Why a module is excluded: its callable procedure graph needs a Node-only runtime or a workflow
|
|
// that has not been composed here. These are explicit gaps, not inferred from the module
|
|
// importing a package which has unrelated Node-only exports. Auth is included: its procedure
|
|
// handlers use Web Crypto; the OIDC redirects and sealed session storage remain in the trusted
|
|
// Next BFF, which invokes Convex functions with server-only admin auth and a verified identity.
|
|
//
|
|
// Convex actions have no ctx.db, so the runtime cannot run an effect procedure that changes the
|
|
// app's own rows in an action. File upload and delete have explicit action→mutation compositions
|
|
// in files.ts; other effects remain omitted until they have an equivalent state-machine workflow.
|
|
export const CONVEX_EXCLUDED_MODULES = new Map([])
|
|
|
|
// The modules whose effect procedures are generated as Convex actions (convex/lib/effects.ts):
|
|
// each effect is one call to a platform service through the module's own port and owns no app
|
|
// row, so it needs no transaction -- except the account module's, whose rows are reached through
|
|
// its bound store, one transaction per resumable step. The kernel still resolves the tenant scope and checks the
|
|
// permission, against ctx.db in an internal query (convex/effectScope.ts), and the handler's
|
|
// nested reads and writes run as the generated queries and mutations they always are.
|
|
export const CONVEX_ACTION_EFFECT_MODULES = new Map()
|
|
CONVEX_ACTION_EFFECT_MODULES.set("guides", "Guides runtime calls through GUIDES_PLATFORM; no app rows") // kit:guides
|
|
CONVEX_ACTION_EFFECT_MODULES.set("support", "Support session/contact calls through SUPPORT_PLATFORM") // kit:support
|
|
// The account module's export and deletion compose every module's share (platform calls) and own the
|
|
// deletion ledger, which they reach through ACCOUNT_STORE: one internal query or mutation per step.
|
|
CONVEX_ACTION_EFFECT_MODULES.set("account", "account export/deletion; ledger steps through convex/account.ts")
|
|
|
|
export const CONVEX_EXCLUDED_PROCEDURES = new Map([
|
|
["branding.logo.set", "logo decoding and Blob writes require an audited action workflow"],
|
|
["branding.logo.clear", "logo record updates and concurrent Blob cleanup require an action workflow"],
|
|
["branding.logo.get", "logo bytes require an authorized Blob action workflow"],
|
|
["files.file.delete", "the BFF composes the object delete action with internal mutations"],
|
|
])
|
|
// The account page's platform analytics erasure and export (ADR-049) call the platform with the
|
|
// deployment token through ACCOUNT_PRIVACY, which only the web's composition root binds; no Convex
|
|
// action binds it yet, so on this profile the panel answers "unavailable".
|
|
for (const name of ["account.analytics.request", "account.analytics.status", "account.analytics.export"]) {
|
|
CONVEX_EXCLUDED_PROCEDURES.set(name, "ACCOUNT_PRIVACY is bound by the web's composition root only")
|
|
}
|
|
// kit:guides:begin -- a survey file's bytes are the streamed body of a PUT, which cannot be a Convex
|
|
// action's argument, and no BFF composition streams it to the platform on this profile yet.
|
|
CONVEX_EXCLUDED_PROCEDURES.set(
|
|
"guides.runtime.uploadFile",
|
|
"a streamed request body cannot be a Convex action argument",
|
|
)
|
|
// kit:guides:end
|
|
|
|
const modulesFor = (appModules, includeBffFileEffects) =>
|
|
appModules
|
|
.filter((module) => !CONVEX_EXCLUDED_MODULES.has(module.id))
|
|
.map((module) => ({
|
|
...module,
|
|
procedures: (module.procedures ?? []).filter((procedure) => {
|
|
const composedBffFileProcedure =
|
|
includeBffFileEffects && module.id === "files" && procedure.name.startsWith("files.file.")
|
|
const runnable = procedure.kind !== "effect" || CONVEX_ACTION_EFFECT_MODULES.has(module.id)
|
|
return composedBffFileProcedure || (runnable && !CONVEX_EXCLUDED_PROCEDURES.has(procedure.name))
|
|
}),
|
|
}))
|
|
|
|
// The backend generator and deployment registry omit procedures that are composed as actions by
|
|
// the BFF. The web HTTP registry keeps those file contracts so their routes still validate input,
|
|
// tenancy, permissions, rate limits and CSRF before the caller invokes the action workflow.
|
|
export const convexModules = (appModules) => modulesFor(appModules, false)
|
|
export const convexBffModules = (appModules) => modulesFor(appModules, true)
|