Skip to content

Commit

Permalink
feat: apply pr fedback
Browse files Browse the repository at this point in the history
  • Loading branch information
wielopolski committed Sep 12, 2024
1 parent c9027fd commit cab1c0e
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 100 deletions.
8 changes: 6 additions & 2 deletions apps/api/src/categories/categories.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { CategoriesQuery } from "./api/categories.types";
import { CategorySortFields, CategorySortField } from "./schemas/categoryQuery";
import { DatabasePg, Pagination } from "src/common";
import { UserRole, UserRoles } from "src/users/schemas/user-roles";
import { getSortOptions } from "./helpers";
import { getSortOptions } from "src/common/helpers/getSortOptions";

@Injectable()
export class CategoriesService {
Expand Down Expand Up @@ -42,7 +42,11 @@ export class CategoriesService {
.select(selectedColumns)
.from(categories)
.where(filterCondition)
.orderBy(sortOrder(this.getColumnToSortBy(sortedField, isAdmin)));
.orderBy(
sortOrder(
this.getColumnToSortBy(sortedField as CategorySortField, isAdmin),
),
);

const dynamicQuery = queryDB.$dynamic();

Expand Down
10 changes: 0 additions & 10 deletions apps/api/src/categories/helpers/index.ts

This file was deleted.

7 changes: 7 additions & 0 deletions apps/api/src/common/helpers/getSortOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { asc, desc } from "drizzle-orm";
export function getSortOptions<T extends string, K extends string>(sort: T) {
return {
sortOrder: sort.startsWith("-") ? desc : asc,
sortedField: sort.replace(/^-/, "") as K,
};
}
6 changes: 3 additions & 3 deletions apps/api/src/courses/api/courses.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class CoursesController {
return new PaginatedResponse(data);
}

@Get("getStudentCourses")
@Get("get-student-courses")
@Validate({
response: paginatedResponse(allCoursesSchema),
request: [
Expand All @@ -78,7 +78,7 @@ export class CoursesController {
@Query("page") page: number,
@Query("perPage") perPage: number,
@Query("sort") sort: SortCourseFieldsOptions,
@CurrentUser() currentUser: { userId: string },
@CurrentUser("userId") currentUserId: string,
): Promise<PaginatedResponse<AllCoursesResponse>> {
const filters: CoursesFilterSchema = {
title,
Expand All @@ -93,7 +93,7 @@ export class CoursesController {

const data = await this.coursesService.getCoursesForUser(
query,
currentUser.userId,
currentUserId,
);

return new PaginatedResponse(data);
Expand Down
131 changes: 57 additions & 74 deletions apps/api/src/courses/courses.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ import { addPagination, DEFAULT_PAGE_SIZE } from "src/common/pagination";
import { CoursesQuery } from "./api/courses.types";
import { DatabasePg, Pagination } from "src/common";
import { AllCoursesResponse } from "./schemas/course.schema";
import { CourseSortField, CourseSortFields } from "./schemas/courseQuery";
import { getSortOptions } from "./helpers";
import {
CoursesFilterSchema,
CourseSortField,
CourseSortFields,
} from "./schemas/courseQuery";
import {
categories,
courseLessons,
courses,
studentCourses,
users,
} from "../storage/schema";
import { getSortOptions } from "src/common/helpers/getSortOptions";

@Injectable()
export class CoursesService {
Expand All @@ -29,43 +33,11 @@ export class CoursesService {
} = query;

const { sortOrder, sortedField } = getSortOptions(sort);

const selectedColumns = {
id: courses.id,
creationDate: courses.createdAt,
title: courses.title,
imageUrl: courses.imageUrl,
author: sql<string>`CONCAT(${users.firstName} || ' ' || ${users.lastName})`,
category: categories.title,
courseLessonCount: sql<number>`(SELECT COUNT(*) FROM ${courseLessons} WHERE ${courseLessons.courseId} = ${courses.id})::INTEGER`,
enrolledParticipantCount: count(studentCourses.courseId),
};
const conditions = this.getFiltersConditions(filters);

return this.db.transaction(async (tx) => {
const conditions = [eq(courses.state, "published")];

if (filters.title) {
conditions.push(
like(categories.title, `%${filters.title.toLowerCase()}%`),
);
}
if (filters.category) {
conditions.push(like(categories.title, `%${filters.category}%`));
}
if (filters.author) {
const authorNameConcat = `${users.firstName} || ' ' || ${users.lastName}`;
conditions.push(sql`${authorNameConcat} LIKE ${`%${filters.author}%`}`);
}
if (filters.creationDateRange) {
const [startDate, endDate] = filters.creationDateRange;
const start = new Date(startDate).toISOString();
const end = new Date(endDate).toISOString();

conditions.push(between(courses.createdAt, start, end));
}

const queryDB = tx
.select(selectedColumns)
.select(this.getSelectFiled())
.from(courses)
.leftJoin(users, eq(courses.authorId, users.id))
.innerJoin(categories, eq(courses.categoryId, categories.id))
Expand All @@ -80,10 +52,14 @@ export class CoursesService {
users.lastName,
categories.title,
)
.orderBy(sortOrder(this.getColumnToSortBy(sortedField)));
.orderBy(
sortOrder(this.getColumnToSortBy(sortedField as CourseSortField)),
);

const dynamicQuery = queryDB.$dynamic();
const paginatedQuery = addPagination(dynamicQuery, page, perPage);
const data = await paginatedQuery;

const [totalItems] = await tx
.select({ count: count() })
.from(courses)
Expand Down Expand Up @@ -125,45 +101,12 @@ export class CoursesService {

const { sortOrder, sortedField } = getSortOptions(sort);

const selectedColumns = {
id: courses.id,
creationDate: courses.createdAt,
title: courses.title,
imageUrl: courses.imageUrl,
author: sql<string>`CONCAT(${users.firstName} || ' ' || ${users.lastName})`,
category: categories.title,
courseLessonCount: sql<number>`(SELECT COUNT(*) FROM ${courseLessons} WHERE ${courseLessons.courseId} = ${courses.id})::INTEGER`,
enrolledParticipantCount: count(studentCourses.courseId),
};

return this.db.transaction(async (tx) => {
const conditions = [
eq(courses.state, "published"),
eq(studentCourses.studentId, userId),
];

if (filters.title) {
conditions.push(
like(categories.title, `%${filters.title.toLowerCase()}%`),
);
}
if (filters.category) {
conditions.push(like(categories.title, `%${filters.category}%`));
}
if (filters.author) {
const authorNameConcat = `${users.firstName} || ' ' || ${users.lastName}`;
conditions.push(sql`${authorNameConcat} LIKE ${`%${filters.author}%`}`);
}
if (filters.creationDateRange) {
const [startDate, endDate] = filters.creationDateRange;
const start = new Date(startDate).toISOString();
const end = new Date(endDate).toISOString();

conditions.push(between(courses.createdAt, start, end));
}
const conditions = [eq(studentCourses.studentId, userId)];
conditions.push(...this.getFiltersConditions(filters));

const queryDB = tx
.select(selectedColumns)
.select(this.getSelectFiled())
.from(studentCourses)
.innerJoin(courses, eq(studentCourses.courseId, courses.id))
.innerJoin(categories, eq(courses.categoryId, categories.id))
Expand All @@ -178,7 +121,10 @@ export class CoursesService {
users.lastName,
categories.title,
)
.orderBy(sortOrder(this.getColumnToSortBy(sortedField)));
.orderBy(
sortOrder(this.getColumnToSortBy(sortedField as CourseSortField)),
);

const dynamicQuery = queryDB.$dynamic();
const paginatedQuery = addPagination(dynamicQuery, page, perPage);
const data = await paginatedQuery;
Expand Down Expand Up @@ -210,6 +156,43 @@ export class CoursesService {
});
}

private getSelectFiled() {
return {
id: courses.id,
creationDate: courses.createdAt,
title: courses.title,
imageUrl: courses.imageUrl,
author: sql<string>`CONCAT(${users.firstName} || ' ' || ${users.lastName})`,
category: categories.title,
courseLessonCount: sql<number>`(SELECT COUNT(*) FROM ${courseLessons} WHERE ${courseLessons.courseId} = ${courses.id})::INTEGER`,
enrolledParticipantCount: count(studentCourses.courseId),
};
}

private getFiltersConditions(filters: CoursesFilterSchema) {
const conditions = [eq(courses.state, "published")];
if (filters.title) {
conditions.push(
like(categories.title, `%${filters.title.toLowerCase()}%`),
);
}
if (filters.category) {
conditions.push(like(categories.title, `%${filters.category}%`));
}
if (filters.author) {
const authorNameConcat = `${users.firstName} || ' ' || ${users.lastName}`;
conditions.push(sql`${authorNameConcat} LIKE ${`%${filters.author}%`}`);
}
if (filters.creationDateRange) {
const [startDate, endDate] = filters.creationDateRange;
const start = new Date(startDate).toISOString();
const end = new Date(endDate).toISOString();

conditions.push(between(courses.createdAt, start, end));
}
return conditions;
}

private getColumnToSortBy(sort: CourseSortField) {
switch (sort) {
case CourseSortFields.author:
Expand Down
10 changes: 0 additions & 10 deletions apps/api/src/courses/helpers/index.ts

This file was deleted.

2 changes: 1 addition & 1 deletion apps/api/src/swagger/api-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@
}
}
},
"/api/courses/getStudentCourses": {
"/api/courses/get-student-courses": {
"get": {
"operationId": "CoursesController_getStudentCourses",
"parameters": [
Expand Down

0 comments on commit cab1c0e

Please sign in to comment.