From 7a4568695230bc197433abd5f2bd31c026579f96 Mon Sep 17 00:00:00 2001 From: rajch_ales Date: Wed, 5 Aug 2026 22:08:42 +0200 Subject: [PATCH] Preconfigure local DBGate connections --- agent.md | 1 + package.json | 2 +- scripts/start-dbgate.ts | 63 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 scripts/start-dbgate.ts diff --git a/agent.md b/agent.md index f7d74be..5579a2e 100644 --- a/agent.md +++ b/agent.md @@ -106,6 +106,7 @@ There are three selectable data sources: - Stores scraper source configuration, manufacturer-to-source mapping, scrape runs, discovered products and assets. - Supplier/manufacturer website settings such as source URL, search templates, fallback mode, browser engine, headless mode, wait time, notes and enabled/priority flags belong in Local scrape DB, not in the product catalog database. - The Settings modal should expose an `Open DBGate` action beside `Local scrape DB`; it opens the local DBGate URL from `DBGATE_URL` / `databaseGate.url` for inspecting `catalog_scrape`. +- Start DBGate only through `npm run dbgate`; the script reads `.env` and preconfigures `Local 9bplus DB` plus `Local scrape DB` as DBGate connections. Do not start raw `dbgate-serve` because it will not receive the project database profiles. - It must never be used as a fallback for catalog reads. When selected in the UI, existing catalog reads continue using Local 9bplus DB until dedicated scrape-storage endpoints are added. - The schema is versioned in `sql/local-scrape-db.sql` and can be created with `npm run db:create-scrape`. - Existing legacy mapping rows from `Local 9bplus DB` can be copied into Local scrape DB with `npm run db:migrate-mapping-to-scrape`. diff --git a/package.json b/package.json index 8e39e2b..5a3dc0e 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "catalog:dry-run": "tsx src/cli.ts catalog-maker --dry-run", "db:create-scrape": "tsx scripts/create-local-scrape-db.ts", "db:migrate-mapping-to-scrape": "tsx scripts/migrate-mapping-to-scrape-db.ts", - "dbgate": "dbgate-serve", + "dbgate": "tsx scripts/start-dbgate.ts", "test": "tsx --test test/*.test.ts", "test:ui": "playwright test", "test:e2e": "playwright test tests/ui/database.e2e.spec.ts", diff --git a/scripts/start-dbgate.ts b/scripts/start-dbgate.ts new file mode 100644 index 0000000..a56ec92 --- /dev/null +++ b/scripts/start-dbgate.ts @@ -0,0 +1,63 @@ +import { spawn } from "node:child_process"; +import fs from "node:fs"; + +const envFile = ".env"; +const localEnv = fs.existsSync(envFile) ? readEnvFile(envFile) : {}; + +const host = localEnv.DB_HOST || "127.0.0.1"; +const port = localEnv.DB_PORT || "3306"; +const user = localEnv.DB_USER || "root"; +const password = localEnv.DB_PASSWORD || ""; +const catalogDatabase = localEnv.DB_NAME || "9bplus"; +const scrapeDatabase = localEnv.SCRAPE_DB_NAME || "catalog_scrape"; + +const dbgateEnv = { + ...process.env, + CONNECTIONS: "local9bplus,localscrape", + + ENGINE_local9bplus: "mariadb@dbgate-plugin-mysql", + SERVER_local9bplus: host, + PORT_local9bplus: port, + USER_local9bplus: user, + PASSWORD_local9bplus: password, + DATABASE_local9bplus: catalogDatabase, + LABEL_local9bplus: "Local 9bplus DB", + READONLY_local9bplus: "1", + + ENGINE_localscrape: "mariadb@dbgate-plugin-mysql", + SERVER_localscrape: host, + PORT_localscrape: port, + USER_localscrape: user, + PASSWORD_localscrape: password, + DATABASE_localscrape: scrapeDatabase, + LABEL_localscrape: "Local scrape DB", + READONLY_localscrape: "0", +}; + +const child = spawn("dbgate-serve", { + stdio: "inherit", + shell: true, + env: dbgateEnv, +}); + +child.on("exit", (code, signal) => { + if (signal) { + process.kill(process.pid, signal); + return; + } + + process.exit(code ?? 0); +}); + +function readEnvFile(filePath: string): Record { + return Object.fromEntries( + fs.readFileSync(filePath, "utf8") + .split(/\r?\n/) + .map((line) => line.trim()) + .filter((line) => line && !line.startsWith("#") && line.includes("=")) + .map((line) => { + const separator = line.indexOf("="); + return [line.slice(0, separator).trim(), line.slice(separator + 1).trim()]; + }), + ); +}