mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 07:22:53 +00:00
Muluhabt ERP modules
This commit is contained in:
110
apps/finance-api/src/config/database.config.ts
Normal file
110
apps/finance-api/src/config/database.config.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
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,
|
||||
}),
|
||||
);
|
||||
Reference in New Issue
Block a user