v2.0.0-alpha: BooCoder foundation — container, schema, DB rename
Phase 1 of v2.0. BooCoder is live at port 9502 with a health endpoint. - Database renamed: ALTER DATABASE boocode RENAME TO boochat (one-time). All services updated to connect to /boochat. Docker service name stays boocode_db (rename is internal to Postgres, not Docker). - New apps/coder/ app skeleton: Fastify server with health endpoint, postgres connection, schema apply on boot. Mirrors apps/server pattern but minimal (no inference loop yet — Phase 2). - Schema: pending_changes (operation queue before /apply), tasks (dispatch DAG with state machine), available_agents (startup-probed agent registry), human_inbox view (tasks WHERE state IN blocked/failed). All IF NOT EXISTS, idempotent on re-run. Same boochat database, different tables. - Dockerfile: Node 20 bookworm-slim (glibc for future node-pty in Phase 5). Multi-stage build matching the existing boocode image pattern. - docker-compose.yml: boocoder service on 100.114.205.53:9502, /opt:/opt:rw mount (write-capable, policy-gated at tool layer), depends on boocode_db. - BOOCODER.md: container guidance declaring write-tool capability + pending-changes discipline. All 4 services boot and pass health checks. 9 tables in the shared DB. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
45
apps/coder/src/db.ts
Normal file
45
apps/coder/src/db.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import postgres from 'postgres';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, resolve } from 'node:path';
|
||||
import type { Config } from './config.js';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
export type Sql = ReturnType<typeof postgres>;
|
||||
|
||||
let sqlInstance: Sql | null = null;
|
||||
|
||||
export function getSql(config: Config): Sql {
|
||||
if (sqlInstance) return sqlInstance;
|
||||
sqlInstance = postgres(config.DATABASE_URL, {
|
||||
max: 10,
|
||||
idle_timeout: 30,
|
||||
connect_timeout: 10,
|
||||
onnotice: () => {},
|
||||
});
|
||||
return sqlInstance;
|
||||
}
|
||||
|
||||
export async function applySchema(sql: Sql): Promise<void> {
|
||||
const schemaPath = resolve(__dirname, 'schema.sql');
|
||||
const ddl = await readFile(schemaPath, 'utf8');
|
||||
await sql.unsafe(ddl);
|
||||
}
|
||||
|
||||
export async function pingDb(sql: Sql): Promise<boolean> {
|
||||
try {
|
||||
await sql`SELECT 1`;
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function closeDb(): Promise<void> {
|
||||
if (sqlInstance) {
|
||||
await sqlInstance.end({ timeout: 5 });
|
||||
sqlInstance = null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user