Soloist.v2.0.0

File Structure

API Documentation

Complete reference for all Convex functions in Soloist application

User Management

Functions for managing user accounts, profiles, and authentication

viewer

query

Get the current authenticated user (viewer)

Parameters

No parameters

Returns

User | null

Example

const user = useQuery(api.users.viewer);

What This Does

This function checks who is currently logged into the app and returns their user information. If nobody is logged in, it returns null. It's commonly used to display user information in the UI or to check if someone is authenticated before showing certain features.

currentUser

query

Get the current authenticated user

Parameters

No parameters

Returns

User | null

Example

const user = useQuery(api.users.currentUser);

What This Does

Similar to the viewer function, this retrieves information about whoever is currently signed in. It's useful when you need to access the logged-in user's details like their name, email, or profile picture anywhere in your application.

getProfile

query

Get user profile information for the authenticated user

Parameters

No parameters

Returns

User

Example

const profile = useQuery(api.users.getProfile);

What This Does

This function fetches the complete profile information for the person who is currently logged in. Unlike viewer or currentUser, this will throw an error if no one is authenticated, making it suitable for protected pages where you know someone must be logged in.

getAllUsers

query

Get all users (admin function)

Parameters

No parameters

Returns

User[]

Example

const users = useQuery(api.users.getAllUsers);

What This Does

This retrieves a list of every user registered in the system. It's intended for administrative purposes, like viewing all users in an admin dashboard. In a production app, this should be restricted to admin users only with proper permission checks.

getUserByEmailPublic

query

Check if user exists by email (public query)

Parameters

NameTypeRequiredDescription
emailstringRequiredUser's email address

Returns

User | null

Example

const user = useQuery(api.users.getUserByEmailPublic, { email: "user@example.com" });

What This Does

This looks up a user by their email address and returns their public profile information if found. It's useful for checking whether someone has already signed up with a particular email or for finding users by email in features like invitations or mentions.

getUserSubscriptionStatus

query

Get user's subscription status

Parameters

No parameters

Returns

{ hasActiveSubscription: boolean, subscriptionType: string | null, subscription: Subscription }

Example

const status = useQuery(api.users.getUserSubscriptionStatus);

What This Does

This checks whether the current user has an active paid subscription. It returns detailed information about their subscription status, which is useful for determining whether to show premium features or prompt them to upgrade their plan.

getUser

query

Get user by ID (public function)

Parameters

NameTypeRequiredDescription
idstringRequiredUser ID

Returns

User | null

Example

const user = useQuery(api.users.getUser, { id: "user_123" });

What This Does

This retrieves a user's information using their unique ID. For security, it only allows users to access their own data - if you request someone else's ID, it returns null. This prevents users from viewing other people's private information.

exportUserData

query

Export all user data including profile, logs, attributes, and subscription

Parameters

No parameters

Returns

{ profile: User, dailyLogs: Log[], userAttributes: UserAttributes, subscription: Subscription, exportedAt: string, totalLogs: number }

Example

const data = useQuery(api.users.exportUserData);

What This Does

This gathers all of the current user's data from across the entire system - their profile, all their daily mood logs, custom attributes, and subscription info - and packages it into a single export. This is useful for GDPR compliance, allowing users to download all their data, or for creating backups.

upsertUser

mutation

Upsert user (public function)

Parameters

NameTypeRequiredDescription
namestringOptionalUser's name
emailstringOptionalUser's email
imagestringOptionalUser's profile image URL

Returns

Id<'users'>

Example

const userId = await upsertUser({ name: "John Doe", email: "john@example.com" });

What This Does

This updates the authenticated user's profile information with any new values you provide. You can update their name, email, or profile picture. It only modifies the fields you include in the request, leaving other fields unchanged.

updateUserProfile

mutation

Update user profile (public mutation for authenticated users)

Parameters

NameTypeRequiredDescription
namestringOptionalUser's name
phonestringOptionalUser's phone number
imagestringOptionalUser's profile image URL

Returns

User

Example

const updated = await updateUserProfile({ name: "Jane Doe" });

What This Does

This allows the current user to update their profile details like name, phone number, or profile picture. After making the changes, it returns the updated user object so you can see the new values. Only authenticated users can call this, and they can only update their own profile.

getUserByEmail

internalQuery

Get user by email (internal function)

Parameters

NameTypeRequiredDescription
emailstringRequiredUser's email address

Returns

User | null

What This Does

