StarterApp Docs
Database

Convex Data Model

How StarterApp organises Convex tables, builders, and generated types.

StarterApp uses Convex for data storage and real-time sync. Schema definitions live in convex/schema.ts and are surfaced through typed helpers in convex/tables.ts.

Tables and Validators

convex/tables.ts exports:

  • T.* table name constants (e.g. T.user, T.orgMeta, T.rateLimits)
  • V.* validator helpers for IDs (e.g. V.userId, V.orgMetaId)
  • Type aliases (UserId, OrgMetaId, etc.)

Avoid hard-coding table strings or Id<"table"> in your code—import from ./tables instead:

import { T, V, type UserId } from "./tables";

export const getOrgMeta = query({
  args: { metaId: V.orgMetaId },
  handler: async (ctx, { metaId }) => {
    const record = await ctx.db.get(metaId);
    return record;
  },
});

Builders

Custom builders in convex/_helpers/builders.ts inject authentication, Autumn helpers, and user-scoped database proxies. Use userQuery, userMutation, or userAction instead of the raw query/mutation/action APIs for user-facing operations.

import { userMutation } from "./_helpers/builders";

export const updateProfile = userMutation({
  args: { name: v.string() },
  handler: async (ctx, { name }) => {
    await ctx.db.patch(ctx.viewerId as UserId, {
      name,
      updatedAt: Date.now(),
    });
  },
});

Codegen

After editing schema.ts, run pnpm codegen to regenerate _generated/*. These files are committed to the repository so CI and AI agents have the latest types.