PSA/ee/server/knexfile.cjs
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

166 lines
4.4 KiB
JavaScript

/* eslint-disable no-undef */
const localRequire =
(typeof require !== 'undefined' && require)
|| (typeof module !== 'undefined' && typeof module.createRequire === 'function'
? module.createRequire(__filename)
: null);
if (!localRequire) {
throw new Error('ee/server/knexfile.cjs must be executed in a CommonJS context where require() is available.');
}
localRequire('dotenv').config();
const fs = localRequire('fs');
const path = localRequire('path');
// Calculate secrets directory path once at module load
const DOCKER_SECRETS_PATH = '/run/secrets';
const LOCAL_SECRETS_PATH = '../secrets';
const SECRETS_PATH = fs.existsSync(DOCKER_SECRETS_PATH) ? DOCKER_SECRETS_PATH : LOCAL_SECRETS_PATH;
function getSecret(secretName, envVar, defaultValue = '') {
const secretPath = path.join(SECRETS_PATH, secretName);
try {
return fs.readFileSync(secretPath, 'utf8').trim();
} catch (error) {
if (process.env[envVar]) {
console.warn(`Using ${envVar} environment variable instead of Docker secret`);
return process.env[envVar] || defaultValue;
}
console.warn(`Neither secret file ${secretPath} nor ${envVar} environment variable found, using default value`);
return defaultValue;
}
}
const DatabaseType = {
postgres: 'postgres'
};
const externals = {
[DatabaseType.postgres]: 'pg'
// Add more alternatives as needed
};
const isValidDbType = (type) => {
return type !== undefined && Object.keys(externals).includes(type);
};
const getClient = () => {
const dbType = process.env.DB_TYPE;
if (isValidDbType(dbType)) {
return externals[dbType];
}
console.warn(`Invalid or missing DB_TYPE: ${dbType}. Defaulting to postgres.`);
return externals[DatabaseType.postgres];
};
const createConnectionWithTenant = (config, tenant) => {
return {
...config,
pool: {
...config.pool,
afterCreate: (conn, done) => {
conn.query(`SET SESSION "app.current_tenant" = '${tenant}';`, (err) => {
if (err) {
console.error('Error setting tenant:', err);
}
done(err, conn);
});
},
},
};
};
// Base configuration for migrations (uses postgres user)
const migrationConfig = {
client: getClient(),
connection: {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER_ADMIN || 'postgres',
password: getSecret('postgres_password', 'DB_PASSWORD_ADMIN'),
database: process.env.DB_NAME_SERVER,
},
pool: {
min: 2,
max: 20,
},
migrations: {
directory: "./migrations"
}
};
// Base configuration for application (uses app_user)
const appConfig = {
client: getClient(),
connection: {
host: process.env.DB_HOST,
port: process.env.DB_PORT,
user: process.env.DB_USER_SERVER || 'app_user',
password: getSecret('db_password_server', 'DB_PASSWORD_SERVER'),
database: process.env.DB_NAME_SERVER,
},
pool: {
min: 2,
max: 20,
}
};
const knexfile = {
development: {
// Development uses app_user for normal operations
...appConfig,
// But keeps postgres user connection for migrations
migrations: migrationConfig.migrations,
seeds: {
directory: "./seeds/dev",
loadExtensions: ['.cjs', '.js']
}
},
test: {
client: getClient(),
connection: {
host: process.env.DB_HOST || 'localhost',
port: process.env.DB_PORT || '5432',
user: process.env.DB_USER_ADMIN || 'postgres',
password: getSecret('db_password_server', 'DB_PASSWORD_SERVER', 'test_password'),
database: process.env.DB_NAME_SERVER || 'sebastian_test',
},
pool: {
min: 2,
max: 20,
},
migrations: migrationConfig.migrations,
},
production: {
// Production uses app_user for normal operations
...appConfig,
// But keeps postgres user connection for migrations
migrations: migrationConfig.migrations,
},
local: {
client: 'postgresql',
connection: {
host: 'localhost',
port: '5432',
user: process.env.DB_USER_SERVER || 'app_user',
password: getSecret('db_password_server', 'DB_PASSWORD_SERVER', 'abcd1234!'),
database: process.env.DB_NAME_SERVER || 'server',
},
migrations: migrationConfig.migrations,
},
// Special config just for running migrations (uses postgres user)
migration: migrationConfig
};
console.log('/server/knexfile', knexfile);
module.exports = {
...knexfile,
createConnectionWithTenant,
};