This is an internal function used by the backend to look up users by email. It's marked as internal so it can only be called by other Convex functions, not directly from the client. This helps protect sensitive operations like authentication and user lookups.

updateProfile

internalMutation

Update user profile

Parameters

NameTypeRequiredDescription
userIdId<'users'>RequiredUser ID
namestringOptionalUser's name
emailstringOptionalUser's email
imagestringOptionalUser's profile image URL
phonestringOptionalUser's phone number

Returns

void

What This Does

This internal function handles the core logic of updating a user's profile information. It's used by other backend functions and removes any undefined values before saving, ensuring only the fields you want to change actually get updated in the database.

deleteAccount

internalMutation

Delete user account and all associated data

Parameters

NameTypeRequiredDescription
userIdId<'users'>RequiredUser ID to delete

Returns

void

What This Does

This permanently removes a user's account and all their associated data from the system. It first deletes related records like subscriptions, then removes the user itself. This is a sensitive operation that's kept internal for security reasons.

completeUserDeletion

internalMutation

Completely delete a user and all associated data by email

Parameters

NameTypeRequiredDescription
emailstringRequiredUser's email address

Returns

DeletionSummary

What This Does

This is a comprehensive deletion function that removes a user and absolutely everything associated with them - subscriptions, payments, logs, forecasts, feed entries, and more. It returns a summary of what was deleted, which is useful for debugging and confirming the deletion was complete.

Daily Logs

Functions for creating, reading, and managing daily mood logs

listDailyLogs

query

Fetch all logs for a given user and year

Parameters

NameTypeRequiredDescription
userIdstringRequiredUser ID
yearstringRequiredYear in YYYY format (e.g., '2025')

Returns

Log[]

Example

const logs = useQuery(api.dailyLogs.listDailyLogs, { userId: "user_123", year: "2025" });

What This Does

This retrieves all mood logs for a specific user during a particular year. For example, if you want to see all of someone's entries from 2025, this will fetch every log from January 1st through December 31st. It's useful for yearly review features or visualizing long-term patterns.

getDailyLog

query

Fetch a single daily log for a given user and date

Parameters

NameTypeRequiredDescription
userIdstringRequiredUser ID
datestringRequiredDate in YYYY-MM-DD format

Returns

Log | null

Example

const log = useQuery(api.dailyLogs.getDailyLog, { userId: "user_123", date: "2025-01-15" });

What This Does

This fetches a single mood log entry for a specific date. If the user has logged their mood on that day, you'll get their entry back. If they haven't logged anything for that date yet, it returns null. This is perfect for showing today's log or checking if a particular day has been filled in.

getLogsByDateRange

query

Fetch all daily logs for a user between two ISO dates (inclusive)

Parameters

NameTypeRequiredDescription
userIdstringRequiredUser ID
startDatestringRequiredStart date in YYYY-MM-DD format
endDatestringRequiredEnd date in YYYY-MM-DD format

Returns

Log[]

Example

const logs = useQuery(api.dailyLogs.getLogsByDateRange, { userId: "user_123", startDate: "2025-01-01", endDate: "2025-01-31" });

What This Does

This gets all logs between two dates, including both the start and end dates. For example, you could fetch all logs from the past week, month, or any custom date range. It's great for showing trends over specific time periods or creating custom reports.

getLogCount

query

Get the total number of logs for a user

Parameters

NameTypeRequiredDescription
userIdstringRequiredUser ID

Returns

number

Example

const count = useQuery(api.dailyLogs.getLogCount, { userId: "user_123" });

What This Does

This simply counts how many total log entries a user has created. It's useful for displaying statistics like 'You've logged your mood 45 times!' or tracking user engagement over time.

listScores

query

List all dates and scores for a user

Parameters

NameTypeRequiredDescription
userIdstringRequiredUser ID

Returns

Array<{ date: string, score: number | null }>

Example

const scores = useQuery(api.dailyLogs.listScores, { userId: "user_123" });

What This Does

This returns a simplified list of just the dates and mood scores for all of a user's logs, leaving out the detailed answers and other information. It's perfect for creating charts and graphs of mood over time without loading unnecessary data.

listAllUserLogs

query

Debugging helper: Show all logs for a user

Parameters

NameTypeRequiredDescription
userIdstringRequiredUser ID

Returns

Log[]

Example

const logs = useQuery(api.dailyLogs.listAllUserLogs, { userId: "user_123" });

What This Does

