Files
skills/docs/api-stack/api/api-plugin-user/src/schema/schema.md
2026-05-29 08:20:56 +01:00

3.1 KiB

schema/schema

(no submodules)

Purpose

The schema module owns the SurrealQL DDL the user plugin ships — a small extension to Better-Auth's user table that adds optional profile columns operators configure via UserPluginOptions.profileFields. Every statement uses DEFINE FIELD OVERWRITE so re-applying the schema across plugin restarts is idempotent — the field definitions are replaced, existing rows are untouched.

Features

  • DEFAULT_USER_PROFILE_FIELDS — the canonical four-field set the plugin ships out of the box.
  • renderUserProfileSchema(fields) — pure function that returns the DDL string. Validates each field against the SurrealQL identifier grammar so the output cannot drift into a parser error.
  • USER_PROFILE_SCHEMA — the rendered DDL for the canonical default field set; the most common operator path.
  • applyUserProfileSchema({ profileFields, migrationRunner?, db? }) — chooses the migration runner when present (so the apply is recorded in the migration tracking table) and falls back to an inline db.execute. Failures wrap into UserError(USER_SCHEMA_APPLY_FAILED).

Usage: Basic

import {
    USER_PROFILE_SCHEMA,
    applyUserProfileSchema,
} from "@suaveplan/api-plugin-user/schema/schema";

await applyUserProfileSchema({
    profileFields: ["displayName", "avatarUrl", "locale", "timezone"],
    db: surrealAdapter,
});

Usage: Advanced

Operators who manage migrations externally render the DDL once and write it to disk for their own tooling to apply:

import { renderUserProfileSchema } from "@suaveplan/api-plugin-user/schema/schema";
import { writeFileSync } from "node:fs";

const ddl = renderUserProfileSchema(["displayName", "avatarUrl", "bio"]);
writeFileSync("migrations/0001_user_profile.surql", ddl);

The plugin's applySchemaOnInit: false flag disables the in-plugin apply step when the externally-applied schema is the source of truth.

API Reference

DEFAULT_USER_PROFILE_FIELDS: readonly string[]

Frozen list of the four default field names.

renderUserProfileSchema(profileFields): string

Returns the DDL string. Throws UserError(USER_INVALID_INPUT) when any field name fails the SurrealQL identifier grammar or the list is empty.

USER_PROFILE_SCHEMA: string

renderUserProfileSchema(DEFAULT_USER_PROFILE_FIELDS) — pre-rendered.

ApplyUserProfileSchemaOptions

{ profileFields, migrationRunner?, db? }.

applyUserProfileSchema(options): Promise<void>

Applies the DDL via the migration runner (preferred) or the adapter (fallback). Throws USER_SCHEMA_APPLY_FAILED on runtime failure, USER_SERVICE_NOT_AVAILABLE when neither transport is supplied.

Implementation Notes

  • The DEFINE FIELD OVERWRITE form is the SurrealDB idiomatic idempotent definition — DEFINE FIELD ... IF NOT EXISTS does not exist in SurrealDB 2.x.
  • The renderer is intentionally pure so operators can diff DDL across plugin upgrades by comparing strings.
  • The migration name (0001-user-profile-schema) lives in the migration-tracking table so re-applies become no-ops once the apply is recorded.