refactor(server): take the storage roots from DataPathsService

The data-directory change said Nest classes inject DataPathsService, but
only AdminService did. StorageRegistryService still read the built-in
uploads and backups roots and the scratch dir from module constants
frozen at import, and StorageJobsService read the scratch dir the same
way.

The registry now takes DataPathsService through its constructor (a
hand-built one resolves the same layout), and the jobs service asks the
registry for its temp dir. The plain helper modules keep calling
resolveDataPaths() because they run without a container or are shared
with code that does: config.ts, the database path, index.ts, the logger,
the backup functions and the plugin trees, which the out-of-process
supervisor reads too. The app-config README now lists both sides, and
the nest README, server/CLAUDE.md and the provider's own comment say the
same.
This commit is contained in:
Maurice
2026-10-08 16:18:39 +02:00
parent d1b461a37f
commit fa0e6a3eae
7 changed files with 73 additions and 18 deletions
@@ -22,6 +22,7 @@ import { Readable } from 'node:stream';
import { encrypt_api_key } from '../../../../src/nest/common/crypto/apiKeyCrypto';
import { StorageEventsService } from '../../../../src/nest/storage/storage-events.service';
import { StorageRegistryService } from '../../../../src/nest/storage/storage-registry.service';
import { DataPathsService } from '../../../../src/nest/app-config/data-paths.service';
import { LocalDriver } from '../../../../src/nest/storage/drivers/local.driver';
import { MirrorDriver, type ReplicaFailure } from '../../../../src/nest/storage/drivers/mirror.driver';
import { S3Driver } from '../../../../src/nest/storage/drivers/s3.driver';
@@ -173,6 +174,34 @@ describe('StorageRegistryService defaults', () => {
);
});
it('takes the built-in roots and the scratch dir from the injected DataPathsService', async () => {
const root = makeTmpDir();
const paths = {
...new DataPathsService(),
uploadsDir: path.join(root, 'uploads'),
backupsDir: path.join(root, 'backups'),
tmpDir: path.join(root, 'tmp'),
} as DataPathsService;
const registry = new StorageRegistryService(
await createTestAppSettingsRepo(testDb),
makeEnvStub({}).env,
new StorageEventsService(),
await createTestUnitOfWork(testDb),
(await sharedTestOrm(testDb)).orm,
paths,
);
await registry.onModuleInit();
expect(registry.tempDir()).toBe(paths.tmpDir);
expect(fs.statSync(paths.tmpDir).isDirectory()).toBe(true);
expect(registry.resolve('files').driver.getLocalPath!('files/x.pdf')).toBe(
path.join(fs.realpathSync(paths.uploadsDir), 'files/x.pdf'),
);
expect(registry.resolve('backups').driver.getLocalPath!('backup-1.zip')).toBe(
path.join(fs.realpathSync(paths.backupsDir), 'backup-1.zip'),
);
});
it('a settings row bearing a built-in name replaces it (first-class override)', async () => {
const relocated = makeTmpDir();
const { registry } = await makeRegistry({ uploadsRoot: relocated });