This is a debugging tool that fetches every single log for a user with all details formatted in a readable way. It includes timestamps and converts them to human-readable dates. Use this when troubleshooting issues or inspecting the raw data structure.

getLogById

query

Debugging helper: Get log details by ID

Parameters

NameTypeRequiredDescription
logIdstringRequiredLog document ID

Returns

Log | null

Example

const log = useQuery(api.dailyLogs.getLogById, { logId: "log_abc123" });

What This Does

This debugging function looks up a specific log using its unique database ID rather than by date and user. It's useful when you're investigating a particular log entry and have its ID, or when building admin tools that need to reference specific records.

dailyLog

mutation

Upserts a daily log record. If a log with (userId, date) already exists, patch it; otherwise insert a new record

Parameters

NameTypeRequiredDescription
userIdstringRequiredUser ID
datestringRequiredDate in YYYY-MM-DD format
answersanyRequiredLog answers data
scorenumberOptionalEmotion score (0-100)

Returns

Log

Example

const log = await dailyLog({ userId: "user_123", date: "2025-01-15", answers: {...}, score: 85 });

What This Does

This saves or updates a daily mood log. If the user already logged their mood for this date, it updates that existing entry. If not, it creates a new one. This smart behavior means users can always safely save their mood without worrying about creating duplicates.

Forecast & AI

AI-powered forecasting and mood prediction functions

testDatabaseConnection

query

Test database connection

Parameters

No parameters

Returns

{ success: boolean, message: string }

Example

const test = useQuery(api.forecast.testDatabaseConnection);

What This Does

This is a simple health check function that confirms the database is working properly. It returns a success message if everything is connected correctly. Useful for debugging or monitoring the system's health.

getLogsForUser

query

Get recent logs for a user up to a specific end date

Parameters

NameTypeRequiredDescription
userIdId<'users'>RequiredUser ID
endDatestringRequiredEnd date in YYYY-MM-DD format

Returns

Log[]

Example

const logs = useQuery(api.forecast.getLogsForUser, { userId: userId, endDate: "2025-01-31" });

What This Does

This retrieves all logs up to a specific date, ordered with the most recent first. It's particularly useful for the forecasting system, which needs to analyze recent mood patterns to predict future moods.

getLogsForUserInRange

query

Get logs for a user in a date range (inclusive)

Parameters

NameTypeRequiredDescription
userIdId<'users'>RequiredUser ID
startDatestringRequiredStart date in YYYY-MM-DD format
endDatestringRequiredEnd date in YYYY-MM-DD format

Returns

Log[]

Example

const logs = useQuery(api.forecast.getLogsForUserInRange, { userId, startDate: "2025-01-01", endDate: "2025-01-31" });

What This Does

Similar to the dailyLogs version, but this one normalizes the dates to ensure they're in a consistent format (removing any time components). This is specifically designed for the forecast system which requires clean date formatting.

getSevenDayForecast

query

Get the 7-day forecast data (3 days before today, today, 3 days after today)

Parameters

NameTypeRequiredDescription
userIdId<'users'>RequiredUser ID
startDatestringOptionalOptional start date override
endDatestringOptionalOptional end date override
todaystringOptionalOptional today date override

Returns

ForecastDay[]

Example

const forecast = useQuery(api.forecast.getSevenDayForecast, { userId });

What This Does

This creates a 7-day view: your past 3 days (with actual mood data), today, and the next 3 days (with AI-predicted moods). It's like a weather forecast but for your emotional state. If forecasts haven't been generated yet, it shows placeholder text prompting you to generate them.

getForecastFeedback

query

Get feedback for forecast dates

Parameters

NameTypeRequiredDescription
userIdId<'users'>RequiredUser ID
forecastDatesstring[]RequiredArray of forecast dates

Returns

Record<string, 'up' | 'down'>

Example

const feedback = useQuery(api.forecast.getForecastFeedback, { userId, forecastDates: ["2025-01-16", "2025-01-17"] });

What This Does

This retrieves thumbs up/down feedback that users have given on forecast predictions. When users rate whether a forecast was accurate, this function lets you see those ratings. It's useful for displaying feedback indicators and for training the AI to improve predictions.

generateForecast

action

Generate forecast for a user based on historical logs

Parameters

NameTypeRequiredDescription
userIdId<'users'>RequiredUser ID
startDatestringOptionalStart date for log range
endDatestringOptionalEnd date for log range

Returns

{ success: boolean, error?: string, forecastDates?: string[] }

Example

const result = await generateForecast({ userId });

