Self-hostable Conduct backend with database adapters
npm install conduct-backendbash
npm install conduct-backend @superfunctions/db @superfunctions/http
Choose your framework adapter
npm install @superfunctions/http-express # For Express
OR npm install @superfunctions/http-hono # For Hono
OR @superfunctions/http-next # For Next.js
Choose your ORM
npm install drizzle-orm postgres # For Drizzle + PostgreSQL
OR npm install @prisma/client # For Prisma
OR npm install kysely pg # For Kysely
`
$3
#### 1. Generate Database Schema
First, generate the ORM-specific schema files from the Conduct backend's abstract schema:
`bash
Generate Drizzle schema files
npx @superfunctions/cli generate-schema \
--config ./node_modules/conduct-backend \
--adapter drizzle \
--output ./src/db
This creates ./src/db/conduct-schema.ts with Drizzle table definitions
`
#### 2. Set Up Database
`typescript
// db.ts
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import * as conductSchema from './db/conduct-schema';
const client = postgres(process.env.DATABASE_URL!);
export const db = drizzle(client, { schema: conductSchema });
`
#### 3. Initialize Conduct SDK
`typescript
// conduct.ts
import { createConductBackend } from 'conduct';
import { drizzleAdapter } from '@superfunctions/db/adapters/drizzle';
import { db } from './db';
const adapter = drizzleAdapter({
db,
dialect: 'postgres',
});
export const conduct = createConductBackend({
database: adapter,
namespace: 'conduct', // Optional: table prefix
auth: {
apiKeys: async (key: string) => {
// Implement your API key validation
const validKey = await validateApiKey(key);
if (!validKey) return null;
return {
apiKeyId: validKey.id,
projectIds: validKey.projectIds,
};
},
},
cors: {
origin: '*', // Configure as needed
credentials: true,
},
});
`
#### 4. Mount in Your Framework
Express:
`typescript
import express from 'express';
import { toExpress } from '@superfunctions/http-express';
import { conduct } from './conduct';
const app = express();
app.use('/api/conduct', toExpress(conduct.router));
app.listen(3000);
`
Hono:
`typescript
import { Hono } from 'hono';
import { toHono } from '@superfunctions/http-hono';
import { conduct } from './conduct';
const app = new Hono();
app.route('/api/conduct', toHono(conduct.router));
export default app;
`
Next.js App Router:
`typescript
// app/api/conduct/[...path]/route.ts
import { toNextHandlers } from '@superfunctions/http-next';
import { conduct } from '@/conduct';
export const { GET, POST, PUT, DELETE } = toNextHandlers(conduct.router);
`
Cloudflare Workers:
`typescript
import { conduct } from './conduct';
export default {
async fetch(request: Request, env: Env) {
return conduct.router.handle(request);
},
};
`
$3
Once mounted, the following endpoints are available:
#### Health Check
- GET /health - Health check (no auth required)
#### Specs
- POST /specs - Create a new spec with requirements
- GET /specs - List specs with pagination
- GET /specs/:id - Get spec with requirements
- PUT /specs/:id - Update spec
#### Plans
- POST /plans - Create execution plan for a spec
- GET /plans/:specId - Get plan with tasks
- PUT /plans/:specId - Update plan
#### Runs
- POST /runs - Start tracking a run
- PUT /runs/:id - Mark run as completed
- GET /runs/:id - Get run details
- GET /runs - List runs with filters
#### Admin
- GET /admin/projects - List projects
- POST /admin/projects - Create project
- GET /admin/projects/:id - Get project
- PUT /admin/projects/:id - Update project
$3
All endpoints (except /health) require:
- Authorization: Bearer YOUR_API_KEY header
- X-Project-ID: project_id header
$3
The SDK uses the following tables:
- projects - Root projects
- specs - Specifications with markdown content (mdJson)
- requirements - Spec requirements
- tasks - Execution tasks (part of plans)
- tasks_requirements - Junction table linking tasks to requirements
- runs - Agent run tracking
$3
IMPORTANT: The conduct-backend no longer exports ORM-specific schemas. You must generate them using the Superfunctions CLI.
#### Step 1: Generate Schema
Run the CLI command to generate ORM-specific schema files:
`bash
For Drizzle
npx @superfunctions/cli generate-schema \
--config ./node_modules/conduct-backend \
--adapter drizzle \
--output ./src/db
For Prisma
npx @superfunctions/cli generate-schema \
--config ./node_modules/conduct-backend \
--adapter prisma \
--output ./prisma
For Kysely
npx @superfunctions/cli generate-schema \
--config ./node_modules/conduct-backend \
--adapter kysely \
--output ./src/db
`
#### Step 2: Import Generated Schema
Import the generated schema when initializing your ORM:
`typescript
// Drizzle
import * as conductSchema from './db/conduct-schema';
const db = drizzle(client, { schema: conductSchema });
// The adapter reads the schema from db._.fullSchema automatically
const adapter = drizzleAdapter({ db, dialect: 'postgres' });
`
#### Step 3: Run Migrations
Use your ORM's migration tools:
`bash
Drizzle
npx drizzle-kit generate
npx drizzle-kit push
Prisma
npx prisma migrate dev
`
$3
`
Consumer Application
├── Framework (Express/Hono/Next.js/etc.)
├── Database Setup (Postgres/MySQL/SQLite)
├── Adapter Creation (drizzleAdapter/prismaAdapter)
└── Conduct SDK Integration
├── Router (framework-agnostic)
├── API Handlers (specs, plans, runs, admin)
└── Database Abstraction (adapter interface)
`
$3
See example-server-v2.ts for a complete Express integration example.
$3
`typescript
import type {
ConductBackend,
ConductConfig,
AuthData,
Spec,
Requirement,
Task,
Run,
} from 'conduct';
`
$3
This is the Conduct backend SDK. For the CLI, see the cli/` directory.