Fix harmonize prod DB targeting and large-hall loading hangs.

Prod env files now win over root .env so harmonize:db can open gallery_prod after gallery_dev; tour_stops gains updated_at; halls no longer block the overlay on every painting texture. Docs cover the fixes and one-artist image pull from prod; Duccio painting assets synced from TrueNAS.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Danila Khodjaef
2026-07-26 01:26:51 +03:00
co-authored by Cursor
parent f6c73c1792
commit 8e444fa461
115 changed files with 124 additions and 37 deletions
+33 -12
View File
@@ -9,8 +9,9 @@ const DEV_DB_NAME = 'gallery_dev';
const PROD_DB_NAME = 'gallery_prod';
const LEGACY_DB_NAMES = ['Gallery', 'gallery'];
function loadEnvFile(filePath) {
if (!fs.existsSync(filePath)) return;
function parseEnvFile(filePath) {
const out = {};
if (!fs.existsSync(filePath)) return out;
const content = fs.readFileSync(filePath, 'utf8');
for (const line of content.split(/\r?\n/)) {
const trimmed = line.trim();
@@ -25,22 +26,35 @@ function loadEnvFile(filePath) {
) {
value = value.slice(1, -1);
}
out[key] = value;
}
return out;
}
/** Load into process.env without overwriting keys already set. */
function loadEnvFile(filePath) {
const parsed = parseEnvFile(filePath);
for (const [key, value] of Object.entries(parsed)) {
if (process.env[key] === undefined) process.env[key] = value;
}
}
function pgConfigFromEnv() {
const host = process.env.DB_HOST || '192.168.10.122';
const port = Number(process.env.DB_PORT || 5432);
const user = process.env.DB_USER;
const password = process.env.DB_PASSWORD;
const database = process.env.DB_NAME;
function pgConfigFromMap(env) {
const host = env.DB_HOST || '192.168.10.122';
const port = Number(env.DB_PORT || 5432);
const user = env.DB_USER;
const password = env.DB_PASSWORD;
const database = env.DB_NAME;
if (!user || !password || !database) {
throw new Error('DB_USER, DB_PASSWORD, and DB_NAME are required');
}
return { host, port, user, password, database };
}
function pgConfigFromEnv() {
return pgConfigFromMap(process.env);
}
function assertProdDatabase(dbName) {
if (!dbName.endsWith(PROD_DB_SUFFIX) && dbName !== PROD_DB_NAME) {
throw new Error(
@@ -61,16 +75,22 @@ function assertDevDatabase(dbName) {
return dbName;
}
/**
* File values win over process.env so loading prod after dev (or vice versa)
* in the same process cannot leave the wrong DB_NAME stuck.
*/
function loadDevPgConfig() {
loadEnvFile(path.join(rootDir, '.env'));
const config = pgConfigFromEnv();
const filePath = path.join(rootDir, '.env');
const fileEnv = parseEnvFile(filePath);
const config = pgConfigFromMap({ ...process.env, ...fileEnv });
assertDevDatabase(config.database);
return config;
}
function loadProdPgConfig() {
loadEnvFile(path.join(rootDir, 'infra', 'docker', '.env.prod'));
const config = pgConfigFromEnv();
const filePath = path.join(rootDir, 'infra', 'docker', '.env.prod');
const fileEnv = parseEnvFile(filePath);
const config = pgConfigFromMap({ ...process.env, ...fileEnv });
assertProdDatabase(config.database);
return config;
}
@@ -93,6 +113,7 @@ module.exports = {
PROD_DB_NAME,
LEGACY_DB_NAMES,
rootDir,
parseEnvFile,
loadEnvFile,
pgConfigFromEnv,
assertProdDatabase,