What This Does

This is the core forecasting action. It analyzes your recent mood logs (default is the last 4 days) and uses AI to predict your mood for the next 3 days. It checks that you have logs for all required days, sends the data to the AI, and saves the predictions. Returns success or an error message if something goes wrong (like missing log data).

generateRetrospectiveForecastAnalysis

action

Generate retrospective forecasts for historical analysis

Parameters

NameTypeRequiredDescription
userIdId<'users'>RequiredUser ID
startDatestringOptionalStart date for analysis
endDatestringOptionalEnd date for analysis

Returns

{ success: boolean, error?: string, analysis?: AnalysisResult }

Example

const analysis = await generateRetrospectiveForecastAnalysis({ userId });

What This Does

This is a testing tool that validates forecast accuracy. It goes back through your historical logs, pretends each day is 'today', generates a forecast for the next day, then compares that prediction to what actually happened. It creates an accuracy report showing how well the AI predictions match reality, helping improve the forecasting system.

submitForecastFeedback

mutation

Submit feedback for a forecast (thumbs up/down)

Parameters

NameTypeRequiredDescription
userIdId<'users'>RequiredUser ID
forecastDatestringRequiredForecast date
feedback'up' | 'down'RequiredFeedback type

Returns

{ updated?: boolean, created?: boolean }

Example

const result = await submitForecastFeedback({ userId, forecastDate: "2025-01-16", feedback: "up" });

What This Does

This lets users rate whether a forecast was accurate with a thumbs up (good prediction) or thumbs down (inaccurate). If they've already rated that date, it updates their rating. If not, it creates a new rating. This feedback helps track forecast accuracy over time.

Templates

Functions for managing custom log templates

getUserTemplates

query

Get all templates for a user

Parameters

NameTypeRequiredDescription
userIdstringRequiredUser ID

Returns

Template[]

Example

const templates = useQuery(api.templates.getUserTemplates, { userId: "user_123" });

What This Does

This retrieves all custom log templates that a user has created. Templates let users define their own questions for mood logging (like 'Did I exercise?' or 'How much did I sleep?'). This function returns them ordered by most recent first.

getTemplateById

query

Get a specific template by ID

Parameters

NameTypeRequiredDescription
templateIdId<'templates'>RequiredTemplate document ID

Returns

Template | null

Example

const template = useQuery(api.templates.getTemplateById, { templateId });

What This Does

This fetches a single template using its unique ID. Useful when you want to load a specific template to edit it or use it for logging. Returns null if the template doesn't exist or was deleted.

saveTemplate

mutation

Save a new template or update existing one

Parameters

NameTypeRequiredDescription
namestringRequiredTemplate name
userIdstringRequiredUser ID
questionsCustomQuestion[]RequiredArray of custom questions

Returns

Id<'templates'>

Example

const id = await saveTemplate({ name: "Morning Routine", userId, questions: [...] });

What This Does

This saves a custom template with its questions. If a template with the same name already exists for this user, it updates that one instead of creating a duplicate. This smart behavior means users can modify their templates without losing the original ID or creating clutter.

deleteTemplate

mutation

Delete a template

Parameters

NameTypeRequiredDescription
templateIdId<'templates'>RequiredTemplate document ID
userIdstringRequiredUser ID (for permission check)

Returns

boolean

Example

await deleteTemplate({ templateId, userId });

What This Does

This permanently removes a template. It includes a security check to ensure users can only delete their own templates, not someone else's. This prevents unauthorized deletions and keeps user data private.

Payments

Stripe payment processing and payment record management

getUserPayments

query

Get all payments for the authenticated user

Parameters

No parameters

Returns

Payment[]

Example

const payments = useQuery(api.payments.getUserPayments);

What This Does

This retrieves the complete payment history for the current user, ordered from newest to oldest. It shows all their transactions, including successful payments, pending ones, and any failed attempts. Useful for displaying a billing history page.

getPaymentById

query

Get payment details by ID

Parameters

NameTypeRequiredDescription
paymentIdId<'payments'>RequiredPayment document ID

Returns

Payment | null

Example

const payment = useQuery(api.payments.getPaymentById, { paymentId });

What This Does

This fetches detailed information about a specific payment. It includes a security check - users can only view their own payment records, not someone else's. If you try to access another user's payment, it returns null.

createCheckoutSession

action

Create a Stripe checkout session for the authenticated user

Parameters

