2.2 KiB
2.2 KiB
service/db-port.ts
Purpose
Declares SiteDb, the structural database port that SiteService and DomainResolverService consume. suaveplan's foundation DatabaseAdapter (@suaveplan/db) only owns query / execute, so the typed CRUD surface (create, update) we need for site records is sourced from @suaveplan/surrealdb's SurrealAdapter. Centralising the port here lets the services depend on a single structural shape rather than SurrealAdapter directly, which keeps the unit tests free of testcontainer requirements and keeps the production wiring honest: any SurrealAdapter instance satisfies this shape by construction.
Features
- One structural interface —
SiteDb— exposingquery(positional bindings),create(typed),update(typed). - No runtime imports — pure type module.
- Lets tests supply minimal fakes without crafting a full
DatabaseAdapter.
Usage: Basic
import type { SiteDb } from "@suaveplan/api-plugin-site/service/db-port";
const fake: SiteDb = {
query: async () => [],
create: async (_t, d) => ({ ...d, id: "site:1" }),
update: async () => null,
};
Usage: Advanced
import type { SurrealAdapter } from "@suaveplan/surrealdb";
import type { SiteDb } from "@suaveplan/api-plugin-site/service/db-port";
// Production wiring — the live SurrealAdapter satisfies SiteDb structurally.
function wire(db: SurrealAdapter): SiteDb {
return db;
}
API Reference
interface SiteDb—query<T>(sql, params?): Promise<T[]>— positional binds ($p0...).create<T>(table, data): Promise<T & { id: string }>— typed create.update<T>(table, id, data): Promise<T | null>— typed merge.
Implementation Notes
querybindings are positional because theDatabaseAdapter.querysignature is(sql, params?: readonly unknown[]). The site plugin's SurQL statements are written with$p0,$p1, ... accordingly.- The port deliberately omits transaction / migrate / connect surface — services don't need it. Adding new methods to the port is a breaking change and follows the OpenSpec workflow.
- The port is structural — adopters do not need to extend or implement an interface explicitly.