Chapter 2 — backend
Wire a NestJS API with SchemaModule and the Supabase adapter.
The backend is a NestJS app that mounts SchemaModule from @stndrds/adapter-nestjs and wires a Supabase database adapter. The schema package from chapter 1 is consumed as a workspace dependency.
Install backend packages
pnpm add @nestjs/common @nestjs/core @nestjs/config @stndrds/adapter-nestjs @stndrds/adapter-supabase @stndrds/adapter-meilisearch @supabase/supabase-js@stndrds/adapter-meilisearch is required because the Supabase adapter mandates a search adapter for full-text indexing. For local development you can run Meilisearch with Docker.
Wire the SchemaModule
Create src/modules/schema/schema.module.ts. The snippet below keeps only the Supabase and Meilisearch wiring — all other optional adapters are omitted.
// @noverify
import { Module } from "@nestjs/common";
import { SchemaModule as StandardSchemaModule } from "@stndrds/adapter-nestjs";
import { MeilisearchSearchAdapter } from "@stndrds/adapter-meilisearch";
import { SupabaseDatabaseAdapter } from "@stndrds/adapter-supabase";
import { createClient } from "@supabase/supabase-js";
import { registry } from "@crm-tutorial/schema";
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!,
);
const search = new MeilisearchSearchAdapter({
host: process.env.MEILISEARCH_HOST!,
apiKey: process.env.MEILISEARCH_API_KEY!,
indexPrefix: "crm",
});
export const SchemaModule = StandardSchemaModule.forRoot({
registry,
adapter: new SupabaseDatabaseAdapter(supabase, { search }),
autoSync: true,
global: true,
});autoSync: true reconciles your object definitions with the database on startup. global: true makes SchemaModule providers available throughout the app without re-importing.
Mount in the app
Import SchemaModule in your root AppModule:
// @noverify
import { Module } from "@nestjs/common";
import { ConfigModule } from "@nestjs/config";
import { SchemaModule } from "./modules/schema/schema.module";
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
SchemaModule,
],
})
export class AppModule {}Env vars
The minimum required variables for this tutorial:
SUPABASE_URL— your Supabase project URLSUPABASE_SERVICE_ROLE_KEY— service-role key (server-only, never expose to the client)MEILISEARCH_HOST— Meilisearch instance URL (e.g.http://localhost:7700)MEILISEARCH_API_KEY— Meilisearch master key
For production wiring with all five adapters (Redis cache, BullMQ queue, E2B sandbox), see the NestJS backend guide.
Auth
A real app needs an auth guard. standards-platform uses a custom Supabase JWT guard for user-facing requests and ApiKeyAuthGuard from @stndrds/adapter-nestjs for service-to-service calls. Pick the scheme that fits your app; the full setup is covered in the NestJS backend guide.
Next: Chapter 3 — views.