This is a dense reference for LLMs working with Vextro’s admin module. It documents every argument to createVextroAdminModule, default behaviors, and the complete list of exported query and mutation functions.
createVextroAdminModule(args)
Factory function that creates the complete Vextro admin API for a Convex backend. Returns all queries and mutations needed to power the admin UI. The return value is a flat object of named Convex functions that you destructure and re-export from your convex/admin.ts file.
import { query, mutation } from "./_generated/server";
import { components } from "./_generated/api";
import { createVextroAdminModule } from "vextro/convex/admin";
const admin = createVextroAdminModule({
query,
mutation,
components,
geospatialComponent: components.geospatial, // Required if using f.point() with spatial indexing
collectionDefinitions,
});
export const { listCollections, getShellData, seedAdminMetadata, /* ... */ } = admin;
Arguments
Core (required)
| Property | Type | Required | Description |
|---|
query | QueryBuilder<DataModel, "public"> | Yes | Convex query builder from _generated/server. Used to create all read functions. |
mutation | MutationBuilder<DataModel, "public"> | Yes | Convex mutation builder from _generated/server. Used to create all write functions. |
components | VextroAdminComponentRefs<TableName> | Yes | Component references from _generated/api. Provides access to Vextro’s internal component functions. |
Definitions
| Property | Type | Required | Description |
|---|
collectionDefinitions | Array<CollectionDefinition<TableName>> | No | Collection definitions produced by buildAdminDefinitions(). When provided, Vextro computes a fingerprint for automatic metadata seeding. |
globalDefinitions | Array<GlobalDefinition> | No | Global definitions for singleton documents (e.g., site settings). |
isTableName | (name: string) => name is TableName | No | Type guard for runtime table name validation. Default: treats all strings as valid table names. |
Auth / Access
| Property | Type | Required | Description |
|---|
getCurrentUser | (ctx) => Promise<User | null> | No | Resolves the current authenticated user. Used for audit logging, presence, and user context. Default: looks up the users table via a by_tokenIdentifier index. Override if your user table or index differs. |
requireAdminRead | (ctx) => Promise<void> | No | Auth guard for all admin read operations (queries). Throw to deny access. Default: requires ctx.auth.getUserIdentity() to be non-null. |
requireAdminWrite | (ctx) => Promise<void> | No | Auth guard for all admin write operations (mutations). Throw to deny access. Default: same as requireAdminRead (checks for authenticated identity). |
getUserRoles | (ctx) => Promise<string[]> | No | Returns role slugs for the current user. Used for collection-level and field-level permission checks. When not provided, a default implementation queries the RBAC tables (userRoles join to roles). |
rbacFailOpen | boolean | No | Controls behavior when getUserRoles throws. false (default): re-throws the error, denying access (fail-closed). true: returns null, allowing access as if RBAC is not configured. Security warning: setting to true means role resolution errors silently bypass all collection-level RBAC. |
accessControl | AccessControlDefinitions | No | Code-defined roles, permissions, and default role-to-permission assignments. Automatically synced to the database when access control pages load. Definitions are additive — manual assignments in the admin UI are preserved. See the AccessControlDefinitions type below. |
requireAccessControlRead | (ctx) => Promise<void> | No | Separate auth guard for access control read operations (roles/permissions/users list pages). Falls back to requireAdminRead when not provided. |
requireAccessControlWrite | (ctx) => Promise<void> | No | Separate auth guard for access control write operations (role/user mutations). Falls back to requireAdminWrite when not provided. |
Scopes
| Property | Type | Required | Description |
|---|
getUserScopes | (ctx, scopeType: string) => Promise<string[] | null> | No | Returns scope IDs the current user can access for a given scope type. Return null to indicate unrestricted (admin-level) access. |
canAccessScope | (ctx, scopeType: string, scopeValue: string) => Promise<boolean> | No | Validates that a user can access a specific scope value. Used for write operations. |
listScopeOptions | (ctx, scopeType: string) => Promise<Array<{ id: string; label: string }>> | No | Returns scope options for the scope selector UI dropdown. |
Scheduling
| Property | Type | Required | Description |
|---|
scheduleCacheInvalidation | (ctx, args: CacheInvalidationArgs) => Promise<void> | No | Callback invoked after document changes to trigger cache invalidation. Typically schedules a ctx.scheduler.runAfter(0, ...) call to a cache invalidation action. |
scheduleWebhookDelivery | (ctx, args: WebhookDeliveryArgs) => Promise<void> | No | Callback to schedule webhook delivery as an action. The host app provides an action that performs the HTTP call. |
User Management
| Property | Type | Required | Description |
|---|
userProfileFields | string[] | No | Fields that users can update on their own profile via updateUserProfile. Default: ["displayName", "avatarUrl"]. |
onUserStatusChange | (ctx, { userId, previousStatus, newStatus }) => Promise<void> | No | Called when a user’s status changes (e.g., via updateUserStatus). Use to invalidate sessions when a user is deactivated, send notifications, or trigger other side effects. Vextro does not invalidate sessions automatically since session storage varies by auth provider. |
Other
| Property | Type | Required | Description |
|---|
blockDeletionStrategy | "preserve" | "delete-exclusive" | No | Strategy for handling blocks when a parent document is deleted. "preserve" (default): blocks remain, only usedIn entries are cleaned up. "delete-exclusive": blocks used only by the deleted document are also deleted. |
geospatialComponent | any | No | Component reference for @convex-dev/geospatial. Required when any collection has a point field with spatialIndex: true (default). Pass components.geospatial from _generated/api. See point field setup. |
richText | { toolbar?: RichTextToolbar } | No | Project-level rich text editor defaults. Merged with field-level config (field-level wins per key). |
getSampleDoc | (ctx, definition) => Promise<Record<string, Value> | undefined> | No | Returns a sample document for a collection. Default: reads the first document from the collection’s table via ctx.db.query(tableName).take(1). Override if you maintain a static sample map or want to skip the DB query. |
getCollectionDefinitions | (ctx) => Promise<Array<CollectionDefinition<string>>> | No | Dynamic collection definitions loader. Called from mutations to get the current definitions at runtime. |
AccessControlDefinitions
type AccessControlDefinitions = {
permissions: Array<{ slug: string; description?: string }>;
roles: Array<{
slug: string;
name: string;
description?: string;
permissions: string[]; // Permission slugs this role should have by default
}>;
tables?: {
permissions?: string; // Default: "permissions"
roles?: string; // Default: "roles"
rolePermissions?: string; // Default: "rolePermissions"
userRoles?: string; // Default: "userRoles"
users?: string; // Default: "users"
userScopes?: string; // Default: "userScopes"
};
};
Complete Production Example
// convex/admin.ts
import { query, mutation } from "./_generated/server";
import { api, components } from "./_generated/api";
import {
createVextroAdminModule,
buildAdminDefinitions,
} from "vextro/convex/admin";
import { posts, pages, media, categories } from "./collections";
import { siteSettings } from "./globals";
import { hero, cta, testimonial } from "./blocks";
const collectionDefinitions = buildAdminDefinitions({
collections: [posts, pages, media, categories],
blocks: [hero, cta, testimonial],
});
const admin = createVextroAdminModule({
// Core (required)
query,
mutation,
components,
// Definitions
collectionDefinitions,
globalDefinitions: [siteSettings],
// Auth guards
getCurrentUser: async (ctx) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) return null;
return await ctx.db
.query("users")
.withIndex("by_clerkId", (q) => q.eq("clerkId", identity.subject))
.unique();
},
requireAdminRead: async (ctx) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Not authenticated");
},
requireAdminWrite: async (ctx) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) throw new Error("Not authenticated");
// Additional role check for write operations
const user = await ctx.db
.query("users")
.withIndex("by_clerkId", (q) => q.eq("clerkId", identity.subject))
.unique();
if (!user || user.status === "inactive") {
throw new Error("Write access denied");
}
},
// RBAC
accessControl: {
permissions: [
{ slug: "cms:read", description: "View CMS content" },
{ slug: "cms:write", description: "Create and edit content" },
{ slug: "cms:admin", description: "Full CMS admin access" },
],
roles: [
{
slug: "admin",
name: "Administrator",
description: "Full system access",
permissions: ["cms:read", "cms:write", "cms:admin"],
},
{
slug: "editor",
name: "Editor",
description: "Content editing access",
permissions: ["cms:read", "cms:write"],
},
],
tables: {
roles: "roles",
permissions: "permissions",
userRoles: "userRoles",
rolePermissions: "rolePermissions",
users: "users",
userScopes: "userScopes",
},
},
// Scheduling
scheduleCacheInvalidation: async (ctx, args) => {
await ctx.scheduler.runAfter(0, api.admin.invalidateVextroCache, args);
},
// Block deletion
blockDeletionStrategy: "delete-exclusive",
// User management
userProfileFields: ["displayName", "avatarUrl", "bio"],
onUserStatusChange: async (ctx, { userId, previousStatus, newStatus }) => {
if (newStatus === "inactive") {
// App-specific session cleanup
}
},
});
export const {
listCollections,
getCollectionBySlug,
listGlobals,
getShellData,
isDefinitionsStale,
getGlobalBySlug,
listFieldsForCollection,
listFieldsForGlobal,
listRelationshipsForCollection,
listRelationshipOptions,
paginateRelationshipOptions,
getSchemaDiagnostics,
getDashboardData,
listDocumentsForCollection,
getCollectionPageData,
paginateDocuments,
getCollectionPageDataPaginated,
getDocumentEditPageData,
getGlobalEditPageData,
getUserListConfig,
getDocumentForCollection,
getGlobalDocument,
listVersionsForDocument,
getVersion,
listSavedViews,
getFileRecord,
listOrphanedFiles,
getBlockUsageDetails,
getExclusiveBlocksForDocument,
getOrphanBlockStats,
listOrphanedBlocks,
globalSearch,
listAuditLog,
getDocumentAuditLog,
listWebhooks,
getWebhook,
listWebhookDeliveries,
getDocumentPresence,
getCollectionPresence,
listNotifications,
getUnreadNotificationCount,
listTemplatesForCollection,
getTemplate,
listScopeOptions,
getUserScopeAccess,
getDocumentAncestors,
getDocumentTree,
listRoles,
getRoleBySlug,
getRoleById,
getUsersForRole,
listRolesWithCounts,
listPermissions,
getCollectionAccess,
me,
getUserById,
listUsers,
listUsersWithRoles,
getUserRolesForUser,
listUserScopes,
createCollection,
updateCollection,
seedAdminMetadata,
syncAccessControl,
setUserListConfig,
deleteUserListConfig,
createDocumentForCollection,
updateDocumentForCollection,
deleteDocumentForCollection,
duplicateDocumentForCollection,
updateGlobalDocument,
restoreFieldsFromVersion,
bulkUpdateStatus,
bulkDeleteDocuments,
bulkUpdateTags,
bulkCreateDocuments,
createSavedView,
updateSavedView,
deleteSavedView,
confirmFileUpload,
deleteFileUpload,
updateFileFocalAndCrop,
updateFileProcessingStatus,
deleteOrphanedFiles,
deleteOrphanedBlocks,
createWebhook,
updateWebhook,
deleteWebhook,
testWebhook,
replayWebhookDelivery,
presenceHeartbeat,
presenceFieldUpdate,
presenceClear,
presenceClearAll,
markNotificationAsRead,
markAllNotificationsAsRead,
deleteNotification,
createTemplate,
updateTemplate,
deleteTemplate,
createRole,
updateRole,
deleteRole,
addPermissionToRole,
removePermissionFromRole,
updateUserProfile,
updateUserStatus,
assignRoleToUser,
removeRoleFromUser,
assignUserScope,
removeUserScope,
} = admin;
Admin API Function Reference
The admin module returns 114 named Convex functions (61 queries + 53 mutations). These are defined in the canonical VEXTRO_ADMIN_FUNCTION_NAMES list in exports.ts.
Queries — Shell & Navigation
| Function | Description |
|---|
listCollections | List all collection definitions, optionally filtered by collectionType and archive status. Respects RBAC — only returns collections the current user can read. |
getCollectionBySlug | Get a single collection definition by its slug. |
listGlobals | List all global definitions, optionally including archived globals. |
getShellData | Get admin shell layout data from the active materialized metadata slot (adminMetadataCollectionView). Hot path uses slot routing only (no per-read fingerprint checks). |
isDefinitionsStale | Check if the stored metadata fingerprint matches the current definitions fingerprint. |
getDashboardData | Get dashboard summary data including document counts and recent activity. |
getSchemaDiagnostics | Get schema diagnostic data: field counts, archived fields, relationships, and fingerprint comparison. |
getMetadataMigrationPreflight | Run Phase 4 migration preflight checks (block graph cycle detection, depth threshold, canonical sharding byte guardrails, and block-count guardrails) before cutover. |
getMetadataMigrationPreflight returns a contract-shaped report that mirrors the sharding logic used during cutover:
| Field | Meaning |
|---|
estimatedEntityRows | Estimated count of canonical entity rows. |
estimatedRelationshipRows | Estimated relationship-view rows. |
estimatedBlockPickerRows | Estimated block-picker rows. |
totalBlockTypes | Total discovered block types across collections. |
maxObservedDepth | Deepest authored metadata depth seen before encoding. |
maxProjectedEditorRowDepth | Deepest projected editor-row depth after encoding. |
encodingAppliedCount | Number of deep metadata branches encoded into compact storage. |
topDepthEntities | Up to five collections or globals with the highest projected depth. |
depthHeadroom | Remaining margin against the MAX_EDITOR_FIELD_VIEW_DEPTH ceiling. |
projectedCanonicalPartitionBytesMax | Largest projected canonical shard size in bytes. |
projectedCanonicalTotalBytes | Combined projected canonical payload size in bytes. |
projectedCanonicalPartitionCount | Number of projected canonical shards. |
cycleErrors | Block graph cycle diagnostics collected during preflight. |
hardErrors | Blocking guardrail failures that stop activation. |
Current sharding thresholds:
EDITOR_FIELD_STORAGE_DEPTH_BUDGET = 10
EDITOR_FIELD_STORAGE_DEPTH_HARD_THRESHOLD = 14
EDITOR_FIELD_STORAGE_CERTIFIED_PERSISTED_DEPTH = 13
MAX_EDITOR_FIELD_VIEW_DEPTH = 16
PREVIEW_CANONICAL_PARTITION_HARD_THRESHOLD = 750_000
PREVIEW_CANONICAL_TOTAL_HARD_THRESHOLD = 2_500_000
Canonical block metadata is compacted to typeKeys references before it is measured, and expanded blocks.types definitions are only used to derive those keys.
Queries — Collections & Documents
| Function | Description |
|---|
listDocumentsForCollection | List all documents for a collection, optionally filtered by status and scope. |
getCollectionPageData | Get collection list page data: documents, fields, relationships, and collection metadata in a single query. |
paginateDocuments | Paginate documents for a collection with cursor-based pagination. |
getCollectionPageDataPaginated | Combined paginated collection page data: paginated documents plus fields and collection metadata. |
getDocumentEditPageData | Get all data needed for the document edit page: document, fields, relationships, versions, presence, and related documents. |
getDocumentForCollection | Get a single document by collection slug and document ID. Applies field-level afterRead hooks. |
getUserListConfig | Get user-specific list view configuration (column order, sort, filters) for a collection. |
Queries — Globals
| Function | Description |
|---|
getGlobalBySlug | Get a single global definition by its slug. |
getGlobalEditPageData | Get all data needed for the global edit page: document, fields, and global metadata. |
getGlobalDocument | Get the current document for a global by its slug. Applies field-level afterRead hooks. |
Queries — Fields & Relationships
| Function | Description |
|---|
listFieldsForCollection | List all fields for a collection by collection ID. Annotates fields with RBAC visibility for the current user. |
listFieldsForGlobal | List all fields for a global by global ID. Annotates fields with RBAC visibility for the current user. |
listRelationshipsForCollection | List all relationship definitions for a collection. |
listRelationshipOptions | Load options for a relationship field by querying the relationship target table using precomputed relationship metadata (adminMetadataRelationshipView) on editor hot paths. |
paginateRelationshipOptions | Paginate relationship options with cursor-based pagination. Uses relationship-view-driven targeting on hot paths and supports search/scope/sort. |
Queries — Versions
| Function | Description |
|---|
listVersionsForDocument | List all version snapshots for a document, ordered by creation time. |
getVersion | Get a single version snapshot by ID. |
Queries — Files & Uploads
| Function | Description |
|---|
getFileRecord | Get a file record by ID from the Vextro file registry. |
listOrphanedFiles | List file records that are no longer referenced by any document. |
Queries — Blocks
| Function | Description |
|---|
getBlockUsageDetails | Get detailed usage information for blocks: which documents reference each block and whether blocks are shared or exclusive. |
getExclusiveBlocksForDocument | Get blocks that are exclusively owned by a specific document (not shared with other documents). |
getOrphanBlockStats | Get statistics on orphaned blocks: counts by block type and total orphan count. |
listOrphanedBlocks | List block records that are no longer referenced by any document. |
Queries — Search
| Function | Description |
|---|
globalSearch | Search across all collections for documents matching a query string. Returns results grouped by collection. |
Queries — Audit Log
| Function | Description |
|---|
listAuditLog | List audit log entries with optional filtering by collection, action, or user. |
getDocumentAuditLog | Get audit log entries for a specific document. |
Queries — Webhooks
| Function | Description |
|---|
listWebhooks | List all configured webhook endpoints. |
getWebhook | Get a single webhook configuration by ID. |
listWebhookDeliveries | List delivery attempts for a webhook, including status codes, response bodies, and retry information. |
Queries — Presence
| Function | Description |
|---|
getDocumentPresence | Get real-time presence data for a document: which users are viewing or editing it, including field-level focus and dirty state. |
getCollectionPresence | Get presence data for all documents in a collection: which documents have active editors. |
Queries — Notifications
| Function | Description |
|---|
listNotifications | List notifications for the current user. |
getUnreadNotificationCount | Get the count of unread notifications for the current user. |
Queries — Templates
| Function | Description |
|---|
listTemplatesForCollection | List saved templates for a collection. |
getTemplate | Get a single template by ID. |
Queries — Scopes
| Function | Description |
|---|
listScopeOptions | List available scope options for the scope selector UI. Delegates to the listScopeOptions callback. |
getUserScopeAccess | Get the current user’s scope access for a scope type: which scope values they can access. |
listUserScopes | List all scope assignments for a specific user. |
Queries — Hierarchy
| Function | Description |
|---|
getDocumentAncestors | Get the ancestor chain for a document in a hierarchical collection (parent, grandparent, etc.). |
getDocumentTree | Get the full document tree for a hierarchical collection, structured as nested nodes. |
Queries — Access Control (Roles & Permissions)
| Function | Description |
|---|
listRoles | List all roles with their permission assignments. |
getRoleBySlug | Get a role by its slug, including assigned permissions. |
getRoleById | Get a role by its ID, including assigned permissions. |
getUsersForRole | List all users assigned to a specific role. |
listRolesWithCounts | List all roles with user count and permission count. |
listPermissions | List all permission definitions. |
getCollectionAccess | Returns RBAC access flags (canRead, canCreate, canUpdate, canDelete) for a specific collection and the current user’s roles. |
Queries — Saved Views
| Function | Description |
|---|
listSavedViews | List all saved views (filter + sort + column configs) for a collection. |
Queries — Users
| Function | Description |
|---|
me | Get the current authenticated user’s profile. |
getUserById | Get a user by their ID. |
listUsers | List all users with optional filtering and pagination. |
listUsersWithRoles | List all users with their assigned roles. |
getUserRolesForUser | Get all role assignments for a specific user. |
| Function | Description |
|---|
createCollection | Create a new collection metadata record in the admin tables. |
updateCollection | Update a collection metadata record. |
seedAdminMetadata | Run the staged metadata seed pipeline (lock -> materialize -> verify -> activate -> audit). Writes active/inactive slot materialized views and flips activeSlot only after verification passes. |
runMetadataMigrationCutover | Execute one-way migration cutover flow: preflight -> lock/canonical -> legacy summary snapshot -> materialize -> verify -> activate -> audit. Snapshot is observability-focused (counts + sync metadata), not a full row-level backup artifact. Returns the activated slot and snapshot summary. |
rollbackMetadataSlot | Roll back metadata atomically by flipping activeSlot back to the previous (or specified) slot when that slot has materialized view rows. |
syncAccessControl | Sync code-defined roles and permissions to the database. Additive: preserves manual assignments made in the admin UI. |
Mutations — Documents
| Function | Description |
|---|
createDocumentForCollection | Create a new document in a collection. Runs beforeValidate, beforeChange, field-level hooks, creates a version snapshot, logs audit entry, triggers webhooks, and syncs block usage. |
updateDocumentForCollection | Update an existing document. Runs full hook pipeline, creates version snapshot, handles status transitions, and triggers webhooks. |
deleteDocumentForCollection | Delete a document. Runs beforeDelete/afterDelete hooks, cleans up block references (per blockDeletionStrategy), logs audit entry, and triggers webhooks. |
duplicateDocumentForCollection | Duplicate a document including its blocks. Creates new block records for exclusive blocks and shares references for shared blocks. |
restoreFieldsFromVersion | Restore specific fields from a version snapshot to the current document. |
bulkUpdateStatus | Update the status of multiple documents in a single operation. |
bulkDeleteDocuments | Delete multiple documents in a single operation. Runs delete hooks for each. |
bulkUpdateTags | Add or remove tags from multiple documents in a single operation. |
bulkCreateDocuments | Create multiple documents in a single operation (used by import). |
Mutations — Globals
| Function | Description |
|---|
updateGlobalDocument | Create or update a global’s document. Runs global hooks, creates version snapshot, and logs audit entry. |
Mutations — User List Config
| Function | Description |
|---|
setUserListConfig | Save user-specific list view configuration for a collection (column order, sort, filters). |
deleteUserListConfig | Reset user-specific list view configuration to defaults. |
Mutations — Saved Views
| Function | Description |
|---|
createSavedView | Create a named saved view (filter + sort + column config) for a collection. |
updateSavedView | Update an existing saved view. |
deleteSavedView | Delete a saved view. |
Mutations — Files & Uploads
| Function | Description |
|---|
confirmFileUpload | Confirm a file upload and create the file record in the Vextro file registry. |
deleteFileUpload | Delete a file record and its associated storage entry. |
updateFileFocalAndCrop | Update the focal point and crop settings for an image file. |
updateFileProcessingStatus | Update the processing status of a file (e.g., after image variant generation). |
deleteOrphanedFiles | Batch delete orphaned file records and their storage entries. |
Mutations — Blocks
| Function | Description |
|---|
deleteOrphanedBlocks | Batch delete orphaned block records that are no longer referenced by any document. |
Mutations — Webhooks
| Function | Description |
|---|
createWebhook | Create a new webhook endpoint configuration. |
updateWebhook | Update an existing webhook configuration. |
deleteWebhook | Delete a webhook configuration. |
testWebhook | Send a test payload to a webhook endpoint. |
replayWebhookDelivery | Replay a failed webhook delivery attempt. |
Mutations — Presence
| Function | Description |
|---|
presenceHeartbeat | Update the current user’s presence heartbeat for a document, keeping their presence indicator active. |
presenceFieldUpdate | Updates field-level presence data (focused field and dirty fields) for the current user on a specific document. Used by the admin UI for real-time field-level presence indicators. |
presenceClear | Clear the current user’s presence from a specific document. |
presenceClearAll | Clear all presence records for the current user across all documents. |
Mutations — Notifications
| Function | Description |
|---|
markNotificationAsRead | Mark a single notification as read. |
markAllNotificationsAsRead | Mark all notifications for the current user as read. |
deleteNotification | Delete a notification. |
Mutations — Templates
| Function | Description |
|---|
createTemplate | Create a new document template for a collection. |
updateTemplate | Update an existing template. |
deleteTemplate | Delete a template. |
Mutations — Access Control (Roles & Permissions)
| Function | Description |
|---|
createRole | Create a new role. |
updateRole | Update a role’s name, slug, or description. |
deleteRole | Delete a role and all associated user-role and role-permission assignments. |
addPermissionToRole | Assign a permission to a role. |
removePermissionFromRole | Remove a permission from a role. |
Mutations — Users
| Function | Description |
|---|
updateUserProfile | Update the current user’s profile fields (limited to userProfileFields). |
updateUserStatus | Update a user’s status (e.g., active/inactive). Triggers the onUserStatusChange callback. |
assignRoleToUser | Assign a role to a user. |
removeRoleFromUser | Remove a role assignment from a user. |
Mutations — Scopes
| Function | Description |
|---|
assignUserScope | Grant a user access to a specific scope value. |
removeUserScope | Remove a user’s access to a specific scope value. |