-
Notifications
You must be signed in to change notification settings - Fork 1
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
Conversation
|
||
private certificateIsAnAdr = (): boolean => this.type === CERTIFICATE_DATA.ADR_DATA; | ||
|
||
public initialise(type: CERTIFICATE_DATA, isWelsh = false) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 😬
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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> { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above :)
const adrDetails: TechRecordType<any> = await this.techRecordService.getAdrDetails(testResult); | ||
const makeAndModel = await this.techRecordService.getVehicleMakeAndModel(testResult); |
There was a problem hiding this comment.
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)
]);
There was a problem hiding this comment.
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[] = []; |
There was a problem hiding this comment.
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
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; |
There was a problem hiding this comment.
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
.
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 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. | ||
*/ |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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? 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes no problem, thanks.
Refactor certificate generation into commands
Isolates all the certificate payload generation commands into their own classes for easier extendability and readability.
CB2-12313
Checklist
id
required prepended with"test-"
have been checked with automation testers and added