Initial Commit
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
<!-- markdownlint-disable MD024 -->
|
||||
|
||||
# Capability Spec Delta: better-auth-surrealdb (extend-better-auth-surrealdb-v1.6-adapter)
|
||||
|
||||
**Package**: `@suaveplan/better-auth-surrealdb`
|
||||
**Status**: PROPOSED
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: betterAuthSurrealAdapter returns a Better-Auth v1.6 DBAdapterInstance
|
||||
|
||||
The package SHALL export `betterAuthSurrealAdapter(options): DBAdapterInstance` from the root barrel AND from a new `./adapter/v1.6` subpath. The return value SHALL be a function `(betterAuthOptions: BetterAuthOptions) => DBAdapter` that Better-Auth v1.6's `createBetterAuth` accepts as its `database` field. The factory SHALL Zod-validate `options` via `BetterAuthSurrealAdapterOptionsSchema` (same schema the v1.4 factory uses); failures raise `BetterAuthSurrealError(BETTER_AUTH_SURREALDB_INVALID_INPUT)`.
|
||||
|
||||
#### Scenario: factory consumed by createBetterAuth
|
||||
|
||||
- **WHEN** `createBetterAuth({ database: betterAuthSurrealAdapter({ client }), secret: "x", baseUrl: "http://localhost" })` is called against a real SurrealDB testcontainer with the schema applied
|
||||
- **THEN** the call returns a `BetterAuth` instance whose `auth.api.signUpEmail({ body: { email, password, name } })` round-trips successfully (creates user, account, session)
|
||||
|
||||
**Verified by:** `src/adapter/v1.6.test.ts::"factory consumed by createBetterAuth signs up successfully"` AND `src/adapter/v1.6.spec-conformance.test.ts::"return type satisfies DBAdapterInstance via expectTypeOf"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: v1.6 factory wraps the shipped 10-method adapter via createAdapterFactory
|
||||
|
||||
The v1.6 factory SHALL internally call `createBetterAuthSurrealAdapter(options)` to build the underlying 10-method adapter and SHALL wrap it via `createAdapterFactory` from `@better-auth/core/db`. The wrapper SHALL forward every Better-Auth v1.6 method onto the underlying adapter's existing methods: `findOne`/`findMany`/`create`/`update`/`updateMany`/`delete`/`deleteMany`/`count` map 1:1; `transaction` forwards to `runSurrealTransaction` from `@suaveplan/surrealdb`; `getDefaultIdField` returns `"id"`; `createSchema` returns `BETTER_AUTH_SURREAL_SCHEMA`. Underlying error classes (`BetterAuthSurrealError`) propagate through the wrapper unchanged.
|
||||
|
||||
#### Scenario: error propagation through the wrapper
|
||||
|
||||
- **WHEN** an invalid operator surfaces in a wrapped v1.6 call (e.g. a `findMany` whose Where uses an unsupported op)
|
||||
- **THEN** the rejection is a `BetterAuthSurrealError(BETTER_AUTH_SURREALDB_INVALID_OPERATOR)` (not a generic wrapper error)
|
||||
|
||||
#### Scenario: transaction forwards to SurrealDB
|
||||
|
||||
- **WHEN** Better-Auth invokes `adapter.transaction(async (txAdapter) => txAdapter.create({...}))` on the wrapped factory
|
||||
- **THEN** `runSurrealTransaction` is invoked AND the inner `create` runs inside the transaction (rolled back on throw, committed on resolve)
|
||||
|
||||
**Verified by:** `src/adapter/v1.6.test.ts::"errors propagate from the underlying adapter"` AND `src/adapter/v1.6.test.ts::"transaction forwards to runSurrealTransaction"` AND `src/adapter/v1.6.test.ts::"getDefaultIdField returns 'id'"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: createSchema returns BETTER_AUTH_SURREAL_SCHEMA verbatim
|
||||
|
||||
The wrapped adapter's `createSchema` method (called by Better-Auth's CLI generator) SHALL return the exact string content of `BETTER_AUTH_SURREAL_SCHEMA`. No interpolation, no per-config customisation in v1 — operators who need a modified schema run `@better-auth/cli generate --output ./schema.surql` then edit the file.
|
||||
|
||||
#### Scenario: createSchema output matches BETTER_AUTH_SURREAL_SCHEMA
|
||||
|
||||
- **WHEN** the wrapped adapter's `createSchema()` is invoked
|
||||
- **THEN** the result equals `BETTER_AUTH_SURREAL_SCHEMA` (character-for-character)
|
||||
|
||||
**Verified by:** `src/adapter/v1.6.test.ts::"createSchema returns BETTER_AUTH_SURREAL_SCHEMA verbatim"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: v1.6 wrapper is exercised end-to-end against real Better-Auth + SurrealDB
|
||||
|
||||
The v1.6 wrapper SHALL be exercised by a full Better-Auth end-to-end integration test (`tests/integration/better-auth-end-to-end.test.ts`) that constructs `betterAuth({ database: betterAuthSurrealAdapter({ client }) })` against a real SurrealDB testcontainer and rounds-trips `auth.api.signUpEmail`. The existing v1.4-shape `runAdapterConformance` harness MAY NOT run verbatim against the v1.6 DBAdapter because Better-Auth's `transformInput` whitelists fields against the in-memory Better-Auth schema, which uses column names that differ from the bundled SurrealQL schema (e.g. Better-Auth's `verification.value` vs. the package's `verification.val`). The wrapper is still smoke-tested against the testcontainer (factory builds, DBAdapter shape correct) and unit-tested at 100% line/branch/function coverage in `src/adapter/v1.6.test.ts`.
|
||||
|
||||
#### Scenario: v1.4-shape harness runs against the v1.4 factory
|
||||
|
||||
- **WHEN** the integration test runs `runAdapterConformance(() => createBetterAuthSurrealAdapter({ client }))` against the testcontainer
|
||||
- **THEN** every scenario passes (no regression in the v1.4 surface)
|
||||
|
||||
#### Scenario: v1.6 wrapper round-trips a full Better-Auth signUpEmail flow
|
||||
|
||||
- **WHEN** the e2e test constructs `betterAuth({ database: betterAuthSurrealAdapter({ client }), … })` and calls `auth.api.signUpEmail({ body: { email, password, name } })` against the testcontainer
|
||||
- **THEN** the call resolves with a `user` whose `email` matches the input, AND the SurrealDB `user` table contains a row with that email, AND the `account` table contains a `credential`-provider row
|
||||
|
||||
**Verified by:** `tests/integration/conformance.test.ts::"v1.4-shape adapter passes conformance"` AND `tests/integration/conformance.test.ts::"factory build + DBAdapter shape smoke check (full flow lives in better-auth-end-to-end.test.ts)"` AND `tests/integration/better-auth-end-to-end.test.ts::"createBetterAuth + signUpEmail round-trips against real SurrealDB"`
|
||||
|
||||
---
|
||||
|
||||
### Requirement: README v1.6 quick-start is the default; v1.4 documented as advanced
|
||||
|
||||
The package README SHALL show `betterAuthSurrealAdapter` (v1.6) usage as the default quick-start. The v1.4-shape `createBetterAuthSurrealAdapter` SHALL be documented under an "Advanced — direct conformance harness usage" section. New subpath `./adapter/v1.6` is listed alongside the existing `./adapter`.
|
||||
|
||||
#### Scenario: README quick-start uses betterAuthSurrealAdapter
|
||||
|
||||
- **WHEN** the docs:check / readme-lint pass scans the README
|
||||
- **THEN** the first non-install code block uses `betterAuthSurrealAdapter(...)` (not the v1.4 surface)
|
||||
|
||||
**Verified by:** `tests/dep-graph.test.ts::"README quick-start uses betterAuthSurrealAdapter v1.6 factory"` AND `tests/dep-graph.test.ts::"./adapter/v1.6 subpath export resolves"`
|
||||
|
||||
<!-- markdownlint-enable MD024 -->
|
||||
Reference in New Issue
Block a user