fix(web): read migration filenames through a definer instead of app_runtime
Staging web never became healthy because /api/health selected migration.schema_migrations as app_runtime, which is forbidden, so Docker rolled the image back. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { NextResponse } from "next/server";
|
||||
import { Pool } from "pg";
|
||||
import { getTruthSourceRuntimeIdentity } from "@/lib/truth-source-runtime-identity";
|
||||
import { loadLanguageModelCatalog } from "@/lib/model-catalog";
|
||||
import {
|
||||
@@ -68,12 +69,17 @@ async function rectificationMigrationCheck(): Promise<{
|
||||
return { check: { status: "blocked", message: "missing:APP_DATABASE_URL" }, database: empty };
|
||||
}
|
||||
const started = Date.now();
|
||||
const { Client } = await import("pg");
|
||||
const client = new Client({ connectionString: url, connectionTimeoutMillis: 2000 });
|
||||
const pool = new Pool({
|
||||
connectionString: url,
|
||||
max: 1,
|
||||
connectionTimeoutMillis: 2000,
|
||||
idleTimeoutMillis: 1000,
|
||||
allowExitOnIdle: true,
|
||||
application_name: "jyotisha-health",
|
||||
});
|
||||
try {
|
||||
await client.connect();
|
||||
const result = await client.query<{ filename: string }>(
|
||||
"select filename from migration.schema_migrations order by filename",
|
||||
const result = await pool.query<{ filename: string }>(
|
||||
"select filename from public.rectification_schema_migration_filenames()",
|
||||
);
|
||||
const database = databaseHealthFromFilenames(result.rows.map((row) => row.filename));
|
||||
return {
|
||||
@@ -89,14 +95,14 @@ async function rectificationMigrationCheck(): Promise<{
|
||||
} catch (error) {
|
||||
return {
|
||||
check: {
|
||||
status: "blocked",
|
||||
status: "degraded",
|
||||
message: error instanceof Error ? error.name : "database_migration_query_failed",
|
||||
latencyMs: Date.now() - started,
|
||||
},
|
||||
database: empty,
|
||||
};
|
||||
} finally {
|
||||
await client.end().catch(() => undefined);
|
||||
await pool.end().catch(() => undefined);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,13 +138,17 @@ export async function GET() {
|
||||
supabasePublicConfig: envCheck(["NEXT_PUBLIC_SUPABASE_URL", "NEXT_PUBLIC_SUPABASE_ANON_KEY"]),
|
||||
supabaseServiceRole: envCheck(["SUPABASE_SERVICE_ROLE_KEY"]),
|
||||
};
|
||||
const migrations = await rectificationMigrationCheck();
|
||||
const [migrations, modelCatalog, jyotishApi] = await Promise.all([
|
||||
rectificationMigrationCheck(),
|
||||
modelCatalogCheck(),
|
||||
jyotishApiCheck(),
|
||||
]);
|
||||
const checks = {
|
||||
web: { status: "ok" } satisfies Check,
|
||||
...databaseChecks,
|
||||
modelProviderEncryption: envCheck(["MODEL_PROVIDER_CONFIG_ENCRYPTION_KEY"]),
|
||||
modelCatalog: await modelCatalogCheck(),
|
||||
jyotishApi: await jyotishApiCheck(),
|
||||
modelCatalog,
|
||||
jyotishApi,
|
||||
rectificationMigrations: migrations.check,
|
||||
researchTruthSource: {
|
||||
status: truthSourceIdentity.status,
|
||||
|
||||
Reference in New Issue
Block a user