# Extend @suaveplan/better-auth-surrealdb with Better-Auth v1.6 DBAdapterInstance factory **Package**: `@suaveplan/better-auth-surrealdb` **Status**: PROPOSED **Type**: feature (additive — preserves shipped v1.4-shape adapter) - **Spec delta**: ./specs/better-auth-surrealdb/spec.md ## Why `@suaveplan/better-auth-surrealdb` (shipped commit 2ed843a5, ~hours ago) exports `createBetterAuthSurrealAdapter` returning a 10-method `Adapter` matching Better-Auth v1.4's contract. The installed `better-auth` (catalog `^1.4.0` resolves to **1.6.11**) expects `BetterAuthOptions.database: DBAdapterInstance = (options: BetterAuthOptions) => DBAdapter` — a factory returning a Kysely-flavored adapter with many more methods (`transaction`, `createSchema`, `getDefaultIdField`, etc.). The shapes are structurally incompatible, so `createBetterAuth({ database: createBetterAuthSurrealAdapter(...) })` fails to type-check AND fails at runtime when Better-Auth invokes the missing methods. Fix: add a v1.6-compatible factory export `betterAuthSurrealAdapter(opts)` that returns a `DBAdapterInstance`. Internally it builds the same 10-method underlying adapter we already ship and wraps it via `createAdapterFactory` from `@better-auth/core/db` — the official escape hatch Better-Auth provides for custom adapters. The existing `createBetterAuthSurrealAdapter` export stays unchanged (still useful for direct conformance harness usage and for hypothetical v1.4 callers). ## What changes Additive — no breaking changes to the existing surface. ADDED: - `betterAuthSurrealAdapter(options): DBAdapterInstance` — the v1.6 factory. Exported from root barrel + new subpath `./adapter/v1.6`. Signature mirrors Better-Auth's `DBAdapterInstance` type: takes the parsed `BetterAuthOptions` at call time (inside `createBetterAuth`), returns the full `DBAdapter`. - Internally: 1. Constructs the 10-method underlying adapter via `createBetterAuthSurrealAdapter(options)` (the existing surface). 2. Wraps via `createAdapterFactory({ ... })` from `@better-auth/core/db`. The wrapper presents the v1.6 `DBAdapter` to Better-Auth and forwards every operation through our adapter's `create/findOne/findMany/update/updateMany/delete/deleteMany/count` methods (the 10th method, `consumeOne`, is wired for atomic verification-token consumption). 3. Translates the `getDefaultIdField` / `transaction` / `createSchema` methods Better-Auth expects: - `getDefaultIdField`: returns `"id"` (default — operators override via `BetterAuthSurrealAdapterOptions.modelToTable` only affects table names). - `transaction`: forwards to SurrealDB's `runSurrealTransaction` helper from `@suaveplan/surrealdb`. - `createSchema`: returns `BETTER_AUTH_SURREAL_SCHEMA` as a `string` so Better-Auth's CLI flows (`@better-auth/cli generate`) can emit the canonical schema. Idempotent per `DEFINE … OVERWRITE`. - `BetterAuthSurrealAdapterV16Options` — type alias for the v1.6 factory's options object. Identical to `BetterAuthSurrealAdapterOptions` except wraps the per-call `BetterAuthOptions` argument the factory receives. Zod-validated via the same `BetterAuthSurrealAdapterOptionsSchema`. - Subpath export: `./adapter/v1.6`. - README quick-start updated to show v1.6 usage as the default. The v1.4-shape adapter is documented as "advanced — direct conformance harness usage." ## Out of scope - **Better-Auth v1.4 support drop.** The existing v1.4-shape export is preserved (no caller uses it yet, but the public surface stability is worth preserving for the conformance harness path). - **Schema generation CLI integration.** Better-Auth's CLI (`@better-auth/cli generate --adapter @suaveplan/better-auth-surrealdb/adapter/v1.6`) will work via the `createSchema` translation, but bundling the CLI itself is a separate package. - **Transaction nesting / savepoints.** SurrealDB v3's transaction model is flat; nested transaction calls degrade to the outermost transaction (matches Better-Auth's documented expectation). - **Custom ID field strategies via Better-Auth's `customIdField`.** Better-Auth's `customIdField` option flows through to the underlying adapter's `idStrategy: "plain"` behaviour (`id` stored as a field, SurrealDB auto-generates the record's storage id). Operators using `customIdField` should pass `idStrategy: "plain"` explicitly. ## Source mapping Genesis-original — surfaced by the `add-api-plugin-auth` scaffold-time blocker. | Requirement | Source | |---|---| | `DBAdapterInstance` factory shape | Better-Auth v1.6 `BetterAuthOptions.database` type | | `createAdapterFactory` wrapper | `@better-auth/core/db` — official custom-adapter escape hatch | | Transaction forwarding | `@suaveplan/surrealdb`'s `runSurrealTransaction` helper | | `createSchema` returning DDL | `BETTER_AUTH_SURREAL_SCHEMA` shipped at `./schema` | ## Impact ### Affected dependents - `@suaveplan/api-plugin-auth` (in-flight) — unblocks. Auth plugin's `onInit` will use `createBetterAuth({ database: betterAuthSurrealAdapter({ client: db, ... }), ...options.betterAuth })`. - Existing `createBetterAuthSurrealAdapter` callers (the conformance harness in `tests/integration/`) — unchanged. Risk: low. Additive on the package; the new factory is a thin wrapper over the existing internal 10-method adapter, exercised by the same conformance harness against the same testcontainer.