NameTypeRequiredDescription
priceIdstringRequiredStripe price ID
paymentModestringOptionalPayment mode ('subscription' or 'payment')
embeddedCheckoutbooleanOptionalWhether to use embedded checkout

Returns

{ clientSecret: string, sessionId: string }

Example

const session = await createCheckoutSession({ priceId: "price_123" });

What This Does

This creates a Stripe checkout session, which is like opening a secure payment window. It initializes the payment process, creates a pending payment record, and returns credentials needed to display the Stripe payment form. The user completes payment in Stripe's secure interface.

getBySessionId

internalQuery

Get payment by Stripe session ID

Parameters

NameTypeRequiredDescription
sessionIdstringRequiredStripe session ID

Returns

Payment | null

What This Does

This internal function looks up a payment record using Stripe's session ID. It's used by webhook handlers to find and update the correct payment when Stripe sends notifications about payment status changes.

create

internalMutation

Create a new payment record

Parameters

NameTypeRequiredDescription
userIdId<'users'>RequiredUser ID
stripeSessionIdstringRequiredStripe session ID
priceIdstringRequiredStripe price ID
statusstringRequiredPayment status
productNamestringRequiredProduct name
paymentModestringRequiredPayment mode
createdAtnumberRequiredCreation timestamp

Returns

Id<'payments'>

What This Does

This internal function creates the initial payment record when a checkout session starts. It stores all the essential details about the payment attempt, including what's being purchased and who's purchasing it. The status typically starts as 'pending' until the payment completes.

recordStripePayment

internalMutation

Record a payment from Stripe webhook

Parameters

NameTypeRequiredDescription
stripeSessionIdstringRequiredStripe session ID
userIdOrEmailstringRequiredUser ID or email
priceIdstringOptionalStripe price ID
productNamestringRequiredProduct name
paymentModestringRequiredPayment mode
amountnumberRequiredPayment amount
currencystringRequiredCurrency code
customerIdstringOptionalStripe customer ID
customerEmailstringOptionalCustomer email
subscriptionIdstringOptionalStripe subscription ID
subscriptionStatusstringOptionalSubscription status

Returns

Id<'payments'>

What This Does

This is called by Stripe webhooks when a payment completes. It intelligently finds the user (trying multiple lookup methods), prevents duplicate records, and saves all the payment details. This ensures the database accurately reflects what happened in Stripe.

updatePaymentStatus

internalMutation

Update payment status after checkout completion

Parameters

NameTypeRequiredDescription
sessionIdstringRequiredStripe session ID
statusstringRequiredNew payment status
customerIdstringOptionalStripe customer ID
subscriptionIdstringOptionalStripe subscription ID

Returns

Id<'payments'>

What This Does

This updates an existing payment record after a checkout is completed. It finds the payment by session ID and updates its status (like changing from 'pending' to 'complete'), and can also store additional information like the customer ID or subscription ID that Stripe provides.

Subscriptions

User subscription management and status checking

hasActiveSubscription

query

Check if current user has an active subscription

Parameters

No parameters

Returns

boolean

Example

const isActive = useQuery(api.userSubscriptions.hasActiveSubscription);

What This Does

This is a simple yes/no check: does the current user have an active paid subscription? It checks both that the subscription status is 'active' or 'trialing' AND that it hasn't expired. Use this to control access to premium features or prompt users to upgrade.

getCurrentSubscription

query

Get current user's subscription details

Parameters

No parameters

Returns

Subscription | null

Example

const subscription = useQuery(api.userSubscriptions.getCurrentSubscription);

What This Does

This retrieves the full subscription record for the current user, including details like when it expires, what status it's in, and the Stripe subscription ID. Returns null if the user doesn't have a subscription. Useful for displaying detailed subscription information in account settings.

createOrUpdate

internalMutation

Create or update a user subscription

Parameters

NameTypeRequiredDescription
userIdstringRequiredAuth user ID
subscriptionIdstringRequiredStripe subscription ID
statusstringRequiredSubscription status
currentPeriodEndnumberOptionalCurrent period end timestamp

Returns

Id<'userSubscriptions'>

What This Does

This internal function handles creating new subscriptions or updating existing ones. It includes smart user lookup logic to handle different ID formats from authentication systems. If a subscription already exists for the user, it updates it; otherwise it creates a new one.

createOrUpdateFromStripe

internalMutation

Create or update a subscription from Stripe webhook data

Parameters

