Skip to main content
The @packages/database package provides a fully-typed Convex database layer with schema definitions, organized functions (public/authenticated/private), and Better Auth integration.

Installation

npm install @packages/database

Overview

This package centralizes all database operations for Answer Overflow, including:
  • Schema definitions using Effect Schema and Convex
  • Function organization (public, authenticated, private)
  • Better Auth integration for authentication
  • Discord data models (servers, channels, messages, users)
  • Analytics and tracking with PostHog

Schema Structure

The database schema is defined in convex/schema.ts using Effect Schema:
import { defineSchema, defineTable } from "@packages/confect/server";
import { Schema } from "effect";

const ServerSchema = Schema.Struct({
  discordId: Schema.BigIntFromSelf,
  name: Schema.String,
  icon: Schema.optional(Schema.String),
  banner: Schema.optional(Schema.String),
  description: Schema.optional(Schema.String),
  approximateMemberCount: Schema.Number,
});

Core Tables

servers
table
Discord servers indexed by Answer Overflow
discordId
bigint
required
Discord server snowflake ID
name
string
required
Server name
icon
string
Server icon hash
approximateMemberCount
number
required
Approximate member count
serverPreferences
table
Server-specific preferences and settings
serverId
bigint
required
Associated Discord server ID
plan
enum
required
Subscription plan: FREE, STARTER, ADVANCED, PRO, ENTERPRISE, OPEN_SOURCE
stripeCustomerId
string
Stripe customer ID for billing
customDomain
string
Custom domain for the server’s docs
botNickname
string
Custom bot nickname
channels
table
Discord channels being indexed
id
bigint
required
Discord channel snowflake ID
serverId
bigint
required
Parent server ID
name
string
required
Channel name
type
number
required
Discord channel type
discordAccounts
table
Discord user accounts
id
bigint
required
Discord user snowflake ID
name
string
required
Username
avatar
string
Avatar hash
userServerSettings
table
User settings per server
serverId
bigint
required
Server ID
userId
bigint
required
Discord user ID
permissions
number
required
Permission bitfield from Discord
canPubliclyDisplayMessages
boolean
required
Whether messages can be displayed publicly
messageIndexingDisabled
boolean
required
Whether to disable message indexing

Function Organization

Convex functions are organized into three categories:

Public Functions

Located in convex/public/ - accessible without authentication:
// convex/public/messages.ts
import { query } from "../_generated/server";

export const getPublicMessages = query({
  handler: async (ctx, args) => {
    // Public message retrieval logic
  }
});
Available public functions:
  • messages.ts - Public message queries
  • channels.ts - Channel data
  • discord_accounts.ts - Public user profiles
  • search.ts - Search functionality

Authenticated Functions

Located in convex/authenticated/ - requires user authentication:
// convex/authenticated/dashboard.ts
import { authenticatedMutation } from "../auth";

export const updateServerSettings = authenticatedMutation({
  handler: async (ctx, args) => {
    const user = await ctx.auth.getUserIdentity();
    // Update logic
  }
});
Available authenticated functions:
  • dashboard.ts - Dashboard queries
  • dashboard_queries.ts - Dashboard data
  • dashboard_mutations.ts - Dashboard updates
  • onboarding.ts - Onboarding flow
  • stripe.ts - Stripe operations
  • github.ts - GitHub integration

Private Functions

Located in convex/private/ - internal functions only:
// convex/private/servers.ts
import { internalMutation } from "../_generated/server";

export const upsertServer = internalMutation({
  handler: async (ctx, args) => {
    // Server upsert logic
  }
});

Better Auth Integration

The package integrates Better Auth for authentication:
import { betterAuth } from "better-auth";
import { convexAdapter } from "@convex-dev/better-auth";

export const auth = betterAuth({
  database: convexAdapter(/* ... */),
  // Auth configuration
});

Auth Schema

Generated schema in convex/betterAuth/generatedSchema.ts includes:
  • User tables
  • Session management
  • OAuth providers
  • Account linking

Client Usage

Import and use the database client:
import { Database } from "@packages/database/database";
import { Effect } from "effect";

// Example: Query servers
const getServer = Effect.gen(function* () {
  const database = yield* Database;
  
  const server = yield* database.private.servers.getServerByDiscordId(
    { discordId: BigInt("123456789") },
    { subscribe: false }
  );
  
  return server;
});

Testing

The package includes comprehensive testing utilities:
import { describe, expect, it } from "@effect/vitest";
import { Effect } from "effect";
import { Database } from "@packages/database/database";
import { DatabaseTestLayer } from "@packages/database/database-test";

describe("Database tests", () => {
  it.scoped("should query data", () =>
    Effect.gen(function* () {
      const database = yield* Database;
      const result = yield* database.private.servers.upsertServer({
        discordId: BigInt(Date.now()),
        name: "Test Server",
        approximateMemberCount: 100,
      });
      expect(result).toBeDefined();
    }).pipe(Effect.provide(DatabaseTestLayer))
  );
});

Exports

./convex/*
module
Convex function exports (compiled JavaScript)
./convex/shared/*
module
Shared types and utilities
./*
module
Source TypeScript files

Scripts

# Deploy to Convex
bun run deploy

# Generate code from schema
bun run codegen

# Generate Better Auth schema
bun run generate:auth-schema

# Run tests
bun run test

# Development mode
bun run dev