-
Notifications
You must be signed in to change notification settings - Fork 14
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
#1786 - Enable Search Student for Institutions - part 1 #1857
#1786 - Enable Search Student for Institutions - part 1 #1857
Conversation
@AllowAuthorizedParty(AuthorizedParties.institution) | ||
@Controller("student") | ||
@ApiTags(`${ClientTypeBaseRoute.Institution}-student`) | ||
@Injectable() |
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.
Do we need an injectable 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.
When @Controller
is used, @Injectable
is not required.
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 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 just moved this code, it already this way. Thanks!
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.
@Controller
does not require the @Injectable
because they are not injected anywhere. They were probably added by mistake someday and kept being added. Anyone that finds one can have them removed or create a PR to remove them all.
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 just moved this code, it already this way. Thanks!
I did not get the part that states that this code was "moved". This is a brand-new file, right?
If the file is new and the code was copied, the statement "it already this way" does not seem accurate, IMO.
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 was already that way in the other file, I just moved the code from there to this one. I'm not saying that I should not have changed it and made it right. Sorry!
* @param institutionId institution id. | ||
* @returns whether the institution type is public. | ||
*/ | ||
async isBCPublicInstitution(institutionId: number): Promise<boolean> { |
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.
Just a suggestion, we already have a method to check if the institution is private, which has one reference. Can we just create a single method that return either the institution is INSTITUTION_TYPE_BC_PRIVATE or INSTITUTION_TYPE_BC_PUBLIC?. Thoughts @ann-aot @andrewsignori-aot @sh16011993 @dheepak-aot
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 see the point @guru-aot.
Maybe we could create read-only properties a the entity model that will do the check based on the constants INSTITUTION_TYPE_BC_PRIVATE
and INSTITUTION_TYPE_BC_PUBLIC
.
IMO this is something that can be considered an entity-level concern. Would be like an emulation of a DB computed property.
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 agree that it should just be a entity level concern.
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.
@guru-aot I get what you are saying, but to have a single method returning private or public, we need to have a thrid category to pull all these institution types.
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 get the point team, I was just talking about combining 2 methods and returning a single value either public or private. I guess its going way out of the scope of this PR. Pausing the discussion for now.
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.
@guru-aot I am exactly trying to comprehend your idea. for e.g. if there is a method called checkIfPrivateOrPublic(): Private | Public
, what will it return if the institution type is International? let me know if I am missing somehthing.
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.
@guru-aot feel free to pause the discussion, from your end, please leave the comment open.
@andrepestana-aot I believe that this method will no longer be needed because we will build the decorator in the future.
If it is still needed let's move it to the entity model alongside the isBCPrivate
.
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 removed the method isBCPublicInstitution
.leftJoin("studentAssessment.offering", "offering") | ||
.leftJoin("offering.institutionLocation", "offeringLocation") | ||
.leftJoin("offeringLocation.institution", "offeringInstitution") | ||
|
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.
please remove empty line here and above.
sources/packages/backend/apps/api/src/app.institutions.module.ts
Outdated
Show resolved
Hide resolved
sources/packages/backend/apps/api/src/route-controllers/index.ts
Outdated
Show resolved
Hide resolved
* lastName, appNumber or sin. | ||
* @returns list of students. | ||
*/ | ||
async searchStudentApplicationForInstitution( |
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.
Cant we reuse the existing query searchStudentApplication to use the instituion id as an optional parameter and return?
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 don't like the idea of doing that because it would make a simple thing like a query to a more complex method with conditions that will be harder to maintain. Thoughts @ann-aot @dheepak-aot @andrewsignori-aot @sh16011993 ?
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.
Maybe I am wrong and I did not tested it, but would the change be something about moving the inner/left and one where inside an if like below?
if (institutionId) {
searchQuery
.innerJoin("application.location", "pirLocation")
.innerJoin("pirLocation.institution", "pirInstitution")
.andWhere(
"(offeringInstitution.id = :institutionId or pirInstitution.id = :institutionId)",
{ institutionId },
);
}
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.
Ok. Changed.
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 noticed the if (institutionId)
twice in the method. Was it because the proposed code on the comment didn't work or because it looks cleaner?
sources/packages/backend/apps/api/src/route-controllers/student/models/student.dto.ts
Outdated
Show resolved
Hide resolved
@@ -93,27 +93,27 @@ export class UpdateStudentAPIInDTO | |||
/** | |||
* Student AEST search parameters. |
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.
pls update the comment too
...es/packages/backend/apps/api/src/route-controllers/student/student.institution.controller.ts
Outdated
Show resolved
Hide resolved
StudentSearchAPIInDTO, | ||
SearchStudentAPIOutDTO, | ||
} from "./models/student.dto"; | ||
|
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.
pls remove the extra line
userToken.authorizations.institutionId, | ||
searchCriteria, | ||
); | ||
return searchStudentApplications.map((eachStudent: Student) => ({ |
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.
If AEST and student are sharing the same DTO, the "map" logic can be centralized also on student.controller.service.ts
.
sources/packages/backend/apps/api/src/services/student/student.service.ts
Outdated
Show resolved
Hide resolved
"application.student.id = student.id", | ||
) | ||
|
||
.innerJoin("application.location", "pirLocation") |
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.
Maybe it would be safe to use left join here since we still are not saving the PIR location right on submission.
Even if we start saving, I believe that it would be better to not rely on it using the INNER.
sources/packages/web/src/components/common/SearchStudentsCommon.vue
Outdated
Show resolved
Hide resolved
sources/packages/web/src/components/common/SearchStudentsCommon.vue
Outdated
Show resolved
Hide resolved
|
||
/** | ||
* Search students based on the search criteria. | ||
* TODO add decorator to restrict to BC Public institutions. |
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.
👍
color="primary" | ||
class="p-button-raised" | ||
data-cy="viewStudent" | ||
@click="$emit('goToStudentView', slotProps.data.id)" |
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 an alternate approach because the params are same between both routes, the component can receive a a route prop and do the navigation here.
The benefit it is avoid the emit. <search-students :view-student-route="InstitutionRoutesConst.STUDENT_PROFILE">
Just a suggestion.
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, there are many ways of doing that. I'm following #1857 (review)
"application", | ||
"application.student.id = student.id", | ||
) | ||
.leftJoin("application.location", "pirLocation") |
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.
Are we changing the submit logic to save the location in a different PR?
And if that is going to happen, this whole part can be removed right?
.leftJoin("application.currentAssessment", "studentAssessment")
.leftJoin("studentAssessment.offering", "offering")
.leftJoin("offering.institutionLocation", "offeringLocation")
.leftJoin("offeringLocation.institution", "offeringInstitution");
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, I'm changing the submit logic to save the location in a different PR.
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.
Are we changing the submit logic to save the location in a different PR?
And if that is going to happen, this whole part can be removed right?
.leftJoin("application.currentAssessment", "studentAssessment") .leftJoin("studentAssessment.offering", "offering") .leftJoin("offering.institutionLocation", "offeringLocation") .leftJoin("offeringLocation.institution", "offeringInstitution");
During previous conversations, we had in mind doing both checks, but since we will save the application.location
during the application submission and assuming that the location can only be changed by editing the application, it could be a nice simplification of the query.
Thanks for making the changes. Just one outstanding question. |
export class StudentInstitutionsController extends BaseController { | ||
constructor( | ||
private readonly studentService: StudentService, | ||
private readonly institutionService: InstitutionService, |
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.
Please remove the institutionService
if it is no longer used.
@UserToken() userToken: IInstitutionUserToken, | ||
@Body() searchCriteria: StudentSearchAPIInDTO, | ||
): Promise<SearchStudentAPIOutDTO[]> { | ||
return await this.studentService.searchStudentApplication( |
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.
No need to await.
@UserToken() userToken: IInstitutionUserToken, | ||
@Body() searchCriteria: StudentSearchAPIInDTO, | ||
): Promise<SearchStudentAPIOutDTO[]> { | ||
return await this.studentService.searchStudentApplication( |
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.
Maybe I am missing something but is the service result directly returned through the API?
The results must be converted to a DTO.
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.
Now I see that the service is returning the DTO directly. The services, unless they are controller services, do not return DTO directly. API DTOs are supposed to be a controller concern only, that is why we usually deal with them at controller or service controller only.
birthDate: getISODateOnlyString(eachStudent.birthDate), | ||
sin: eachStudent.sinValidation.sin, | ||
})); | ||
return await this.studentService.searchStudentApplication(searchCriteria); |
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 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.
@andrepestana-aot Looks good to 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.
Thanks for doing the changes. LGTM 👍
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.
LGTM, nice work @andrepestana-aot
sources/packages/backend/apps/api/src/route-controllers/institution/models/institution.dto.ts
Outdated
Show resolved
Hide resolved
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.
Thanks for doing the changes, looks good 👍
Kudos, SonarCloud Quality Gate passed!
|
In this PR
I will create another PR to:
BC Public Institution
Other Institutions