Harden conversation bootstrap on staging
This commit is contained in:
14
src/db/ensure-runtime-schema.ts
Normal file
14
src/db/ensure-runtime-schema.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { db } from "./client.js";
|
||||
import { log } from "../log.js";
|
||||
|
||||
async function ensureGrowConversationsMetadataColumn() {
|
||||
await db.execute(`
|
||||
ALTER TABLE grow_conversations
|
||||
ADD COLUMN IF NOT EXISTS metadata jsonb NOT NULL DEFAULT '{}'::jsonb
|
||||
`);
|
||||
}
|
||||
|
||||
export async function ensureRuntimeSchema() {
|
||||
await ensureGrowConversationsMetadataColumn();
|
||||
log.info("runtime schema ensured");
|
||||
}
|
||||
@@ -24,12 +24,14 @@ import { logRoutes } from "./routes/logs.js";
|
||||
import { v1Routes } from "./v1/index.js";
|
||||
import { startGrowEventsRedisConsumer } from "./events/redis-consumer.js";
|
||||
import { db } from "./db/client.js";
|
||||
import { ensureRuntimeSchema } from "./db/ensure-runtime-schema.js";
|
||||
import { hydratePortAllocator, reconcileOnBoot, ensureCentralGiteaReady } from "./docker/manager.js";
|
||||
import { initCatalog } from "./agents/catalog.js";
|
||||
|
||||
async function main() {
|
||||
// Boot-time DB sanity + reconcile + central Gitea readiness.
|
||||
await db.execute("select 1");
|
||||
await ensureRuntimeSchema();
|
||||
await hydratePortAllocator();
|
||||
|
||||
// Ensure central Gitea is reachable before accepting traffic (changes.md §2A).
|
||||
|
||||
@@ -3,7 +3,6 @@ import { requireUser, type AuthContext } from "../auth/clerk.js";
|
||||
import { db } from "../db/client.js";
|
||||
import { growEvents, users, userStacks, type UserStack } from "../db/schema.js";
|
||||
import { and, desc, eq, inArray } from "drizzle-orm";
|
||||
import { provisionUserStack } from "../docker/manager.js";
|
||||
import { log } from "../log.js";
|
||||
import { config } from "../config.js";
|
||||
import { ensureOnboardingBaselineQscore } from "../events/onboarding-qscore.js";
|
||||
@@ -18,12 +17,6 @@ function publicStack(stack: UserStack | null | undefined) {
|
||||
return safe;
|
||||
}
|
||||
|
||||
function shouldStartProvisioning(stack: UserStack | null | undefined) {
|
||||
if (!stack || stack.status === "error" || stack.status === "stopped") return true;
|
||||
if (stack.status !== "provisioning") return false;
|
||||
return Date.now() - stack.updatedAt.getTime() >= 5 * 60_000;
|
||||
}
|
||||
|
||||
function userServiceTarget(path: string, search = "") {
|
||||
return new URL(`/api/v1/users${path}${search}`, config.userServiceUrl.replace(/\/$/, ""));
|
||||
}
|
||||
@@ -110,12 +103,6 @@ export function userRoutes() {
|
||||
where: eq(userStacks.userId, userId),
|
||||
});
|
||||
|
||||
if (shouldStartProvisioning(stack)) {
|
||||
void provisionUserStack(userId).catch((err) =>
|
||||
log.error({ err, userId }, "background provision failed"),
|
||||
);
|
||||
}
|
||||
|
||||
return c.json({
|
||||
user: userServiceUser,
|
||||
backendUser: userRow,
|
||||
|
||||
Reference in New Issue
Block a user