mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 00:52:50 +00:00
111 lines
4.1 KiB
TypeScript
111 lines
4.1 KiB
TypeScript
import { dirname } from "path";
|
|
|
|
import { registerAs } from "@nestjs/config";
|
|
import { TypeOrmModuleOptions } from "@nestjs/typeorm";
|
|
import { DataSourceOptions } from "typeorm";
|
|
|
|
/**
|
|
* Finance migrations are recorded in `finance.migrations`, alongside
|
|
* `iam.typeorm_migrations`, `freight.migrations` and `hr.migrations` in the same
|
|
* database. Each app owns exactly one history table; Finance never writes
|
|
* another app's.
|
|
*/
|
|
export const FINANCE_MIGRATIONS = {
|
|
schema: "finance",
|
|
table: "migrations",
|
|
} as const;
|
|
|
|
/**
|
|
* IAM entity registration.
|
|
*
|
|
* `IamModule` is embedded in this app (the platform pattern: every service takes
|
|
* the IAM package as a dependency and IAM gates each action by the caller's
|
|
* position), so its entities must be on this DataSource.
|
|
*
|
|
* Registered as GLOBS over the two package dists rather than as a hand-written
|
|
* class list — copied from `apps/edr-hr-api/src/config/database.config.ts`,
|
|
* which documents why: freight-api's hand-listed array goes stale on every
|
|
* package bump, and globs cannot.
|
|
*
|
|
* BOTH dists are required. Some IAM entities relate to notification entities
|
|
* that physically live in `@tria-plc/api-common` — the IAM barrel only
|
|
* re-exports them — so registering only the IAM dist throws
|
|
* `Entity metadata for User#sessions was not found` at boot.
|
|
*/
|
|
function resolvePackageDist(pkg: string): string {
|
|
// Node honours each package's `exports` map at runtime even though TypeScript's
|
|
// resolution does not, so require.resolve on the barrel lands in dist/.
|
|
return dirname(require.resolve(pkg)).replace(/\\/g, "/");
|
|
}
|
|
|
|
const IAM_ENTITY_GLOBS = [
|
|
`${resolvePackageDist("@tria-plc/iamapi-common")}/entities/**/*.entity.{ts,js}`,
|
|
`${resolvePackageDist("@tria-plc/api-common")}/entities/**/*.entity.{ts,js}`,
|
|
];
|
|
|
|
function buildConnectionOptions() {
|
|
return {
|
|
type: "postgres" as const,
|
|
host: process.env.DB_HOST ?? "localhost",
|
|
port: parseInt(process.env.DB_PORT ?? "5432", 10),
|
|
username: process.env.DB_USER ?? "edr",
|
|
password: process.env.DB_PASSWORD ?? "edr_secret",
|
|
database: process.env.DB_NAME ?? "edr_database",
|
|
// Do NOT pass `extra.options: '-c search_path=...'` — the connection pooler
|
|
// fronting the dev database rejects the Postgres `options` startup parameter
|
|
// with `08P01`. search_path is applied per physical connection in a pool
|
|
// `connect` handler instead (see app.module.ts).
|
|
synchronize: false,
|
|
logging:
|
|
process.env.TYPEORM_LOGGING === "true"
|
|
? true
|
|
: (["error", "warn"] as DataSourceOptions["logging"]),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Runtime options for the API. Carries no migrations — see `migration:run`.
|
|
*
|
|
* One connection serves both schemas: Finance entities are
|
|
* `@Entity({schema:"finance"})` and IAM's are `schema:"iam"`, so they cannot
|
|
* collide. `autoLoadEntities` is OFF because everything is listed explicitly
|
|
* here — leaving it on lets IamModule's `forFeature` registrations add a PARTIAL
|
|
* entity set, which is the exact configuration that failed at boot in HR.
|
|
*/
|
|
export function buildDataSourceOptions(): DataSourceOptions {
|
|
return {
|
|
...buildConnectionOptions(),
|
|
schema: FINANCE_MIGRATIONS.schema,
|
|
entities: [__dirname + "/../**/*.entity.{ts,js}", ...IAM_ENTITY_GLOBS],
|
|
migrations: [],
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Finance migrations only, recorded in `finance.migrations`.
|
|
*
|
|
* Deliberately no entities: this DataSource exists to run Finance's own DDL.
|
|
* Finance never migrates `iam`, `freight`, `passenger`, `hr` or `edr_payment` —
|
|
* it only ever READS those, and each belongs to its own owner.
|
|
*/
|
|
export function buildFinanceMigrationDataSourceOptions(): DataSourceOptions {
|
|
return {
|
|
...buildConnectionOptions(),
|
|
schema: FINANCE_MIGRATIONS.schema,
|
|
entities: [],
|
|
migrations: [__dirname + "/../migrations/*.js"],
|
|
migrationsTableName: FINANCE_MIGRATIONS.table,
|
|
migrationsTransactionMode: "each",
|
|
};
|
|
}
|
|
|
|
export default registerAs(
|
|
"database",
|
|
(): TypeOrmModuleOptions => ({
|
|
...buildDataSourceOptions(),
|
|
autoLoadEntities: false,
|
|
// Migrations run as a separate one-shot step, never on API boot (house rule).
|
|
migrationsRun: false,
|
|
}),
|
|
);
|