ProjectR Docs
Backend (Convex)

API — content

Generated catalog of Convex functions in convex/content/. Regenerated by `bun run docs:api`.

Auto-generated from source. Do not edit by hand — run bun run docs:api.

query (7)

FunctionDescriptionArgs
getCampaignGet single campaign by ID (admin only){ id: v.id("marketingCampaigns"), }
getCampaignsGet all marketing campaigns (admin only - includes drafts){ publishedOnly: v.optional(v.boolean()), }
getCarouselItemGet single carousel item by ID (admin only){ id: v.id("carouselItems"), }
getCarouselItemsGet carousel items for dashboard (admin only). Optionally filter by placement and active status.{ includeInactive: v.optional(v.boolean()), placement: v.optional(v.string()), }
mobileGetCampaignGet published campaign by slug for mobile{ slug: v.string(), }
mobileGetCarouselItemsGet active carousel items for mobile homepage. Filters by placement (defaults to "home_hero" for backward compat).{ limit: v.optional(v.number()), placement: v.optional(v.string()), }
mobileGetCarouselItemsByPlacementGet active carousel items by placement (generic). Returns both home-style and loyalty-style fields. Supports tier filtering for loyalty placement.{ placement: v.string(), limit: v.optional(v.number()), userTierSlug: v.optional(v.string()), }

mutation (9)

FunctionDescriptionArgs
createCampaignCreate new marketing campaign Updated to match original schema with rich content support{ // Original field names (preferred) slug: v.optional(v.string()), title: v.optional(v.string()), subtitle: v.optional(v.string()), // Rich content (origina…
createCarouselItemCreate new carousel item Updated to support both original and legacy field names{ title: v.optional(v.string()), subtitle: v.optional(v.string()), imageUrl: v.string(), // Media type — defaults to "image" when omitted mediaType: v.option…
deleteCampaignDelete campaign{ id: v.id("marketingCampaigns"), }
deleteCarouselItemDelete carousel item{ id: v.id("carouselItems"), }
publishCampaignPublish campaign (set isActive to true){ id: v.id("marketingCampaigns"), }
reorderCarouselItemsReorder carousel items Takes array of { id, displayOrder } and updates all items{ updates: v.array( v.object({ id: v.id("carouselItems"), displayOrder: v.number(), }) ), }
unpublishCampaignUnpublish campaign (set isActive to false){ id: v.id("marketingCampaigns"), }
updateCampaignUpdate campaign (admin only){ const auth = await verifyAdminAccess(ctx); if (!auth) return { success: false, message: "Admin access required", campaign: null }; return applyCampaignUpda…
updateCarouselItemUpdate existing carousel item Updated to support both original and legacy field names{ id: v.id("carouselItems"), title: v.optional(v.string()), subtitle: v.optional(v.string()), imageUrl: v.optional(v.string()), // Media type — defaults to "…

internalQuery (1)

FunctionDescriptionArgs
getActiveCarouselItemsGet active carousel items (internal - no auth check){ limit: v.optional(v.number()), }

internalMutation (4)

FunctionDescriptionArgs
internalCreateCampaignCreate campaign (internal - no auth check){ // Required fields (original schema) slug: v.string(), title: v.string(), isPublished: v.optional(v.boolean()), // Optional new fields subtitle: v.optional…
internalCreateCarouselItemCreate carousel item (internal - no auth check){ title: v.optional(v.string()), subtitle: v.optional(v.string()), imageUrl: v.string(), mediaType: v.optional(v.union( v.literal("image"), v.literal("video"…
internalUpdateCampaignUpdate campaign (internal - no auth check). Same patch semantics as updateCampaign; used from the CLI where no dashboard session exists.{ args: { id: v.id("marketingCampaigns"), }, returns: v.object({ success: v.boolean(), message: v.string(), }), handler: async (ctx, { id }) => { const auth …
internalUpdateCarouselItemUpdate carousel item (internal - no auth check){ id: v.id("carouselItems"), title: v.optional(v.string()), subtitle: v.optional(v.string()), imageUrl: v.optional(v.string()), mediaType: v.optional(v.union…

On this page