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

feature/CB2-12313: Refactor certificate generation into commands #193

Merged
merged 7 commits into from
Oct 11, 2024

Conversation

me-matt
Copy link
Contributor

@me-matt me-matt commented Oct 7, 2024

Refactor certificate generation into commands

Isolates all the certificate payload generation commands into their own classes for easier extendability and readability.

CB2-12313

Checklist

  • Branch is rebased against the latest develop/common
  • Necessary id required prepended with "test-" have been checked with automation testers and added
  • Code and UI has been tested manually after the additional changes
  • PR title includes the JIRA ticket number
  • Squashed commits contain the JIRA ticket number
  • Link to the PR added to the repo
  • Delete branch after merge


private certificateIsAnAdr = (): boolean => this.type === CERTIFICATE_DATA.ADR_DATA;

public initialise(type: CERTIFICATE_DATA, isWelsh = false) {
Copy link
Contributor

Choose a reason for hiding this comment

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

is welsh isn't being used in a lot of these commands, can they be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So isWelsh is used by some of the commands and so it exists on the initialise for them all to maintain the same interface. We want this because....take a look at how we iterate the collection in

this.commands.forEach((cmd) => cmd.initialise(type, isWelsh));
.

If we remove isWelsh for some of the commands we would need to individually initialise / generate each certificate command which isn't particularly DRY, especially when I feel it's a reasonable assertion that isWelsh may be used across those commands in the future. yk?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thinking about this a bit more, it's fairly typical here to use a StageBag for injecting params...we could refactor that way. It wouldn't have any real functional difference, but would probably read more cleanly...which is really the intended outcome here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So I have introduced the state bag pattern and refactored the commands to use a base abstract class to make each command more DRY.

Copy link
Contributor

Choose a reason for hiding this comment

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

Am i right in thinking, that these commands are a way of busting out what was in the certificate service?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, basically. We want to adhere to the SOLID princples. So each command becomes it's own isolated unit of code to maintain / extend.

Each command becomes easier to parse and extend, in addition the certificate service becomes easier to parse.

In the future we might want to apply a decorator to some of these commands, but again I'm just trying to limit the structural changes here.

* @param flattenedDefects - the list of flattened defects after being retrieved from the defect service
* @param isWelsh - determines whether the atf in which the test result was conducted resides in Wales
*/
private generateDefects(
Copy link
Contributor

Choose a reason for hiding this comment

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

In the current develop even though this code is near enough identical, it seems to be implicit that it is an async function. But for some reason it no longer seems to be picking that up with this change, so the linting is coming up with Redundant 'await' for a non-promise type on line 63 for me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had this when using eslint. Is your linting running biome?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This function is a hot mess tbh, with the mix of by ref / by val params and lack of typings 😬

Copy link
Contributor

Choose a reason for hiding this comment

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

Strange, yes I am using Biome for this repo with ESLint disabled.

Choose a reason for hiding this comment

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

There is also a tslint.json in this repo which is causing issues in my IDE - it might be the right time to strip that out!


public generate(testResult: ITestResult): Promise<ICertificatePayload> {
if (!this.certificateIsAnIva()) {
return Promise.resolve({} as ICertificatePayload);
Copy link
Contributor

Choose a reason for hiding this comment

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

For consistency is it possible to make this generate method async please, removing the need for the Promise.resolve() wrapper in this return and the return on line 51.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah I believe I had it this way because of the same linting reason you mentioned above.

Good spot, I'll update now 🙏

this.type = type;
}

public generate(testResult: ITestResult): Promise<ICertificatePayload> {
Copy link
Contributor

Choose a reason for hiding this comment

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

For consistency is it possible to make this generate method async please, removing the need for the Promise.resolve() wrapper in this return and the return on line 44.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same as above :)

Comment on lines 23 to 24
const adrDetails: TechRecordType<any> = await this.techRecordService.getAdrDetails(testResult);
const makeAndModel = await this.techRecordService.getVehicleMakeAndModel(testResult);

Choose a reason for hiding this comment

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

As these appear non dependent, we could optimise this by utilising Promise.all to make these requests in parallel e.g.

const [adrDetails, makeAndModel] = await Promise.all([
  this.techRecordService.getAdrDetails(testResult),
  this.techRecordService.getVehicleMakeAndModel(testResult)
]);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good spot! Will update 👍

private async getPayloadData(testResult: ITestResult, type: CERTIFICATE_DATA): Promise<any> {
const { isWelsh } = this.state;

let defectListFromApi: IDefectParent[] = [];

Choose a reason for hiding this comment

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

It looks like defectListFromApi is only hydrated inside the if statement. Therefore, if we convert it to a const within the if statement, we save creating the variable for non welsh tests and remove the let e.g.

let flattenedDefects: IFlatDefect[] = [];

if (isWelsh) {
  const defectListFromApi = await this.defectRepository.getDefectTranslations();
  flattenedDefects = this.defectService.flattenDefectsFromApi(defectListFromApi);
}

// and so on

Comment on lines 34 to 38
const makeAndModel = await this.techRecordService.getVehicleMakeAndModel(testResult);

const trnRegistration = this.testResultService.isValidForTrn(vehicleType, makeAndModel as any)
? await this.trailerRepository.getTrailerRegistrationObject(testResult.vin, makeAndModel.Make as any)
: undefined;

Choose a reason for hiding this comment

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

Looks as if the makeAndModel keys should always exist based on the types package, so to coerce this, I think we should be able to do

const makeAndModel = await this.techRecordService.getVehicleMakeAndModel(testResult) as Required<IMakeAndModel>;

This means we can remove the casting to any.

@cb-cs
Copy link
Contributor

cb-cs commented Oct 9, 2024

This is just more of a general comment, I can't speak for how big the code was prior to the updates, but I think once the changes have been implemented a good ticket to look at would be minification, as we did with authoriser and logs.

The code is currently sitting at over 50mbs.

@me-matt
Copy link
Contributor Author

me-matt commented Oct 9, 2024

This is just more of a general comment, I can't speak for how big the code was prior to the updates, but I think once the changes have been implemented a good ticket to look at would be minification, as we did with authoriser and logs.

The code is currently sitting at over 50mbs.

Yep, totally agree. There's currently no optimisations in place. I'm expecting tree shaking and minification to be delivered through the repository template improvement.

* Initialises the certificate generation process.
* @param type The type of certificate to generate
* @param isWelsh True if a Welsh certificate should also be generated.
*/
Copy link
Contributor

Choose a reason for hiding this comment

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

Not the end of the world but it looks like this was the doc block prior to the state bag implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll remove this in another PR so we don't have to re-request reviews, if that's ok? 😄

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes no problem, thanks.

@me-matt me-matt merged commit bbea5eb into develop Oct 11, 2024
7 checks passed
@me-matt me-matt deleted the feature/CB2-12313 branch October 11, 2024 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants