diff --git a/client/src/adapters/comment.ts b/client/src/adapters/comment.ts new file mode 100644 index 0000000000000000000000000000000000000000..ba35a5f2ba6ab7f5a4c179f5eb7ee9ae4a943c81 --- /dev/null +++ b/client/src/adapters/comment.ts @@ -0,0 +1,33 @@ + +import { executeApiGet, executeApiPost, executeApiPut } from './util'; + +export interface Comment { + id: string; + task: string; + user: string; + text: string; + created: Date; + edited: Date; +} + +export function getComment(uuid: string): Promise<Comment> { + return executeApiGet(`comment/${uuid}`, ({ comment }) => ({ + ...comment, + edited: new Date(comment.edited), + created: new Date(comment.created), + }), "Failed to get comment"); +} + +interface AddCommentBody { + task: string; + text: string; +} + +export function createComment(comment: AddCommentBody): Promise<string> { + return executeApiPost(`comment`, comment, ({ id }) => id, "Failed to create comment"); +} + +export function updateComment(uuid: string, text: string) { + return executeApiPut(`comment/${uuid}`, { text: text }, () => {}, "Failed to update comment"); +} + diff --git a/client/src/adapters/project.ts b/client/src/adapters/project.ts new file mode 100644 index 0000000000000000000000000000000000000000..38c62e5c828ecaba54992e197eee30ccc64866da --- /dev/null +++ b/client/src/adapters/project.ts @@ -0,0 +1,83 @@ + +import { executeApiGet, executeApiPost, executeApiPut } from './util'; +import { Task } from './task'; +import { User } from './user'; +import { Work } from './work'; + +export interface Project { + id: string; + name: string; + text: string; + color: string; + status: 'open' | 'closed' | 'suspended'; + deadline?: Date; + teams: Array<string>; +} + +export interface AssignedUser extends User { + time: number; +} + +export type ReducedProject = Exclude<Project, 'teams'>; + +export function getProjects(): Promise<ReducedProject[]> { + return executeApiGet(`project`, ({ projects }) => projects.map((project: any) => ({ + ...project, + deadline: project.deadline ? new Date(project.deadline) : undefined, + })), "Failed to get projects"); +} + +export function getProject(uuid: string): Promise<Project> { + return executeApiGet(`project/${uuid}`, ({ project }) => ({ + ...project, + deadline: project.deadline ? new Date(project.deadline) : undefined, + }), "Failed to get project"); +} + +export function getProjectTasks(uuid: string): Promise<Task[]> { + return executeApiGet(`project/${uuid}/tasks`, ({ tasks }) => tasks.map((task: any) => ({ + ...task, + edited: new Date(task.edited), + created: new Date(task.created), + })), "Failed to get project tasks"); +} + +export function getProjectAssignees(uuid: string): Promise<AssignedUser[]> { + return executeApiGet(`project/${uuid}/assigned`, ({ assigned }) => assigned, "Failed to get project assignees"); +} + +export function getProjectWork(uuid: string): Promise<Work[]> { + return executeApiGet(`project/${uuid}/work`, ({ work }) => work.map((work: any) => ({ + ...work, + started: new Date(work.started), + finished: work.finished ? new Date(work.finished) : undefined, + })), "Failed to get project work"); +} + +interface NewTeamData { + teams: Array<string>; + name: string; + text: string; + color: string; + deadline?: Date; +} + +export function createProject(project: NewTeamData): Promise<string> { + return executeApiPost(`project`, project, ({ id }) => id, "Failed to create project"); +} + +interface UpdateTeamData { + remove_teams?: Array<string>; + add_teams?: Array<string>; + name?: string; + text?: string; + color?: string; + status?: string; + deadline?: string; +} + +export function updateProject(uuid: string, project: UpdateTeamData) { + return executeApiPut(`project/${uuid}`, project, () => {}, "Failed to update project"); +} + + diff --git a/client/src/adapters/task.ts b/client/src/adapters/task.ts new file mode 100644 index 0000000000000000000000000000000000000000..5ce7c84f6ba597924ae22362f38dff32e108f7d1 --- /dev/null +++ b/client/src/adapters/task.ts @@ -0,0 +1,112 @@ + +import { executeApiGet, executeApiPost, executeApiPut } from './util'; +import { Comment } from './comment'; +import { Work } from './work'; + +export interface TaskRequirement { + role: string; + time: number; +} + +export interface TaskAssignment { + user: string; + time: number; + finished: boolean; +} + +export interface Task { + id: string; + project: string; + name: string; + text: string; + icon: string; + priority: 'low' | 'medium' | 'high' | 'urgent'; + status: 'open' | 'closed' | 'suspended'; + dependentcies: Array<string>; + requirements: Array<TaskRequirement>; + assigned: Array<TaskAssignment>; + created: Date; + edited: Date; +} + +export function getTasks(): Promise<Task[]> { + return executeApiGet(`task`, ({ tasks }) => tasks.map((task: any) => ({ + ...task, + edited: new Date(task.edited), + created: new Date(task.created), + })), "Failed to get tasks"); +} + +export function getTasksWithStatus(status: 'open' | 'closed' | 'suspended'): Promise<Task[]> { + return executeApiGet(`task/${status}`, ({ tasks }) => tasks.map((task: any) => ({ + ...task, + edited: new Date(task.edited), + created: new Date(task.created), + })), "Failed to get tasks with status"); +} + +export function getPossibleTasks(): Promise<Task[]> { + return executeApiGet(`task/possible`, ({ tasks }) => tasks.map((task: any) => ({ + ...task, + edited: new Date(task.edited), + created: new Date(task.created), + })), "Failed to get possible tasks"); +} + +export function getTask(uuid: string): Promise<Task> { + return executeApiGet(`task/${uuid}`, ({ task }) => ({ + ...task, + edited: new Date(task.edited), + created: new Date(task.created), + }), "Failed to get task"); +} + +export function getTaskComments(uuid: string): Promise<Comment[]> { + return executeApiGet(`task/${uuid}/comments`, ({ comments }) => comments.map((comment: any) => ({ + ...comment, + edited: new Date(comment.edited), + created: new Date(comment.created), + })), "Failed to get task comments"); +} + +export function getTaskWork(uuid: string): Promise<Work[]> { + return executeApiGet(`task/${uuid}/work`, ({ work }) => work.map((work: any) => ({ + ...work, + started: new Date(work.started), + finished: work.finished ? new Date(work.finished) : undefined, + })), "Failed to get task work"); +} + +interface AddTaskBody { + project: string; + name: string; + text: string; + icon: string; + priority: string; + dependentcies: Array<string>; + requirements: Array<TaskRequirement>; + assigned: Array<TaskAssignment>; +} + +export function createTask(task: AddTaskBody): Promise<string> { + return executeApiPost(`task`, task, ({ id }) => id, "Failed to create task"); +} + +interface UpdateTaskBody { + name?: string; + text?: string; + icon?: string; + priority?: string; + status?: string; + remove_dependentcies?: Array<string>; + remove_requirements?: Array<string>; + remove_assigned?: Array<string>; + add_dependentcies?: Array<string>; + add_requirements?: Array<TaskRequirement>; + add_assigned?: Array<TaskAssignment>; +} + +export function updateTask(uuid: string, task: UpdateTaskBody) { + return executeApiPut(`task/${uuid}`, task, () => {}, "Failed to update task"); +} + diff --git a/client/src/adapters/team.ts b/client/src/adapters/team.ts new file mode 100644 index 0000000000000000000000000000000000000000..2aaef8580411be4902370b8ceed383d364109ac5 --- /dev/null +++ b/client/src/adapters/team.ts @@ -0,0 +1,84 @@ + +import { executeApiDelete, executeApiGet, executeApiPost, executeApiPut } from './util'; +import { User } from './user'; +import { ReducedProject } from './project'; +import { Work } from './work'; + +export interface Team { + id: string; + name: string; + role?: string; +} + +export interface TeamRole { + id: string; + name: string; +} + +export interface TeamMember extends User { + role: TeamRole; +} + +export function getTeams(): Promise<Team[]> { + return executeApiGet(`team`, ({ teams }) => teams, "Failed to get teams"); +} + +export function getTeam(uuid: string): Promise<Team> { + return executeApiGet(`team/${uuid}`, ({ team }) => team, "Failed to get team"); +} + +export function getTeamMembers(uuid: string): Promise<TeamMember[]> { + return executeApiGet(`team/${uuid}/members`, ({ members }) => members, "Failed to get team members"); +} + +export function getTeamRoles(uuid: string): Promise<TeamRole[]> { + return executeApiGet(`team/${uuid}/roles`, ({ roles }) => roles, "Failed to get team roles"); +} + +export function getTeamProjects(uuid: string): Promise<ReducedProject[]> { + return executeApiGet(`team/${uuid}/projects`, ({ projects }) => projects.map((project: any) => ({ + ...project, + deadline: new Date(project.deadline), + })), "Failed to get team projects"); +} + +export function getTeamWork(uuid: string): Promise<Work[]> { + return executeApiGet(`team/${uuid}/work`, ({ work }) => work.map((work: any) => ({ + ...work, + started: new Date(work.started), + finished: work.finished ? new Date(work.finished) : undefined, + })), "Failed to get team work"); +} + +export function createTeam(name: string): Promise<string> { + return executeApiPost(`team`, { name: name }, ({ id }) => id, "Failed to create team"); +} + +export function updateTeam(uuid: string, name: string) { + return executeApiPut(`team/${uuid}`, { name: name }, () => {}, "Failed to update team"); +} + +export function removeTeamMember(team: string, user: string) { + return executeApiDelete(`team/${team}/members/${user}`, () => {}, "Failed to remove team member"); +} + +export function createTeamRole(team: string, name: string): Promise<TeamRole> { + return executeApiPost(`team/${team}/roles`, { name: name }, ({ role }) => role, "Failed to create team role"); +} + +export function deleteTeamRole(team: string, role: string) { + return executeApiDelete(`team/${team}/roles/${role}`, () => {}, "Failed to delete team role"); +} + +export function addTeamMember(team: string, member: { user: string, role: string }) { + return executeApiPost(`team/${team}/members`, member, () => {}, "Failed to add team member"); +} + +export function updateTeamMember(team: string, member: { user: string, role: string }) { + return executeApiPut(`team/${team}/members`, member, () => {}, "Failed to update team member"); +} + +export function leaveTeam(team: string) { + return executeApiDelete(`team/${team}`, () => {}, "Failed to leave team"); +} + diff --git a/client/src/adapters/user.ts b/client/src/adapters/user.ts index 655b475eaed9c3493c7d661b9bcfe417abda9b1d..1eaf9f08e756f6899cb39fa636d1e76b5691ca33 100644 --- a/client/src/adapters/user.ts +++ b/client/src/adapters/user.ts @@ -1,6 +1,17 @@ import { apiRoot } from 'config'; +import { executeApiGet, executeApiPut } from './util'; +import { Task } from './task'; +import { Work } from './work'; + +export interface User { + id: string; + username: string; + realname?: string; + email?: string; +} + export async function exists(username: string) { try { const response = await fetch(`${apiRoot}/user/name/${username}`); @@ -11,3 +22,35 @@ export async function exists(username: string) { } } +export function getCurrentUser(): Promise<User> { + return executeApiGet(`user`, ({ user }) => user, "Failed to get user"); +} + +export function getUserTasks(): Promise<Array<Task>> { + return executeApiGet(`user/tasks`, ({ tasks }) => tasks.map((task: any) => ({ + ...task, + edited: new Date(task.edited), + created: new Date(task.created), + })), "Failed to get user tasks"); +} + +export function getUserWork(): Promise<Work> { + return executeApiGet(`user/work`, ({ work }) => work.map((work: any) => ({ + ...work, + started: new Date(work.started), + finished: work.finished ? new Date(work.finished) : undefined, + })), "Failed to get user work"); +} + +export function getUser(uuid: string): Promise<User> { + return executeApiGet(`user/${uuid}`, ({ user }) => user, "Failed to get user"); +} + +export function updateUser(user: { realname?: string, email?: string }) { + return executeApiPut(`user`, user, () => {}, "Failed to update user"); +} + +export function getUserImageUri(uuid: string): string { + return `${apiRoot}/user/${uuid}/image`; +} + diff --git a/client/src/adapters/util.ts b/client/src/adapters/util.ts new file mode 100644 index 0000000000000000000000000000000000000000..08a6b61442e3f8ad4da0a73079f4ef465f98b1dd --- /dev/null +++ b/client/src/adapters/util.ts @@ -0,0 +1,41 @@ + +import { apiRoot } from 'config'; + +import { getAuthHeader } from './auth'; + +async function executeApiRequest<T>(path: string, method: string, body: any, onSuccess: (data: any) => T, errorMessage: string): Promise<T> { + try { + const response = await fetch(`${apiRoot}/${path}`, { + method: method, + headers: { + ...getAuthHeader(), + ...(body ? { 'Content-Type': 'application/json' } : { }), + }, + body: body ? JSON.stringify(body) : undefined, + }); + if (response.ok) { + return onSuccess(await response.json()); + } else { + throw new Error(errorMessage); + } + } catch (e) { + throw new Error(errorMessage); + } +} + +export function executeApiGet<T>(path: string, onSuccess: (data: any) => T, errorMessage: string): Promise<T> { + return executeApiRequest(path, 'GET', undefined, onSuccess, errorMessage); +} + +export function executeApiDelete<T>(path: string, onSuccess: (data: any) => T, errorMessage: string): Promise<T> { + return executeApiRequest(path, 'DELETE', undefined, onSuccess, errorMessage); +} + +export function executeApiPost<T>(path: string, body: any, onSuccess: (data: any) => T, errorMessage: string): Promise<T> { + return executeApiRequest(path, 'POST', body, onSuccess, errorMessage); +} + +export function executeApiPut<T>(path: string, body: any, onSuccess: (data: any) => T, errorMessage: string): Promise<T> { + return executeApiRequest(path, 'PUT', body, onSuccess, errorMessage); +} + diff --git a/client/src/adapters/work.ts b/client/src/adapters/work.ts new file mode 100644 index 0000000000000000000000000000000000000000..835fc33e06db2240bdc98c601fb1cbd3b66e3fd6 --- /dev/null +++ b/client/src/adapters/work.ts @@ -0,0 +1,27 @@ + +import { executeApiGet, executeApiPost, executeApiPut } from './util'; + +export interface Work { + id: string; + task: string; + user: string; + started: Date; + finished?: Date; +} + +export function startWork(task: string): Promise<string> { + return executeApiPost(`work/start`, { task: task }, ({ id }) => id, "Failed to start work"); +} + +export function finishWork() { + return executeApiPut(`work/finish`, null, () => {}, "Failed to finish work"); +} + +export function openWork(): Promise<Work> { + return executeApiGet(`work/`, ({ work }) => ({ + ...work, + started: new Date(work.started), + finished: work.finished ? new Date(work.finished) : undefined, + }), "Failed to get open work"); +} + diff --git a/server/src/v1/comment.ts b/server/src/v1/comment.ts index f7739b9536f7cbc83d913707aac12a9380466559..66fef84296a7f62fd91f5aeef727bc0a12bf7813 100644 --- a/server/src/v1/comment.ts +++ b/server/src/v1/comment.ts @@ -70,12 +70,12 @@ comment.post('/', async (req, res) => { }); interface UpdateCommentBody { - text?: string; + text: string; token: Token; } comment.put('/:uuid', async (req, res) => { - if (isOfType<UpdateCommentBody>(req.body, [])) { + if (isOfType<UpdateCommentBody>(req.body, [['text', 'string']])) { try { const comment_id = req.params.uuid; if (validate(comment_id)) { diff --git a/server/src/v1/project.ts b/server/src/v1/project.ts index a576904110219fd52a45f1c00b07b88914de103b..0e25838d6a308b250bc5e41759fe0dcd5a1729ae 100644 --- a/server/src/v1/project.ts +++ b/server/src/v1/project.ts @@ -19,7 +19,10 @@ project.get('/', async (req, res) => { .select({ id: 'projects.id', name: 'projects.name', + text: 'projects.text', + color: 'projects.color', status: 'projects.status', + deadline: 'projects.deadline', }) .where({ 'team_members.user_id': req.body.token.id, @@ -51,6 +54,7 @@ project.get('/:uuid', async (req, res) => { text: 'projects.text', color: 'projects.color', status: 'projects.status', + deadline: 'projects.deadline', team_id: 'tms.team_id', }) .where({ @@ -64,7 +68,10 @@ project.get('/:uuid', async (req, res) => { project: { id: projects[0].id, name: projects[0].name, + text: projects[0].text, status: projects[0].status, + color: projects[0].color, + deadline: projects[0].deadline, teams: projects.map(task => task.team_id), } }); @@ -160,7 +167,7 @@ project.get('/:uuid/assigned', async (req, res) => { .groupBy('users.id'); res.status(200).json({ status: 'success', - tasks: users, + assigned: users, }); } else { res.status(400).json({ @@ -301,6 +308,7 @@ interface UpdateProjectBody { text?: string; color?: string; status?: string; + deadline?: string; token: Token; } @@ -330,15 +338,18 @@ project.put('/:uuid', async (req, res) => { }); if (projects.length >= 1) { await database.transaction(async transaction => { - await transaction('projects') - .update({ - name: req.body.name, - text: req.body.text, - color: req.body.color, - status: req.body.status, - }).where({ - id: id, - }); + if (req.body.name || req.body.text || req.body.color || req.body.status || req.body.deadline) { + await transaction('projects') + .update({ + name: req.body.name, + text: req.body.text, + color: req.body.color, + status: req.body.status, + deadline: req.body.deadline, + }).where({ + id: id, + }); + } if (remove_team_ids.length !== 0) { await transaction('team_projects') .delete() diff --git a/server/src/v1/task.ts b/server/src/v1/task.ts index 3662b6e65532c6114d1f04d34d9f1f9f5e92407b..e00c3ce06c063c8e6985112d914f2ef0ce389fd6 100644 --- a/server/src/v1/task.ts +++ b/server/src/v1/task.ts @@ -546,18 +546,20 @@ task.put('/:uuid', async (req, res) => { }); if (task.length >= 1) { await database.transaction(async transaction => { - await transaction('tasks') - .update({ - name: req.body.name, - text: req.body.text, - icon: req.body.icon, - priority: req.body.priority, - status: req.body.status, - edited: new Date(), - }) - .where({ - 'tasks.id': task_id, - }); + if (req.body.name || req.body.text || req.body.icon || req.body.priority || req.body.status) { + await transaction('tasks') + .update({ + name: req.body.name, + text: req.body.text, + icon: req.body.icon, + priority: req.body.priority, + status: req.body.status, + edited: new Date(), + }) + .where({ + 'tasks.id': task_id, + }); + } if (remove_requirement_ids.length !== 0) { await transaction('task_requirements') .delete() diff --git a/server/src/v1/team.ts b/server/src/v1/team.ts index e012eec1efab9dcb5721af6195c07a4d0c9ed565..a12609eb7adbbcddafef31b9ec3a00a43630a9cb 100644 --- a/server/src/v1/team.ts +++ b/server/src/v1/team.ts @@ -10,48 +10,96 @@ const team = express(); team.use(requireVerification); -interface TeamCreateBody { +interface CreateTeamBody { name: string; token: Token; } team.post('/', async (req, res) => { - if (isOfType<TeamCreateBody>(req.body, [['name', 'string']])) { + if (isOfType<CreateTeamBody>(req.body, [['name', 'string']])) { const team_id = uuid(); - const team_name = req.body.name.trim(); const role_id = uuid(); - if (team_name.length >= 4) { + const team_name = req.body.name; + try { + await database.transaction(async transaction => { + await transaction('teams').insert({ + id: team_id, + name: team_name, + }); + await transaction('roles').insert({ + id: role_id, + team_id: team_id, + name: 'Default', + }); + await transaction('team_members').insert({ + user_id: req.body.token.id, + team_id: team_id, + role_id: role_id, + }); + }); + res.status(200).json({ + status: 'success', + id: team_id, + }); + } catch (e) { + res.status(400).json({ + status: 'error', + message: 'failed create team', + }); + } + } else { + res.status(400).json({ + status: 'error', + message: 'missing request fields', + }); + } +}); + +interface UpdateTeamBody { + name: string; + token: Token; +} + +team.put('/:uuid', async (req, res) => { + if (isOfType<UpdateTeamBody>(req.body, [['name', 'string']])) { + const team_id = req.params.uuid; + if (validate(team_id)) { + const team_name = req.body.name; try { - await database.transaction(async transaction => { - await transaction('teams').insert({ - id: team_id, - name: team_name, + const team = await database('teams') + .leftJoin('team_members', 'teams.id', 'team_members.team_id') + .select({ id: 'teams.id' }) + .where({ + 'team_members.user_id': req.body.token.id, + 'teams.id': team_id, }); - await transaction('roles').insert({ - id: role_id, - team_id: team_id, - name: 'Default', + if (team.length >= 1) { + await database('teams') + .update({ + name: team_name, + }) + .where({ + 'teams.id': team_id, + }) + res.status(200).json({ + status: 'success', }); - await transaction('team_members').insert({ - user_id: req.body.token.id, - team_id: team_id, - role_id: role_id, + } else { + res.status(404).json({ + status: 'error', + message: 'team not found', }); - }); - res.status(200).json({ - status: 'success', - id: team_id, - }); + } } catch (e) { res.status(400).json({ status: 'error', - message: 'failed create team', + message: 'failed update team', }); } } else { res.status(400).json({ status: 'error', - message: 'team names must be four letters or longer', + message: 'malformed uuid', }); } } else { @@ -105,7 +153,7 @@ team.get('/:uuid/', async (req, res) => { 'team_members.user_id': null, 'teams.id': id, }) - if (team.length === 1) { + if (team.length >= 1) { res.status(200).json({ status: 'success', team: team[0], @@ -196,7 +244,7 @@ team.delete('/:teamid/members/:userid', async (req, res) => { 'team_members.user_id': req.body.token.id, 'team_members.team_id': team_id, }); - if (team.length === 1) { + if (team.length >= 1) { const deleted = await database('team_members') .delete() .where({ @@ -233,7 +281,6 @@ team.delete('/:teamid/members/:userid', async (req, res) => { } }); - team.get('/:uuid/roles', async (req, res) => { try { const id = req.params.uuid; @@ -284,7 +331,10 @@ team.get('/:uuid/projects', async (req, res) => { .select({ id: 'projects.id', name: 'projects.name', + text: 'projects.text', + color: 'projects.color', status: 'projects.status', + deadline: 'projects.deadline', }) .where({ 'team_members.user_id': req.body.token.id, @@ -363,7 +413,7 @@ team.post('/:uuid/roles', async (req, res) => { 'team_members.user_id': req.body.token.id, 'team_members.team_id': team_id, }); - if (team.length === 1) { + if (team.length >= 1) { const role_id = uuid(); const role_name = req.body.name; await database('roles').insert({ @@ -415,7 +465,7 @@ team.delete('/:teamid/roles/:roleid', async (req, res) => { 'team_members.user_id': req.body.token.id, 'team_members.team_id': team_id, }); - if (team.length === 1) { + if (team.length >= 1) { const deleted = await database('roles') .delete() .where({ @@ -473,7 +523,7 @@ team.post('/:uuid/members', async (req, res) => { 'team_members.team_id': team_id, 'roles.id': role_id, }); - if (role.length === 1) { + if (role.length >= 1) { await database('team_members').insert({ user_id: user_id, team_id: team_id, @@ -529,7 +579,7 @@ team.put('/:uuid/members', async (req, res) => { 'team_members.team_id': team_id, 'roles.id': role_id, }); - if (role.length === 1) { + if (role.length >= 1) { await database('team_members') .update({ role_id: role_id }) .where({ diff --git a/server/src/v1/user.ts b/server/src/v1/user.ts index d4ffdbb1ad808dea9837e4c1ca925b865b8fe818..2fa51c76ca96331a1cc3224b4caf296bade1ba6a 100644 --- a/server/src/v1/user.ts +++ b/server/src/v1/user.ts @@ -145,25 +145,29 @@ interface UserUpdateBody { } user.put('/', async (req, res) => { - if ( - isOfType<UserUpdateBody>(req.body, [['realname', 'string']]) - || isOfType<UserUpdateBody>(req.body, [['email', 'string']]) - ) { + if (isOfType<UserUpdateBody>(req.body, [])) { try { - const updated = await database('users') - .update({ - email: req.body.email, - real_name: req.body.realname, - }) - .where({ id: req.body.token.id }); - if (updated >= 1) { + if (req.body.realname || req.body.email) { + const updated = await database('users') + .update({ + email: req.body.email, + real_name: req.body.realname, + }) + .where({ id: req.body.token.id }); + if (updated >= 1) { + res.status(200).json({ + status: 'success', + }); + } else { + res.status(404).json({ + status: 'error', + message: 'user not found', + }); + } + } else { res.status(200).json({ status: 'success', - }); - } else { - res.status(404).json({ - status: 'error', - message: 'user not found', + message: 'nothing to do', }); } } catch (e) { diff --git a/server/src/v1/work.ts b/server/src/v1/work.ts index 680e3e79e2fc958ed95e83888a30e50696a5f12e..65e32237c409d9c7586702dd10ac8a1900e53c57 100644 --- a/server/src/v1/work.ts +++ b/server/src/v1/work.ts @@ -109,7 +109,13 @@ work.put('/finish', async (req, res) => { work.get('/', async (req, res) => { try { const work = await database('workhours') - .select() + .select({ + id: 'workhours.id', + task: 'workhours.task_id', + user: 'workhours.user_id', + started: 'workhours.started', + finished: 'workhours.finished', + }) .where({ user_id: req.body.token.id, finished: null,