feat: sync all workspaces (#4353)

This commit is contained in:
Jérémy M 2024-03-07 15:40:09 +01:00 committed by GitHub
parent eabece6918
commit c3a024b047
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 80 additions and 49 deletions

View File

@ -9,6 +9,16 @@ import { kebabCase } from 'src/utils/kebab-case';
export class CommandLogger {
constructor(private readonly className: string) {}
async createSubDirectory(subDirectory: string): Promise<void> {
const path = `./logs/${kebabCase(this.className)}/${subDirectory}`;
if (existsSync(path) === false) {
await fs.mkdir(path, { recursive: true });
}
return;
}
async writeLog(
fileName: string,
data: unknown,

View File

@ -64,4 +64,10 @@ export class WorkspaceService extends TypeOrmQueryService<Workspace> {
return workspace;
}
async getWorkspaceIds() {
return this.workspaceRepository
.find()
.then((workspaces) => workspaces.map((workspace) => workspace.id));
}
}

View File

@ -13,66 +13,70 @@ export class SyncWorkspaceLoggerService {
constructor() {}
async saveLogs(
workspaceId: string,
storage: WorkspaceSyncStorage,
workspaceMigrations: WorkspaceMigrationEntity[],
) {
// Create sub directory
await this.commandLogger.createSubDirectory(workspaceId);
// Save workspace migrations
await this.commandLogger.writeLog(
'workspace-migrations',
`${workspaceId}/workspace-migrations`,
workspaceMigrations,
);
// Save object metadata create collection
await this.commandLogger.writeLog(
'object-metadata-create-collection',
`${workspaceId}/object-metadata-create-collection`,
storage.objectMetadataCreateCollection,
);
// Save object metadata update collection
await this.commandLogger.writeLog(
'object-metadata-update-collection',
`${workspaceId}/object-metadata-update-collection`,
storage.objectMetadataUpdateCollection,
);
// Save object metadata delete collection
await this.commandLogger.writeLog(
'object-metadata-delete-collection',
`${workspaceId}/object-metadata-delete-collection`,
storage.objectMetadataDeleteCollection,
);
// Save field metadata create collection
await this.commandLogger.writeLog(
'field-metadata-create-collection',
`${workspaceId}/field-metadata-create-collection`,
storage.fieldMetadataCreateCollection,
);
// Save field metadata update collection
await this.commandLogger.writeLog(
'field-metadata-update-collection',
`${workspaceId}/field-metadata-update-collection`,
storage.fieldMetadataUpdateCollection,
);
// Save field metadata delete collection
await this.commandLogger.writeLog(
'field-metadata-delete-collection',
`${workspaceId}/field-metadata-delete-collection`,
storage.fieldMetadataDeleteCollection,
);
// Save relation metadata create collection
await this.commandLogger.writeLog(
'relation-metadata-create-collection',
`${workspaceId}/relation-metadata-create-collection`,
storage.relationMetadataCreateCollection,
);
// Save relation metadata update collection
await this.commandLogger.writeLog(
'relation-metadata-update-collection',
`${workspaceId}/relation-metadata-update-collection`,
storage.relationMetadataUpdateCollection,
);
// Save relation metadata delete collection
await this.commandLogger.writeLog(
'relation-metadata-delete-collection',
`${workspaceId}/relation-metadata-delete-collection`,
storage.relationMetadataDeleteCollection,
);
}

View File

@ -5,12 +5,13 @@ import { Command, CommandRunner, Option } from 'nest-commander';
import { DataSourceService } from 'src/metadata/data-source/data-source.service';
import { WorkspaceSyncMetadataService } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.service';
import { WorkspaceHealthService } from 'src/workspace/workspace-health/workspace-health.service';
import { WorkspaceService } from 'src/core/workspace/services/workspace.service';
import { SyncWorkspaceLoggerService } from './services/sync-workspace-logger.service';
// TODO: implement dry-run
interface RunWorkspaceMigrationsOptions {
workspaceId: string;
workspaceId?: string;
dryRun?: boolean;
force?: boolean;
}
@ -27,6 +28,7 @@ export class SyncWorkspaceMetadataCommand extends CommandRunner {
private readonly workspaceHealthService: WorkspaceHealthService,
private readonly dataSourceService: DataSourceService,
private readonly syncWorkspaceLoggerService: SyncWorkspaceLoggerService,
private readonly workspaceService: WorkspaceService,
) {
super();
}
@ -35,56 +37,63 @@ export class SyncWorkspaceMetadataCommand extends CommandRunner {
_passedParam: string[],
options: RunWorkspaceMigrationsOptions,
): Promise<void> {
const issues = await this.workspaceHealthService.healthCheck(
options.workspaceId,
);
const workspaceIds = options.workspaceId
? [options.workspaceId]
: await this.workspaceService.getWorkspaceIds();
// Security: abort if there are issues.
if (issues.length > 0) {
if (!options.force) {
this.logger.error(
`Workspace contains ${issues.length} issues, aborting.`,
for (const workspaceId of workspaceIds) {
const issues = await this.workspaceHealthService.healthCheck(workspaceId);
// Security: abort if there are issues.
if (issues.length > 0) {
if (!options.force) {
this.logger.error(
`Workspace contains ${issues.length} issues, aborting.`,
);
this.logger.log(
'If you want to force the migration, use --force flag',
);
this.logger.log(
'Please use `workspace:health` command to check issues and fix them before running this command.',
);
return;
}
this.logger.warn(
`Workspace contains ${issues.length} issues, sync has been forced.`,
);
this.logger.log('If you want to force the migration, use --force flag');
this.logger.log(
'Please use `workspace:health` command to check issues and fix them before running this command.',
);
return;
}
this.logger.warn(
`Workspace contains ${issues.length} issues, sync has been forced.`,
);
}
const dataSourceMetadata =
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
workspaceId,
);
const dataSourceMetadata =
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
options.workspaceId,
);
const { storage, workspaceMigrations } =
await this.workspaceSyncMetadataService.syncStandardObjectsAndFieldsMetadata(
{
workspaceId,
dataSourceId: dataSourceMetadata.id,
},
{ applyChanges: !options.dryRun },
);
const { storage, workspaceMigrations } =
await this.workspaceSyncMetadataService.syncStandardObjectsAndFieldsMetadata(
{
workspaceId: options.workspaceId,
dataSourceId: dataSourceMetadata.id,
},
{ applyChanges: !options.dryRun },
);
if (options.dryRun) {
await this.syncWorkspaceLoggerService.saveLogs(
storage,
workspaceMigrations,
);
if (options.dryRun) {
await this.syncWorkspaceLoggerService.saveLogs(
workspaceId,
storage,
workspaceMigrations,
);
}
}
}
@Option({
flags: '-w, --workspace-id [workspace_id]',
description: 'workspace id',
required: true,
required: false,
})
parseWorkspaceId(value: string): string {
return value;

View File

@ -3,6 +3,7 @@ import { Module } from '@nestjs/common';
import { DataSourceModule } from 'src/metadata/data-source/data-source.module';
import { WorkspaceSyncMetadataModule } from 'src/workspace/workspace-sync-metadata/workspace-sync-metadata.module';
import { WorkspaceHealthModule } from 'src/workspace/workspace-health/workspace-health.module';
import { WorkspaceModule } from 'src/core/workspace/workspace.module';
import { SyncWorkspaceMetadataCommand } from './sync-workspace-metadata.command';
@ -12,6 +13,7 @@ import { SyncWorkspaceLoggerService } from './services/sync-workspace-logger.ser
imports: [
WorkspaceSyncMetadataModule,
WorkspaceHealthModule,
WorkspaceModule,
DataSourceModule,
],
providers: [SyncWorkspaceMetadataCommand, SyncWorkspaceLoggerService],