ShipNext

Auth Tables

Better Auth user, session, account, and verification tables.

Auth tables are driven by Better Auth. Schemas are defined for both SQLite and PostgreSQL:

src/core/db/schema/sqlite/auth.schema.ts
src/core/db/schema/pg/auth.schema.ts

The field meanings are the same across databases, though low-level column types differ.

Business boundary

These tables support:

  • Email/password login, email verification, password reset
  • Google and GitHub social login
  • Magic links
  • Server-side session reads
  • User role and avatar fields

Better Auth is configured in src/modules/auth/config.ts, and the route handler lives in app/api/auth/[...all]/route.ts.

Tables

TableMeaningMain writer
userApplication usersBetter Auth and profile update API
sessionLogin sessionsBetter Auth
accountLogin provider bindingsBetter Auth
verificationEmail verification, reset password, magic link tokensBetter Auth

user

FieldDescription
idUser ID
nameDisplay name
emailUnique email
emailVerifiedEmail verification status
imageAvatar URL or storage object key
roleProject extension, default user, admin uses admin
createdAt / updatedAtTimestamps

role is declared as an additional Better Auth field. Profile updates go through app/api/user/profile/route.ts and update name and image.

session

FieldDescription
userIdReferences user.id
tokenUnique session token
expiresAtExpiration
ipAddress / userAgentRequest source metadata
createdAt / updatedAtTimestamps

Read the current session with:

import { getSession } from "@/modules/auth/server";

API routes can use:

import { getUser, requireUser, requireAdmin } from "@/modules/auth/server";

account

FieldDescription
userIdReferences user.id
accountIdProvider account ID
providerIdProvider such as credential, google, github
accessToken / refreshTokenOAuth tokens
passwordEmail/password credential managed by Better Auth
scope / idTokenOAuth fields

Do not manipulate OAuth token fields from business modules.

verification

FieldDescription
identifierEmail or target identifier
valueToken value; magic links use hashed token
expiresAtExpiration
createdAt / updatedAtTimestamps

This powers email verification, password reset, and magic links.

Extend user fields

Update both schemas

src/core/db/schema/sqlite/auth.schema.ts
src/core/db/schema/pg/auth.schema.ts

Update Better Auth additionalFields

Declare the field in src/modules/auth/config.ts.

Update business read/write paths

Keep user profile logic centralized in user services and types.

Generate and run migrations

For local SQLite you can usually use:

pnpm db:push

Notes

  • user.email is unique and central to account identity.
  • Deleting a user cascades to session and account, but other business tables depend on their own foreign key rules.
  • Admin access depends on user.role, not only hidden UI.

On this page