Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
13 changes: 11 additions & 2 deletions backend/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import { PassportModule } from '@nestjs/passport';
import { ScheduleModule } from '@nestjs/schedule';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PrometheusModule } from '@willsoto/nestjs-prometheus';
import * as fs from 'node:fs';
import * as path from 'node:path';
import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions';
import accessConfig from './access_config.json';
import { appVersion } from './app-version';
import { AccessModule } from './endpoints/access/access.module';
import { ActionModule } from './endpoints/action/action.module';
Expand Down Expand Up @@ -48,7 +49,15 @@ import { DBDumper } from './services/dbdumper.service';
configuration,
(): {
accessConfig: AccessGroupConfig;
} => ({ accessConfig: accessConfig as AccessGroupConfig }),
} => {
const configPath =
process.env.ACCESS_CONFIG_PATH ??
path.resolve(process.cwd(), 'access_config.json');
const content = fs.readFileSync(configPath, 'utf8');
return {
accessConfig: JSON.parse(content) as AccessGroupConfig,
};

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ConfigModule load callback reads and parses the access config with fs.readFileSync/JSON.parse without any error handling. If the file is missing or malformed, startup will throw a low-level ENOENT / JSON error that’s hard to diagnose. Consider validating existence and wrapping parse errors to throw a clearer message (and optionally use the existing env.ACCESS_CONFIG_PATH getter for consistency).

Suggested change
process.env.ACCESS_CONFIG_PATH ??
path.resolve(process.cwd(), 'access_config.json');
const content = fs.readFileSync(configPath, 'utf8');
return {
accessConfig: JSON.parse(content) as AccessGroupConfig,
};
env.ACCESS_CONFIG_PATH ??
path.resolve(process.cwd(), 'access_config.json');
if (!fs.existsSync(configPath)) {
throw new Error(
`Access config file not found: ${configPath}`,
);
}
let content: string;
try {
content = fs.readFileSync(configPath, 'utf8');
} catch (error) {
const message =
error instanceof Error ? error.message : String(error);
throw new Error(
`Failed to read access config file "${configPath}": ${message}`,
);
}
try {
return {
accessConfig: JSON.parse(content) as AccessGroupConfig,
};
} catch (error) {
const message =
error instanceof Error ? error.message : String(error);
throw new Error(
`Failed to parse access config file "${configPath}" as JSON: ${message}`,
);
}

Copilot uses AI. Check for mistakes.
},
],
}),
TypeOrmModule.forRootAsync({
Expand Down
5 changes: 4 additions & 1 deletion backend/src/services/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ export class AuthService implements OnModuleInit {
}

async onModuleInit(): Promise<void> {
await this.affiliationGroupService.createAccessGroups(this.config);
await this.affiliationGroupService.syncAccessGroups(
this.config,
this.userRepository,
);
Comment on lines +55 to +58

Copilot AI Apr 14, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AuthService.onModuleInit() now calls syncAccessGroups(), which performs potentially heavy DB writes/reads across all users. This makes application startup time/data-plane health dependent on completing a full sync. If this is intended, consider moving to a dedicated bootstrap job with logging/metrics and (at minimum) ensuring it is resilient to partial failures (e.g., wrap and log errors rather than failing module init).

Suggested change
await this.affiliationGroupService.syncAccessGroups(
this.config,
this.userRepository,
);
logger.info('Starting access group sync in background during module initialization');
void this.affiliationGroupService
.syncAccessGroups(this.config, this.userRepository)
.then(() => {
logger.info('Access group sync completed');
})
.catch((error: unknown) => {
logger.error(
'Access group sync failed during module initialization',
error,
);
});

Copilot uses AI. Check for mistakes.
Comment on lines 54 to +58

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 createAccessGroups is redundant before syncAccessGroups

syncAccessGroups already upserts every group from the config in its step 1, so the preceding createAccessGroups call performs duplicate lookups for every configured group. Removing it avoids the unnecessary round-trips.

Prompt To Fix With AI
This is a comment left during a code review.
Path: backend/src/services/auth.service.ts
Line: 54-59

Comment:
**`createAccessGroups` is redundant before `syncAccessGroups`**

`syncAccessGroups` already upserts every group from the config in its step 1, so the preceding `createAccessGroups` call performs duplicate lookups for every configured group. Removing it avoids the unnecessary round-trips.

How can I resolve this? If you propose a fix, please make it concise.

}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
Loading
Loading