Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: workspace health #3344

Merged
merged 13 commits into from
Jan 11, 2024
Merged

feat: workspace health #3344

merged 13 commits into from
Jan 11, 2024

Conversation

magrinj
Copy link
Member

@magrinj magrinj commented Jan 10, 2024

Introducing the workspace:health Command

In this PR, we're introducing a new command: workspace:health. This command is designed to assess the health of a specified workspace by examining its metadata and database structure.

Key Features

  • Comprehensive Validation: Ensures each object corresponds to a table, each field aligns with a database column, and all metadata are valid based on their types.
  • Flexible Modes: Offers different levels of checking, including structure, metadata, or both.
  • Verbose Output Option: Provides detailed issue reporting for in-depth analysis.

How It Works

Run this command in your terminal as follows:

$ yarn command workspace:health --workspace-id 20202020-1c25-4d02-bf25-6aeccf7ea419

Customizable Parameters

  • Mode Selection (-m, --mode [all | structure | metadata]):

    • all: Checks both structure and metadata.
    • structure: Focuses on the database table structure based on metadata.
    • metadata: Concentrates on the validity of metadata.
  • Verbose Output (-v, --verbose):

    • When enabled, displays detailed information about all detected issues within the terminal. If not used, only a brief summary message is shown.

Warning

Relations are not yet checked

@magrinj magrinj force-pushed the feat/workspace-health branch 2 times, most recently from 9bc6052 to ad0fd72 Compare January 11, 2024 09:11
@magrinj magrinj marked this pull request as ready for review January 11, 2024 11:14
@magrinj magrinj linked an issue Jan 11, 2024 that may be closed by this pull request
Copy link
Member

@Weiko Weiko left a comment

Choose a reason for hiding this comment

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

That's great! I feel like we will benefit a lot from unit tests for this part but does not have to be in this PR 🙂

message: `Table ${objectMetadata.targetTableName} not found in schema ${schemaName}`,
});

return issues;
Copy link
Member

Choose a reason for hiding this comment

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

Probably unnecessary since we return issues after this condition anyway?

Copy link
Member Author

Choose a reason for hiding this comment

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

It's here in case we add more check after this condition, if table doesn't exist we don't have to check anything else

Copy link
Member

Choose a reason for hiding this comment

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

Alright 👍

return 'now()';
default:
throw new BadRequestException('Invalid dynamic default value type');
const serializedTypeDefaultValue = serializeTypeDefaultValue(defaultValue);
Copy link
Member

Choose a reason for hiding this comment

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

I find the naming a bit confusing because this function is already serialising default value based on their types.
I know why you did that though 😅. Maybe we should have named

{
   type: something
} 

to

{
   strategy: something
}

Anyway, not a big issue, just wanted to mention it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes I agree with that, manipulating it doesn't seems really nice with that name, but it's better to change this in another PR 🙂

import { FieldMetadataEntity } from 'src/metadata/field-metadata/field-metadata.entity';
import { ObjectMetadataEntity } from 'src/metadata/object-metadata/object-metadata.entity';

export enum WorkspaceHealthIssueType {
Copy link
Member

Choose a reason for hiding this comment

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

Great! I can already see us benefiting a lot from this for debugging 💪

defaultValue && 'value' in defaultValue ? defaultValue.value : null;

if (typeof value === 'number') {
return value.toString();
Copy link
Member

Choose a reason for hiding this comment

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

This is because default values are stored as "strings" in DB for numbers?

Copy link
Member Author

Choose a reason for hiding this comment

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

Don't really know if they are stored as string, but in my structure query they are strings

);

if (!workspaceTableColumns) {
throw new NotFoundException(
Copy link
Member

Choose a reason for hiding this comment

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

nit: Not for this PR but we should probably not return httpExceptions in this kind of code. Actually we should probably not throw httpExceptions in services at all. Since we don't have our own Error classes yet I think it's fine for now but just wanted to mention it!

Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure about that, in Nest.JS documentation it's advised to use HttpException for Rest or GraphQL API, we should I guess throw class errors in service and wrap them inside the controller or resolver, but it's going to be a lot verbose 😅

Copy link
Member

Choose a reason for hiding this comment

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

I see. Yes I'm sure we can find a way to make this less verbose though, I find it weird to have HttpExceptions inside commands where http is not exposed. 🤔 Let's discuss this later 👍

}

// Try to connect to the data source
await this.typeORMService.connectToDataSource(dataSourceMetadata);
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need to connect to the workspace datasource here? This is to check if this settings are valid and that we can connect later?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes exactly, it's just to check if the connection to this workspace is working properly

Copy link
Member

@Weiko Weiko left a comment

Choose a reason for hiding this comment

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

LGTM 💪 !

@magrinj magrinj merged commit 5f0c9f6 into main Jan 11, 2024
13 checks passed
@magrinj magrinj deleted the feat/workspace-health branch January 11, 2024 15:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Timebox] feat: workspace health check
3 participants