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

#1910 - Student profile returns SIN #2354

Merged
merged 7 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ describe("StudentInstitutionsController(e2e)-getStudentProfile", () => {
},
disabilityStatus: student.disabilityStatus,
validSin: student.sinValidation.isValidSIN,
sin: student.sinValidation.sin,
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,10 +181,13 @@ export class StudentProfileAPIOutDTO {
contact: ContactInformationAPIOutDTO;
validSin: boolean;
disabilityStatus: DisabilityStatus;
}

export class InstitutionStudentProfileAPIOutDTO extends StudentProfileAPIOutDTO {
sin: string;
}

export class AESTStudentProfileAPIOutDTO extends StudentProfileAPIOutDTO {
export class AESTStudentProfileAPIOutDTO extends InstitutionStudentProfileAPIOutDTO {
hasRestriction: boolean;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,13 +242,18 @@ export class StudentAESTController extends BaseController {
@Param("studentId", ParseIntPipe) studentId: number,
): Promise<AESTStudentProfileAPIOutDTO> {
const [student, studentRestrictions] = await Promise.all([
this.studentControllerService.getStudentProfile(studentId),
this.studentControllerService.getStudentProfile(studentId, {
withSensitiveData: true,
Copy link
Collaborator

Choose a reason for hiding this comment

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

👍

}),
this.studentRestrictionService.getStudentRestrictionsById(studentId, {
onlyActive: true,
}),
]);

return { ...student, hasRestriction: !!studentRestrictions.length };
return {
...student,
hasRestriction: !!studentRestrictions.length,
};
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
StudentProfileAPIOutDTO,
StudentFileDetailsAPIOutDTO,
StudentUploadFileAPIOutDTO,
InstitutionStudentProfileAPIOutDTO,
} from "./models/student.dto";
import { transformAddressDetailsForAddressBlockForm } from "../utils/address-utils";

Expand Down Expand Up @@ -113,14 +114,36 @@ export class StudentControllerService {
* @param studentId student id to retrieve the data.
* @returns student profile details.
*/
async getStudentProfile(studentId: number): Promise<StudentProfileAPIOutDTO> {
async getStudentProfile(studentId: number): Promise<StudentProfileAPIOutDTO>;
/**
* Get the student information that represents the profile.
* @param studentId student id to retrieve the data.
* @param options options:
* - `withSensitiveData` boolean option to return sensitive data such as SIN.
* @returns student profile details.
*/
async getStudentProfile(
studentId: number,
options: { withSensitiveData: true },
): Promise<InstitutionStudentProfileAPIOutDTO>;
/**
* Get the student information that represents the profile.
* @param studentId student id to retrieve the data.
* @param options options:
* - `withSensitiveData` boolean option to return sensitive data such as SIN.
* @returns student profile details.
*/
async getStudentProfile(
studentId: number,
options?: { withSensitiveData: true },
): Promise<StudentProfileAPIOutDTO | InstitutionStudentProfileAPIOutDTO> {
const student = await this.studentService.getStudentById(studentId);
if (!student) {
throw new NotFoundException("Student not found.");
}

const address = student.contactInfo.address ?? ({} as AddressInfo);
return {
const studentProfile = {
firstName: student.user.firstName,
lastName: student.user.lastName,
fullName: getUserFullName(student.user),
Expand All @@ -133,8 +156,12 @@ export class StudentControllerService {
},
disabilityStatus: student.disabilityStatus,
validSin: student.sinValidation.isValidSIN,
sin: student.sinValidation.sin,
};

if (options?.withSensitiveData) {
return { ...studentProfile, sin: student.sinValidation.sin };
}
return studentProfile;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ export class StudentInstitutionsController extends BaseController {
async getStudentProfile(
@Param("studentId", ParseIntPipe) studentId: number,
): Promise<StudentProfileAPIOutDTO> {
return this.studentControllerService.getStudentProfile(studentId);
return this.studentControllerService.getStudentProfile(studentId, {
withSensitiveData: true,
});
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,15 @@
import { onMounted, ref, defineComponent } from "vue";
import { StudentService } from "@/services/StudentService";
import { useFormatters } from "@/composables";
import { StudentProfile } from "@/types";
import { AddressAPIOutDTO } from "@/services/http/dto";
import { StudentProfile } from "@/types";

/**
* Used to combine institution and ministry DTOs and make SIN explicitly mandatory.
*/
interface SharedStudentProfile extends Omit<StudentProfile, "sin"> {
sin: string;
}

export default defineComponent({
props: {
Expand All @@ -109,13 +116,13 @@ export default defineComponent({
},
},
setup(props) {
const studentDetail = ref({} as StudentProfile);
const studentDetail = ref({} as SharedStudentProfile);
const address = ref({} as AddressAPIOutDTO);
const { sinDisplayFormat, emptyStringFiller } = useFormatters();
onMounted(async () => {
studentDetail.value = await StudentService.shared.getStudentProfile(
studentDetail.value = (await StudentService.shared.getStudentProfile(
props.studentId,
);
)) as SharedStudentProfile;
address.value = studentDetail.value.contact.address;
});
return {
Expand Down
12 changes: 8 additions & 4 deletions sources/packages/web/src/services/http/StudentApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {
CreateSINValidationAPIInDTO,
UpdateSINValidationAPIInDTO,
SearchStudentAPIInDTO,
InstitutionStudentProfileAPIOutDTO,
AESTStudentProfileAPIOutDTO,
} from "@/services/http/dto";

export class StudentApi extends HttpBaseClient {
Expand Down Expand Up @@ -45,10 +47,12 @@ export class StudentApi extends HttpBaseClient {
*/
async getStudentProfile(
studentId?: number,
): Promise<StudentProfileAPIOutDTO> {
return this.getCall<StudentProfileAPIOutDTO>(
this.addClientRoot(`student/${studentId ?? ""}`),
);
): Promise<
| StudentProfileAPIOutDTO
| InstitutionStudentProfileAPIOutDTO
| AESTStudentProfileAPIOutDTO
> {
return this.getCall(this.addClientRoot(`student/${studentId ?? ""}`));
}

/**
Expand Down
12 changes: 10 additions & 2 deletions sources/packages/web/src/services/http/dto/Student.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,17 @@ export interface StudentProfileAPIOutDTO {
contact: ContactInformationAPIOutDTO;
validSin: boolean;
disabilityStatus: DisabilityStatus;
sin: string;
sinConsent: boolean;
hasRestriction?: boolean;
}

export interface InstitutionStudentProfileAPIOutDTO
extends StudentProfileAPIOutDTO {
sin: string;
}

export interface AESTStudentProfileAPIOutDTO
extends InstitutionStudentProfileAPIOutDTO {
hasRestriction: boolean;
}

/**
Expand Down
13 changes: 10 additions & 3 deletions sources/packages/web/src/types/contracts/StudentContract.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import {
AddressDetailsFormAPIDTO,
AESTStudentProfileAPIOutDTO,
InstitutionStudentProfileAPIOutDTO,
SINValidationsAPIOutDTO,
StudentProfileAPIOutDTO,
} from "@/services/http/dto";
import { IdentityProviders } from "@/types";

export interface StudentProfile extends StudentProfileAPIOutDTO {
birthDateFormatted: string;
}
export type StudentProfile =
| (
| StudentProfileAPIOutDTO
| InstitutionStudentProfileAPIOutDTO
| AESTStudentProfileAPIOutDTO
) & {
birthDateFormatted: string;
};

/**
* Disability status of student.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ import { onMounted, ref, defineComponent } from "vue";
import { StudentService } from "@/services/StudentService";
import { AESTRoutesConst } from "@/constants/routes/RouteConstants";
import StudentRestrictionChip from "@/components/generic/StudentRestrictionChip.vue";
import { StudentRestrictionStatus, StudentProfile } from "@/types";
import { StudentRestrictionStatus } from "@/types";
import { AESTStudentProfileAPIOutDTO } from "@/services/http/dto";

export default defineComponent({
components: { StudentRestrictionChip },
Expand All @@ -51,7 +52,7 @@ export default defineComponent({
},
},
setup(props) {
const studentDetails = ref({} as StudentProfile);
const studentDetails = ref({} as AESTStudentProfileAPIOutDTO);
const items = ref([
{
label: "Profile",
Expand Down Expand Up @@ -112,9 +113,9 @@ export default defineComponent({
]);

onMounted(async () => {
studentDetails.value = await StudentService.shared.getStudentProfile(
studentDetails.value = (await StudentService.shared.getStudentProfile(
props.studentId,
);
)) as AESTStudentProfileAPIOutDTO;
});

return {
Expand Down