From b658b5e68d32d1c2d5003ebe0f0e579d602957cc Mon Sep 17 00:00:00 2001 From: Maurice Date: Thu, 8 Oct 2026 15:40:22 +0200 Subject: [PATCH] docs(server): say why the admin domain does not import DatabaseBackupModule DatabaseBackupModule stays @Global, but its comment gave a vague reason. The real one is concrete: the backup domain already reaches admin through auth and settings, so importing the module from AdminModule would add a domain cycle that lint:boundaries rejects. The module comment now says that and points at the e2e harness that imports it by hand, and AdminModule notes where its DATABASE_BACKUP comes from. --- server/src/nest/admin/admin.module.ts | 4 ++++ server/src/nest/backup/database-backup.module.ts | 14 +++++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/server/src/nest/admin/admin.module.ts b/server/src/nest/admin/admin.module.ts index 7b55a47b6..5599eb079 100644 --- a/server/src/nest/admin/admin.module.ts +++ b/server/src/nest/admin/admin.module.ts @@ -24,6 +24,10 @@ import { PackingModule } from '../packing/packing.module'; // not @Global, so the import must be explicit. import { PermissionsModule } from '../permissions/permissions.module'; import { AppConfigModule } from '../app-config/app-config.module'; +// AdminService and DemoResetJob inject DATABASE_BACKUP, which the @Global +// DatabaseBackupModule (nest/backup/) provides once BackupModule is in the +// graph. It is not imported here on purpose: see that module for the cycle an +// import would close. import { Users } from '../../db/entities/Users.entity'; import { AuditLog } from '../../db/entities/AuditLog.entity'; import { AppSettings } from '../../db/entities/AppSettings.entity'; diff --git a/server/src/nest/backup/database-backup.module.ts b/server/src/nest/backup/database-backup.module.ts index ddba341b0..51744a92f 100644 --- a/server/src/nest/backup/database-backup.module.ts +++ b/server/src/nest/backup/database-backup.module.ts @@ -7,11 +7,15 @@ import { SqliteDatabaseBackup } from './sqlite-database-backup'; /** * Binds the database backup port (`DATABASE_BACKUP`) to the engine in use. * - * Global because its consumers sit in two domains that must not depend on each - * other: the backup domain itself and the admin domain (the demo reset job and - * the baseline route). They inject the token from the shared database kernel - * and never import this file. `BackupModule` imports it, which is what puts it - * in the application. + * Global because its consumers sit in two domains: the backup domain itself + * and the admin domain (the demo reset job and the baseline route). Admin + * cannot import this file. The backup domain already reaches admin (backup + * imports auth, auth imports settings, settings imports admin), so an + * `admin -> backup` import would close a new domain cycle that + * `lint:boundaries` refuses. Both inject the token from the shared database + * kernel instead. `BackupModule` imports this module, which is what puts it in + * the application; a test harness that mounts `AdminModule` without + * `BackupModule` imports it itself (tests/e2e/admin.e2e.test.ts). */ @Global() @Module({