To ensure the validity of the input before mutating the action table, you can use argument validation for your endpoints. Convex provides a way to add validation to your queries, mutations, and actions using the zod helpers from the convex-helpers npm package.
Here's an example of how you can use zod for validation:
import { defineMutation } from 'convex/server';
import { z } from 'zod';
const inputSchema = z.object({
title: z.string(),
description: z.string().optional(),
language: z.string(),
chapters: z.array(z.object({
chapterName: z.string(),
chapterIndex: z.string(),
chapterDescription: z.string().optional(),
sections: z.array(z.object({
sectionName: z.string(),
sectionIndex: z.string(),
sectionDescription: z.string().optional(),
})),
})),
});
export default defineMutation(inputSchema, async ({ db }, input) => {
});
In this example, inputSchema is a zod schema that matches the structure of your input. The defineMutation function takes this schema as its first argument, and it will automatically validate any input against this schema before running the mutation. If the input is invalid, the mutation will throw an error.
Validation should take place as soon as you receive the user input, before any processing or mutation happens. This way, you can catch any invalid input early and prevent it from causing issues down the line.
As for organizing your functions, it's generally a good idea to separate your validation logic from your business logic. This way, your business logic can assume that the input is valid, which can make it simpler and easier to reason about.