NameTypeRequiredDescription
userIdOrEmailstringRequiredUser ID or email
subscriptionIdstringRequiredStripe subscription ID
statusstringRequiredSubscription status
currentPeriodEndnumberOptionalCurrent period end timestamp
customerEmailstringOptionalCustomer email

Returns

Id<'userSubscriptions'>

What This Does

This is called by Stripe webhooks when subscription events occur (new subscription, renewal, cancellation, etc.). It has robust user lookup logic that tries multiple methods to find the right user, handles different authentication formats, and properly updates or creates subscription records to keep the database in sync with Stripe.

cancelByStripeId

internalMutation

Cancel a subscription by Stripe subscription ID

Parameters

NameTypeRequiredDescription
stripeSubscriptionIdstringRequiredStripe subscription ID
currentPeriodEndnumberOptionalCurrent period end timestamp

Returns

Id<'userSubscriptions'>

What This Does

This marks a subscription as canceled when Stripe notifies us of a cancellation. It finds the subscription by Stripe's ID and updates its status to 'canceled'. Often, canceled subscriptions remain active until the current billing period ends, which is tracked by the currentPeriodEnd timestamp.

updateSubscription

internalMutation

Update subscription from Stripe webhook

Parameters

NameTypeRequiredDescription
userIdstringRequiredUser ID
subscriptionIdstringRequiredStripe subscription ID
statusstringRequiredSubscription status
currentPeriodEndnumberRequiredCurrent period end timestamp
metadataobjectRequiredSubscription metadata

Returns

Id<'userSubscriptions'>

What This Does

Another webhook handler that processes subscription updates from Stripe. It's similar to createOrUpdateFromStripe but takes the user ID directly. This handles events like subscription renewals, plan changes, or status updates, keeping our database synchronized with Stripe's records.

getUserIdBySubscriptionId

internalQuery

Get a user ID by subscription ID

Parameters

NameTypeRequiredDescription
subscriptionIdstringRequiredStripe subscription ID

Returns

Id<'users'> | undefined

What This Does

This looks up which user owns a particular Stripe subscription. It's useful in webhook handlers when Stripe sends us an event about a subscription, and we need to figure out which user in our database it belongs to.

Waitlist

Feature waitlist management functions

isOnWaitlist

query

Check if current user is on waitlist for a specific feature

Parameters

NameTypeRequiredDescription
featurestringRequiredFeature name

Returns

boolean

Example

const onWaitlist = useQuery(api.waitlist.isOnWaitlist, { feature: "ai-coach" });

What This Does

This checks whether the current user has already joined the waitlist for a specific feature. It's useful for showing different UI - if they're already on the waitlist, show 'You're on the list!' instead of a 'Join Waitlist' button.

getWaitlistStats

query

Get waitlist stats for a specific feature

Parameters

NameTypeRequiredDescription
featurestringRequiredFeature name

Returns

{ totalCount: number, recentSignups: number }

Example

const stats = useQuery(api.waitlist.getWaitlistStats, { feature: "ai-coach" });

What This Does

This provides statistics about a feature's waitlist - how many total people have signed up, and how many joined in the last 7 days. Great for showing social proof ('Join 247 others waiting for this feature!') or tracking interest over time.

getAllWaitlistEntries

query

Get all waitlist entries (admin only)

Parameters

No parameters

Returns

WaitlistEntry[]

Example

const entries = useQuery(api.waitlist.getAllWaitlistEntries);

What This Does

This retrieves every waitlist entry across all features. It's protected - only users with admin role can access it. Use this in admin dashboards to see who's interested in what features and plan development priorities accordingly.

joinWaitlist

mutation

Join the waitlist for a specific feature

Parameters

NameTypeRequiredDescription
featurestringRequiredFeature name

Returns

{ success: boolean, message: string, waitlistId: Id<'waitlist'> }

Example

const result = await joinWaitlist({ feature: "ai-coach" });

What This Does

This adds the current user to the waitlist for a specific upcoming feature. It saves their user info (name and email) and when they signed up. It prevents duplicate entries - if you're already on that waitlist, it throws an error instead of adding you again.

leaveWaitlist

mutation

Remove user from waitlist

Parameters

NameTypeRequiredDescription
featurestringRequiredFeature name

Returns

{ success: boolean, message: string }

Example

await leaveWaitlist({ feature: "ai-coach" });

What This Does

This removes the current user from a feature's waitlist. Maybe they changed their mind or aren't interested anymore. If they're not actually on the waitlist, it throws an error. This gives users control over their waitlist signups.