From 9b141b5338a863b09a54f5122b75b35353fec397 Mon Sep 17 00:00:00 2001 From: SoulSniper1212 Date: Tue, 11 Nov 2025 17:04:39 -0500 Subject: [PATCH] fix: resolve issue #715 Signed-off-by: SoulSniper1212 --- .../src/components/global/GoogleAnalytics.tsx | 2 +- .../OffersSubmissionAnalysis.tsx | 2 +- .../router/offers/offers-admin-router.ts | 754 +++++++++--------- .../router/offers/offers-analysis-router.ts | 2 +- .../router/offers/offers-comments-router.ts | 1 - .../offers/offers-user-profile-router.ts | 2 +- ...uestions-question-encounter-user-router.ts | 27 +- .../src/utils/offers/randomNameGenerator.ts | 42 +- .../contents/algorithms/sorting-searching.md | 2 +- 9 files changed, 420 insertions(+), 414 deletions(-) diff --git a/apps/portal/src/components/global/GoogleAnalytics.tsx b/apps/portal/src/components/global/GoogleAnalytics.tsx index 472e31a5..48ca57a3 100644 --- a/apps/portal/src/components/global/GoogleAnalytics.tsx +++ b/apps/portal/src/components/global/GoogleAnalytics.tsx @@ -71,7 +71,7 @@ export default function GoogleAnalytics({ children }: Props) { return () => { router.events.off('routeChangeComplete', handleRouteChange); }; - }, [router.events,]); + }, [router.events]); return ( diff --git a/apps/portal/src/components/offers/offersSubmission/OffersSubmissionAnalysis.tsx b/apps/portal/src/components/offers/offersSubmission/OffersSubmissionAnalysis.tsx index 7e0a7d47..eeae57c7 100644 --- a/apps/portal/src/components/offers/offersSubmission/OffersSubmissionAnalysis.tsx +++ b/apps/portal/src/components/offers/offersSubmission/OffersSubmissionAnalysis.tsx @@ -33,4 +33,4 @@ export default function OffersSubmissionAnalysis({ )} ); -} \ No newline at end of file +} diff --git a/apps/portal/src/server/router/offers/offers-admin-router.ts b/apps/portal/src/server/router/offers/offers-admin-router.ts index 62d57ea4..1ba50eb5 100644 --- a/apps/portal/src/server/router/offers/offers-admin-router.ts +++ b/apps/portal/src/server/router/offers/offers-admin-router.ts @@ -43,449 +43,451 @@ const getYoeRange = (yoeCategory: number | null | undefined) => { : null; // Internship }; -export const offerAdminRouter = createProtectedRouter().query('list', { - input: z.object({ - companyId: z.string().nullish(), - countryId: z.string().nullish(), - currency: z.string().nullish(), - dateEnd: z.date().nullish(), - dateStart: z.date().nullish(), - limit: z.number().positive(), - offset: z.number().nonnegative(), - salaryMax: z.number().nonnegative().nullish(), - salaryMin: z.number().nonnegative().nullish(), - sortBy: z - .string() - .regex(createValidationRegex(Object.keys(sortingKeysMap), '[+-]{1}')) - .nullish(), - title: z.string().nullish(), - yoeCategory: z.number().min(0).max(3).nullish(), - yoeMax: z.number().max(100).nullish(), - yoeMin: z.number().min(0).nullish(), - }), - async resolve({ ctx, input }) { - const userId = ctx.session.user.id; - const adminAccount = await ctx.prisma.offersAdmin.findFirst({ - where: { - userId - } - }) - - if (!adminAccount) { - throw new TRPCError({ - code: 'UNAUTHORIZED', - message: 'Not an admin.', +export const offerAdminRouter = createProtectedRouter() + .query('list', { + input: z.object({ + companyId: z.string().nullish(), + countryId: z.string().nullish(), + currency: z.string().nullish(), + dateEnd: z.date().nullish(), + dateStart: z.date().nullish(), + limit: z.number().positive(), + offset: z.number().nonnegative(), + salaryMax: z.number().nonnegative().nullish(), + salaryMin: z.number().nonnegative().nullish(), + sortBy: z + .string() + .regex(createValidationRegex(Object.keys(sortingKeysMap), '[+-]{1}')) + .nullish(), + title: z.string().nullish(), + yoeCategory: z.number().min(0).max(3).nullish(), + yoeMax: z.number().max(100).nullish(), + yoeMin: z.number().min(0).nullish(), + }), + async resolve({ ctx, input }) { + const userId = ctx.session.user.id; + const adminAccount = await ctx.prisma.offersAdmin.findFirst({ + where: { + userId, + }, }); - } - const yoeRange = getYoeRange(input.yoeCategory); - const yoeMin = input.yoeMin != null ? input.yoeMin : yoeRange?.minYoe; - const yoeMax = input.yoeMax != null ? input.yoeMax : yoeRange?.maxYoe; + if (!adminAccount) { + throw new TRPCError({ + code: 'UNAUTHORIZED', + message: 'Not an admin.', + }); + } - if (!input.sortBy) { - input.sortBy = '-' + sortingKeysMap.monthYearReceived; - } + const yoeRange = getYoeRange(input.yoeCategory); + const yoeMin = input.yoeMin != null ? input.yoeMin : yoeRange?.minYoe; + const yoeMax = input.yoeMax != null ? input.yoeMax : yoeRange?.maxYoe; - const order = getOrder(input.sortBy.charAt(0)); - const sortingKey = input.sortBy.substring(1); + if (!input.sortBy) { + input.sortBy = '-' + sortingKeysMap.monthYearReceived; + } + + const order = getOrder(input.sortBy.charAt(0)); + const sortingKey = input.sortBy.substring(1); - const data = !yoeRange - ? await ctx.prisma.offersOffer.findMany({ - // Internship - include: { - company: true, - location: { - include: { - state: { - include: { - country: true, + const data = !yoeRange + ? await ctx.prisma.offersOffer.findMany({ + // Internship + include: { + company: true, + location: { + include: { + state: { + include: { + country: true, + }, }, }, }, - }, - offersFullTime: { - include: { - baseSalary: true, - bonus: true, - stocks: true, - totalCompensation: true, + offersFullTime: { + include: { + baseSalary: true, + bonus: true, + stocks: true, + totalCompensation: true, + }, }, - }, - offersIntern: { - include: { - monthlySalary: true, + offersIntern: { + include: { + monthlySalary: true, + }, }, - }, - profile: { - include: { - background: true, - offers: true, + profile: { + include: { + background: true, + offers: true, + }, }, }, - }, - orderBy: - sortingKey === sortingKeysMap.monthYearReceived - ? { - monthYearReceived: order, - } - : sortingKey === sortingKeysMap.totalCompensation - ? [ - { - offersIntern: { - monthlySalary: { - baseValue: order, + orderBy: + sortingKey === sortingKeysMap.monthYearReceived + ? { + monthYearReceived: order, + } + : sortingKey === sortingKeysMap.totalCompensation + ? [ + { + offersIntern: { + monthlySalary: { + baseValue: order, + }, }, }, - }, - { - monthYearReceived: 'desc', - }, - ] - : sortingKey === sortingKeysMap.totalYoe - ? [ - { - profile: { - background: { - totalYoe: order, + { + monthYearReceived: 'desc', + }, + ] + : sortingKey === sortingKeysMap.totalYoe + ? [ + { + profile: { + background: { + totalYoe: order, + }, }, }, - }, - { - monthYearReceived: 'desc', - }, - ] - : sortingKey === sortingKeysMap.companyName - ? [ - { - company: { - name: order, + { + monthYearReceived: 'desc', }, - }, - { - monthYearReceived: 'desc', - }, - ] - : sortingKey === sortingKeysMap.jobTitle - ? [ - { - offersIntern: { - title: order, + ] + : sortingKey === sortingKeysMap.companyName + ? [ + { + company: { + name: order, + }, + }, + { + monthYearReceived: 'desc', + }, + ] + : sortingKey === sortingKeysMap.jobTitle + ? [ + { + offersIntern: { + title: order, + }, + }, + { + monthYearReceived: 'desc', + }, + ] + : { monthYearReceived: 'desc' }, + where: { + AND: [ + { + location: { + state: { + countryId: + input.countryId != null && input.countryId.length !== 0 + ? input.countryId + : undefined, }, }, - { - monthYearReceived: 'desc', + }, + { + offersIntern: { + isNot: null, }, - ] - : { monthYearReceived: 'desc' }, - where: { - AND: [ - { - location: { - state: { - countryId: - input.countryId != null && input.countryId.length !== 0 - ? input.countryId + }, + { + offersIntern: { + title: + input.title != null && input.title.length !== 0 + ? input.title : undefined, }, }, - }, - { - offersIntern: { - isNot: null, + { + offersIntern: { + monthlySalary: { + baseValue: { + gte: input.salaryMin ?? undefined, + lte: input.salaryMax ?? undefined, + }, + }, + }, }, - }, - { - offersIntern: { - title: - input.title != null && input.title.length !== 0 - ? input.title + { + offersFullTime: { + is: null, + }, + }, + { + companyId: + input.companyId && input.companyId.length !== 0 + ? input.companyId : undefined, }, - }, - { - offersIntern: { - monthlySalary: { - baseValue: { - gte: input.salaryMin ?? undefined, - lte: input.salaryMax ?? undefined, + { + profile: { + background: { + totalYoe: { + gte: yoeMin, + lte: yoeMax, + }, }, }, }, - }, - { - offersFullTime: { - is: null, + { + monthYearReceived: { + gte: input.dateStart ?? undefined, + lte: input.dateEnd ?? undefined, + }, }, - }, - { - companyId: - input.companyId && input.companyId.length !== 0 - ? input.companyId - : undefined, - }, - { - profile: { - background: { - totalYoe: { - gte: yoeMin, - lte: yoeMax, + ], + }, + }) + : await ctx.prisma.offersOffer.findMany({ + // Junior, Mid, Senior + include: { + company: true, + location: { + include: { + state: { + include: { + country: true, }, }, }, }, - { - monthYearReceived: { - gte: input.dateStart ?? undefined, - lte: input.dateEnd ?? undefined, + offersFullTime: { + include: { + baseSalary: true, + bonus: true, + stocks: true, + totalCompensation: true, }, }, - ], - }, - }) - : await ctx.prisma.offersOffer.findMany({ - // Junior, Mid, Senior - include: { - company: true, - location: { - include: { - state: { - include: { - country: true, - }, + offersIntern: { + include: { + monthlySalary: true, }, }, - }, - offersFullTime: { - include: { - baseSalary: true, - bonus: true, - stocks: true, - totalCompensation: true, - }, - }, - offersIntern: { - include: { - monthlySalary: true, - }, - }, - profile: { - include: { - background: true, - offers: true, + profile: { + include: { + background: true, + offers: true, + }, }, }, - }, - orderBy: - sortingKey === sortingKeysMap.monthYearReceived - ? { - monthYearReceived: order, - } - : sortingKey === sortingKeysMap.totalCompensation - ? [ - { - offersFullTime: { - totalCompensation: { - baseValue: order, + orderBy: + sortingKey === sortingKeysMap.monthYearReceived + ? { + monthYearReceived: order, + } + : sortingKey === sortingKeysMap.totalCompensation + ? [ + { + offersFullTime: { + totalCompensation: { + baseValue: order, + }, }, }, - }, - { - monthYearReceived: 'desc', - }, - ] - : sortingKey === sortingKeysMap.totalYoe - ? [ - { - profile: { - background: { - totalYoe: order, + { + monthYearReceived: 'desc', + }, + ] + : sortingKey === sortingKeysMap.totalYoe + ? [ + { + profile: { + background: { + totalYoe: order, + }, }, }, - }, - { - monthYearReceived: 'desc', - }, - ] - : sortingKey === sortingKeysMap.companyName - ? [ - { - company: { - name: order, + { + monthYearReceived: 'desc', }, - }, - { - monthYearReceived: 'desc', - }, - ] - : sortingKey === sortingKeysMap.jobTitle - ? [ - { - offersFullTime: { - title: order, + ] + : sortingKey === sortingKeysMap.companyName + ? [ + { + company: { + name: order, + }, + }, + { + monthYearReceived: 'desc', + }, + ] + : sortingKey === sortingKeysMap.jobTitle + ? [ + { + offersFullTime: { + title: order, + }, + }, + { + monthYearReceived: 'desc', + }, + ] + : { monthYearReceived: 'desc' }, + where: { + AND: [ + { + location: { + state: { + countryId: + input.countryId != null && input.countryId.length !== 0 + ? input.countryId + : undefined, }, }, - { - monthYearReceived: 'desc', + }, + { + offersIntern: { + is: null, }, - ] - : { monthYearReceived: 'desc' }, - where: { - AND: [ - { - location: { - state: { - countryId: - input.countryId != null && input.countryId.length !== 0 - ? input.countryId - : undefined, + }, + { + offersFullTime: { + isNot: null, }, }, - }, - { - offersIntern: { - is: null, + { + offersFullTime: { + title: + input.title != null && input.title.length !== 0 + ? input.title + : undefined, + }, }, - }, - { - offersFullTime: { - isNot: null, + { + offersFullTime: { + totalCompensation: { + baseValue: { + gte: input.salaryMin ?? undefined, + lte: input.salaryMax ?? undefined, + }, + }, + }, }, - }, - { - offersFullTime: { - title: - input.title != null && input.title.length !== 0 - ? input.title + { + companyId: + input.companyId && input.companyId.length !== 0 + ? input.companyId : undefined, }, - }, - { - offersFullTime: { - totalCompensation: { - baseValue: { - gte: input.salaryMin ?? undefined, - lte: input.salaryMax ?? undefined, + { + profile: { + background: { + totalYoe: { + gte: yoeMin, + lte: yoeMax, + }, }, }, }, - }, - { - companyId: - input.companyId && input.companyId.length !== 0 - ? input.companyId - : undefined, - }, - { - profile: { - background: { - totalYoe: { - gte: yoeMin, - lte: yoeMax, - }, + { + monthYearReceived: { + gte: input.dateStart ?? undefined, + lte: input.dateEnd ?? undefined, }, }, - }, - { - monthYearReceived: { - gte: input.dateStart ?? undefined, - lte: input.dateEnd ?? undefined, - }, - }, - ], - }, - }); + ], + }, + }); - const startRecordIndex: number = input.limit * input.offset; - const endRecordIndex: number = - startRecordIndex + input.limit <= data.length - ? startRecordIndex + input.limit - : data.length; - let paginatedData = data.slice(startRecordIndex, endRecordIndex); + const startRecordIndex: number = input.limit * input.offset; + const endRecordIndex: number = + startRecordIndex + input.limit <= data.length + ? startRecordIndex + input.limit + : data.length; + let paginatedData = data.slice(startRecordIndex, endRecordIndex); - // CONVERTING - const currency = input.currency?.toUpperCase(); - if (currency != null && currency in Currency) { - paginatedData = await Promise.all( - paginatedData.map(async (offer) => { - if (offer.offersFullTime?.totalCompensation != null) { - offer.offersFullTime.totalCompensation.value = - await convertWithDate( - offer.offersFullTime.totalCompensation.value, - offer.offersFullTime.totalCompensation.currency, - currency, - offer.offersFullTime.totalCompensation.updatedAt, - ); - offer.offersFullTime.totalCompensation.currency = currency; + // CONVERTING + const currency = input.currency?.toUpperCase(); + if (currency != null && currency in Currency) { + paginatedData = await Promise.all( + paginatedData.map(async (offer) => { + if (offer.offersFullTime?.totalCompensation != null) { + offer.offersFullTime.totalCompensation.value = + await convertWithDate( + offer.offersFullTime.totalCompensation.value, + offer.offersFullTime.totalCompensation.currency, + currency, + offer.offersFullTime.totalCompensation.updatedAt, + ); + offer.offersFullTime.totalCompensation.currency = currency; - if (offer.offersFullTime?.baseSalary != null) { - offer.offersFullTime.baseSalary.value = await convertWithDate( - offer.offersFullTime.baseSalary.value, - offer.offersFullTime.baseSalary.currency, - currency, - offer.offersFullTime.baseSalary.updatedAt, - ); - offer.offersFullTime.baseSalary.currency = currency; - } + if (offer.offersFullTime?.baseSalary != null) { + offer.offersFullTime.baseSalary.value = await convertWithDate( + offer.offersFullTime.baseSalary.value, + offer.offersFullTime.baseSalary.currency, + currency, + offer.offersFullTime.baseSalary.updatedAt, + ); + offer.offersFullTime.baseSalary.currency = currency; + } - if (offer.offersFullTime?.stocks != null) { - offer.offersFullTime.stocks.value = await convertWithDate( - offer.offersFullTime.stocks.value, - offer.offersFullTime.stocks.currency, - currency, - offer.offersFullTime.stocks.updatedAt, - ); - offer.offersFullTime.stocks.currency = currency; - } + if (offer.offersFullTime?.stocks != null) { + offer.offersFullTime.stocks.value = await convertWithDate( + offer.offersFullTime.stocks.value, + offer.offersFullTime.stocks.currency, + currency, + offer.offersFullTime.stocks.updatedAt, + ); + offer.offersFullTime.stocks.currency = currency; + } - if (offer.offersFullTime?.bonus != null) { - offer.offersFullTime.bonus.value = await convertWithDate( - offer.offersFullTime.bonus.value, - offer.offersFullTime.bonus.currency, + if (offer.offersFullTime?.bonus != null) { + offer.offersFullTime.bonus.value = await convertWithDate( + offer.offersFullTime.bonus.value, + offer.offersFullTime.bonus.currency, + currency, + offer.offersFullTime.bonus.updatedAt, + ); + offer.offersFullTime.bonus.currency = currency; + } + } else if (offer.offersIntern?.monthlySalary != null) { + offer.offersIntern.monthlySalary.value = await convertWithDate( + offer.offersIntern.monthlySalary.value, + offer.offersIntern.monthlySalary.currency, currency, - offer.offersFullTime.bonus.updatedAt, + offer.offersIntern.monthlySalary.updatedAt, ); - offer.offersFullTime.bonus.currency = currency; + offer.offersIntern.monthlySalary.currency = currency; + } else { + throw new TRPCError({ + code: 'NOT_FOUND', + message: 'Total Compensation or Salary not found', + }); } - } else if (offer.offersIntern?.monthlySalary != null) { - offer.offersIntern.monthlySalary.value = await convertWithDate( - offer.offersIntern.monthlySalary.value, - offer.offersIntern.monthlySalary.currency, - currency, - offer.offersIntern.monthlySalary.updatedAt, - ); - offer.offersIntern.monthlySalary.currency = currency; - } else { - throw new TRPCError({ - code: 'NOT_FOUND', - message: 'Total Compensation or Salary not found', - }); - } - - return offer; - }), - ); - } - return getAdminOffersResponseMapper( - paginatedData.map((offer) => adminDashboardOfferDtoMapper(offer)), - { - currentPage: input.offset, - numOfItems: paginatedData.length, - numOfPages: Math.ceil(data.length / input.limit), - totalItems: data.length, - }, - !yoeRange ? JobType.INTERN : JobType.FULLTIME, - ); - }, -}).query('isAdmin', { - async resolve({ ctx }) { - const userId = ctx.session.user.id; - const result = await ctx.prisma.offersAdmin.findFirst({ - where: { - userId + return offer; + }), + ); } - }) - return result ? true : false - } -}); + return getAdminOffersResponseMapper( + paginatedData.map((offer) => adminDashboardOfferDtoMapper(offer)), + { + currentPage: input.offset, + numOfItems: paginatedData.length, + numOfPages: Math.ceil(data.length / input.limit), + totalItems: data.length, + }, + !yoeRange ? JobType.INTERN : JobType.FULLTIME, + ); + }, + }) + .query('isAdmin', { + async resolve({ ctx }) { + const userId = ctx.session.user.id; + const result = await ctx.prisma.offersAdmin.findFirst({ + where: { + userId, + }, + }); + + return result ? true : false; + }, + }); diff --git a/apps/portal/src/server/router/offers/offers-analysis-router.ts b/apps/portal/src/server/router/offers/offers-analysis-router.ts index 5850fee3..b1e0def8 100644 --- a/apps/portal/src/server/router/offers/offers-analysis-router.ts +++ b/apps/portal/src/server/router/offers/offers-analysis-router.ts @@ -37,4 +37,4 @@ export const offersAnalysisRouter = createRouter() async resolve({ ctx, input }) { return generateAnalysis({ ctx, input }); }, - }); \ No newline at end of file + }); diff --git a/apps/portal/src/server/router/offers/offers-comments-router.ts b/apps/portal/src/server/router/offers/offers-comments-router.ts index 73f0db82..9fff8034 100644 --- a/apps/portal/src/server/router/offers/offers-comments-router.ts +++ b/apps/portal/src/server/router/offers/offers-comments-router.ts @@ -320,7 +320,6 @@ export const offersCommentsRouter = createRouter() id: input.profileId, }, }); - } else { throw new trpc.TRPCError({ code: 'UNAUTHORIZED', diff --git a/apps/portal/src/server/router/offers/offers-user-profile-router.ts b/apps/portal/src/server/router/offers/offers-user-profile-router.ts index 826e76f9..ae816261 100644 --- a/apps/portal/src/server/router/offers/offers-user-profile-router.ts +++ b/apps/portal/src/server/router/offers/offers-user-profile-router.ts @@ -138,4 +138,4 @@ export const offersUserProfileRouter = createProtectedRouter() }, }); }, - }); \ No newline at end of file + }); diff --git a/apps/portal/src/server/router/questions/questions-question-encounter-user-router.ts b/apps/portal/src/server/router/questions/questions-question-encounter-user-router.ts index 6a78dc14..e34e166c 100644 --- a/apps/portal/src/server/router/questions/questions-question-encounter-user-router.ts +++ b/apps/portal/src/server/router/questions/questions-question-encounter-user-router.ts @@ -41,12 +41,13 @@ export const questionsQuestionEncounterUserRouter = createProtectedRouter() }); } - await tx.questionsQuestion.update({ data: { - lastSeenAt: (questionToUpdate.lastSeenAt === null || - questionToUpdate.lastSeenAt < input.seenAt) - ? input.seenAt : undefined, + lastSeenAt: + questionToUpdate.lastSeenAt === null || + questionToUpdate.lastSeenAt < input.seenAt + ? input.seenAt + : undefined, numEncounters: { increment: 1, }, @@ -179,16 +180,16 @@ export const questionsQuestionEncounterUserRouter = createProtectedRouter() } await tx.questionsQuestion.update({ - data: { - lastSeenAt: lastSeenVal, - numEncounters: { - increment: -1, - }, - }, - where: { - id: questionToUpdate!.id, + data: { + lastSeenAt: lastSeenVal, + numEncounters: { + increment: -1, }, - }); + }, + where: { + id: questionToUpdate!.id, + }, + }); return questionEncounterDeleted; }); diff --git a/apps/portal/src/utils/offers/randomNameGenerator.ts b/apps/portal/src/utils/offers/randomNameGenerator.ts index ff02e503..3a7754bc 100644 --- a/apps/portal/src/utils/offers/randomNameGenerator.ts +++ b/apps/portal/src/utils/offers/randomNameGenerator.ts @@ -1,8 +1,13 @@ import type { Config } from 'unique-names-generator'; -import { adjectives, animals,colors, uniqueNamesGenerator } from 'unique-names-generator'; +import { + adjectives, + animals, + colors, + uniqueNamesGenerator, +} from 'unique-names-generator'; import { PrismaClient } from '@prisma/client'; -const prisma = new PrismaClient() +const prisma = new PrismaClient(); const customConfig: Config = { dictionaries: [adjectives, colors, animals], @@ -10,24 +15,23 @@ const customConfig: Config = { separator: '-', }; - export default async function generateRandomName(): Promise { - let uniqueName: string = uniqueNamesGenerator(customConfig); + let uniqueName: string = uniqueNamesGenerator(customConfig); - let sameNameProfiles = await prisma.offersProfile.findMany({ - where: { - profileName: uniqueName - } - }) + let sameNameProfiles = await prisma.offersProfile.findMany({ + where: { + profileName: uniqueName, + }, + }); - while (sameNameProfiles.length !== 0) { - uniqueName = uniqueNamesGenerator(customConfig); - sameNameProfiles = await prisma.offersProfile.findMany({ - where: { - profileName: uniqueName - } - }) - } + while (sameNameProfiles.length !== 0) { + uniqueName = uniqueNamesGenerator(customConfig); + sameNameProfiles = await prisma.offersProfile.findMany({ + where: { + profileName: uniqueName, + }, + }); + } - return uniqueName -} \ No newline at end of file + return uniqueName; +} diff --git a/apps/website/contents/algorithms/sorting-searching.md b/apps/website/contents/algorithms/sorting-searching.md index e67c8187..df0978b9 100644 --- a/apps/website/contents/algorithms/sorting-searching.md +++ b/apps/website/contents/algorithms/sorting-searching.md @@ -71,7 +71,7 @@ While you're unlikely to be asked to implement a sorting algorithm from scratch ## Things to look out for during interviews -Make sure you know the time and space complexity of the language's default sorting algorithm! The time complexity is almost definitely O(nlog(n))). Bonus points if you can name the sort. In Python, it's [Timsort](https://en.wikipedia.org/wiki/Timsort). In Java, [an implementation of Timsort](https://github.com/openjdk/jdk/blob/d9052b946682d1c0f2629455d73fe4e6b95b29db/src/java.base/share/classes/java/util/TimSort.java) is used for sorting objects, and [Dual-Pivot Quicksort](https://github.com/openjdk/jdk/blob/d9052b946682d1c0f2629455d73fe4e6b95b29db/src/java.base/share/classes/java/util/DualPivotQuicksort.java) is used for sorting primitives. +Make sure you know the time and space complexity of the language's default sorting algorithm! The time complexity is almost definitely O(n log n). Bonus points if you can name the sort. In Python 3.11+, it's [Powersort](https://www.wild-inter.net/posts/powersort-in-python-3.11), which replaced Timsort as the default sorting algorithm. In Java, [an implementation of Timsort](https://github.com/openjdk/jdk/blob/d9052b946682d1c0f2629455d73fe4e6b95b29db/src/java.base/share/classes/java/util/TimSort.java) is used for sorting objects, and [Dual-Pivot Quicksort](https://github.com/openjdk/jdk/blob/d9052b946682d1c0f2629455d73fe4e6b95b29db/src/java.base/share/classes/java/util/DualPivotQuicksort.java) is used for sorting primitives. ## Corner cases