-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract business logic to services, add tests and run tests during CI/CD
- Loading branch information
Showing
7 changed files
with
164 additions
and
53 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { asc, eq } from 'drizzle-orm'; | ||
import type { UserType } from '@kinde-oss/kinde-typescript-sdk'; | ||
import { db } from '../db/db'; | ||
import { backlogTaskGroupTable } from '../db/schema'; | ||
|
||
export async function getGroups(user: UserType) { | ||
return await db | ||
.select() | ||
.from(backlogTaskGroupTable) | ||
.where(eq(backlogTaskGroupTable.userId, user.id)) | ||
.orderBy(asc(backlogTaskGroupTable.createdAt)); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { and, desc, eq, gte } from 'drizzle-orm'; | ||
import type { ValueOf } from 'ts-essentials'; | ||
import type { UserType } from '@kinde-oss/kinde-typescript-sdk'; | ||
import { db } from '../db/db'; | ||
import { backlogTasksTable } from '../db/schema'; | ||
import { BACKLOG_TASK_CREATED_FILTER } from '../constants/backlog-task-created-filter'; | ||
import dayjs from 'dayjs'; | ||
|
||
export async function getTasksByCreatedDate( | ||
user: UserType, | ||
createdFilter: ValueOf<typeof BACKLOG_TASK_CREATED_FILTER> | ||
) { | ||
return await db | ||
.select() | ||
.from(backlogTasksTable) | ||
.where(and(eq(backlogTasksTable.userId, user.id), getCreatedDateFilter(createdFilter))) | ||
.orderBy(desc(backlogTasksTable.createdAt)); | ||
} | ||
|
||
function getCreatedDateFilter(createdFilter: ValueOf<typeof BACKLOG_TASK_CREATED_FILTER>) { | ||
switch (createdFilter) { | ||
case BACKLOG_TASK_CREATED_FILTER.TODAY: | ||
return gte(backlogTasksTable.createdAt, dayjs().startOf('day').toISOString()); | ||
case BACKLOG_TASK_CREATED_FILTER.LAST_7_DAYS: | ||
return gte(backlogTasksTable.createdAt, dayjs().subtract(7, 'day').toISOString()); | ||
case BACKLOG_TASK_CREATED_FILTER.LAST_MONTH: | ||
return gte(backlogTasksTable.createdAt, dayjs().subtract(1, 'month').toISOString()); | ||
case BACKLOG_TASK_CREATED_FILTER.LAST_3_MONTHS: | ||
return gte(backlogTasksTable.createdAt, dayjs().subtract(3, 'month').toISOString()); | ||
case BACKLOG_TASK_CREATED_FILTER.LAST_6_MONTHS: | ||
return gte(backlogTasksTable.createdAt, dayjs().subtract(6, 'month').toISOString()); | ||
default: | ||
throw new Error('Invalid created filter'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { describe, it, expect, mock } from 'bun:test'; | ||
import { getBacklogTasks } from './backlog.service'; | ||
import { BACKLOG_TASK_CREATED_FILTER } from '../constants/backlog-task-created-filter'; | ||
import type { UserType } from '@kinde-oss/kinde-typescript-sdk'; | ||
import type { BacklogTask, BacklogTaskGroup } from '../db/schema'; | ||
import { BACKLOG_TASK_PRIORITY } from '../constants/backlog-task-priority.const'; | ||
|
||
describe('getBacklogTasks', () => { | ||
const user = { id: 'user1' } as UserType; | ||
const createdFilter = BACKLOG_TASK_CREATED_FILTER.TODAY; | ||
|
||
it('should fetch backlog task groups and tasks', async () => { | ||
const mockGroups = [ | ||
{ id: 'group1', name: 'test', userId: 'user1', createdAt: '2023-01-01T00:00:00Z' }, | ||
] as BacklogTaskGroup[]; | ||
|
||
const mockTasks = [ | ||
{ | ||
id: 'task1', | ||
userId: 'user1', | ||
groupId: 'group1', | ||
priority: BACKLOG_TASK_PRIORITY.HIGH, | ||
createdAt: '2023-01-01T00:00:00Z', | ||
}, | ||
] as BacklogTask[]; | ||
|
||
mock.module('../repos/group.repo', () => ({ | ||
getGroups: () => Promise.resolve(mockGroups), | ||
})); | ||
|
||
mock.module('../repos/tasks.repo', () => ({ | ||
getTasksByCreatedDate: () => Promise.resolve(mockTasks), | ||
})); | ||
|
||
const result = await getBacklogTasks(user, createdFilter); | ||
|
||
expect(result).toEqual([ | ||
{ | ||
...mockGroups[0], | ||
tasks: mockTasks, | ||
}, | ||
]); | ||
}); | ||
|
||
it('should sort tasks by priority', async () => { | ||
const mockGroups = [{ id: 'group1', userId: 'user1', createdAt: '2023-01-01T00:00:00Z' }]; | ||
const mockTasks = [ | ||
{ | ||
id: 'task1', | ||
userId: 'user1', | ||
groupId: 'group1', | ||
priority: BACKLOG_TASK_PRIORITY.LOW, | ||
createdAt: '2023-01-01T00:00:00Z', | ||
}, | ||
{ | ||
id: 'task2', | ||
userId: 'user1', | ||
groupId: 'group1', | ||
priority: BACKLOG_TASK_PRIORITY.HIGH, | ||
createdAt: '2023-01-01T00:00:00Z', | ||
}, | ||
]; | ||
|
||
mock.module('../repos/group.repo', () => ({ | ||
getGroups: () => Promise.resolve(mockGroups), | ||
})); | ||
|
||
mock.module('../repos/tasks.repo', () => ({ | ||
getTasksByCreatedDate: () => Promise.resolve(mockTasks), | ||
})); | ||
|
||
const result = await getBacklogTasks(user, createdFilter); | ||
console.log('res', result); | ||
expect(result[0].tasks).toEqual([mockTasks[1], mockTasks[0]]); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import type { ValueOf } from 'ts-essentials'; | ||
import type { UserType } from '@kinde-oss/kinde-typescript-sdk'; | ||
import { type BacklogTask, type BacklogTaskGroup } from '../db/schema'; | ||
import { BACKLOG_TASK_PRIORITY } from '../constants/backlog-task-priority.const'; | ||
import { BACKLOG_TASK_CREATED_FILTER } from '../constants/backlog-task-created-filter'; | ||
import { getGroups } from '../repos/group.repo'; | ||
import { getTasksByCreatedDate } from '../repos/tasks.repo'; | ||
|
||
export type BacklogTaskGroupWithTasks = BacklogTaskGroup & { | ||
tasks: BacklogTask[]; | ||
}; | ||
|
||
const priorityMap = { | ||
[BACKLOG_TASK_PRIORITY.HIGH]: 1, | ||
[BACKLOG_TASK_PRIORITY.MEDIUM]: 2, | ||
[BACKLOG_TASK_PRIORITY.LOW]: 3, | ||
}; | ||
|
||
export async function getBacklogTasks(user: UserType, createdFilter: ValueOf<typeof BACKLOG_TASK_CREATED_FILTER>) { | ||
const groups = await getGroups(user); | ||
const tasks = await getTasksByCreatedDate(user, createdFilter); | ||
|
||
const groupsWithTasks = groups.map((group) => { | ||
return { | ||
...group, | ||
tasks: tasks | ||
.filter((task) => task.groupId === group.id) | ||
.sort((a, b) => { | ||
return priorityMap[a.priority] - priorityMap[b.priority]; | ||
}), | ||
}; | ||
}); | ||
|
||
return groupsWithTasks; | ||
} |