Unstack Pro Docs

Database Schema

Understanding the Convex database schema and data models

Database Schema

The database schema is auto-generated by the Better Auth CLI. You don't need to manually define or modify auth tables.

We use better-convex for Better Auth integration. The auth schema lives in your main Convex database, not as a separate Convex Component. This means you can directly reference users, sessions, and organizations in your Convex functions without going through a component layer.

Direct Access

Since auth tables are in your main database, you can query them directly:

convex/users.ts
import { query } from "./_generated/server";
import { v } from "convex/values";

export const getUser = query({
  args: { userId: v.string() },
  handler: async (ctx, args) => {
    return await ctx.db
      .query("users")
      .filter((q) => q.eq(q.field("id"), args.userId))
      .first();
  },
});

Extending the Schema

When adding your own features, extend the schema alongside the auth tables:

convex/schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

// Import Better Auth schema
import { betterAuthSchema } from "./betterAuth/schema";

export default defineSchema({
  // Include Better Auth tables
  ...betterAuthSchema,

  // Add your own tables
  projects: defineTable({
    name: v.string(),
    description: v.optional(v.string()),
    ownerId: v.string(), // Reference to user.id
    organizationId: v.optional(v.string()),
    createdAt: v.number(),
  })
    .index("by_owner", ["ownerId"])
    .index("by_organization", ["organizationId"]),
});

Relationships

Reference auth data directly in your queries:

// Get project with owner details
export const getProjectWithOwner = query({
  args: { projectId: v.id("projects") },
  handler: async (ctx, args) => {
    const project = await ctx.db.get(args.projectId);
    if (!project) return null;

    const owner = await ctx.db
      .query("users")
      .filter((q) => q.eq(q.field("id"), project.ownerId))
      .first();

    return { ...project, owner };
  },
});

Resources

Next Steps

On this page