Skip to content
Snippets Groups Projects
Commit e71db7e5 authored by Bernard Roland (Student Com20)'s avatar Bernard Roland (Student Com20)
Browse files

Added API paths for getting work

parent e221cea2
No related branches found
No related tags found
No related merge requests found
...@@ -29,6 +29,7 @@ export async function up(database: Knex): Promise<void> { ...@@ -29,6 +29,7 @@ export async function up(database: Knex): Promise<void> {
.createTable('projects', table => { .createTable('projects', table => {
table.uuid('id').notNullable().primary(); table.uuid('id').notNullable().primary();
table.text('name').notNullable(); table.text('name').notNullable();
table.text('text').notNullable();
table.string('color').notNullable(); table.string('color').notNullable();
table.enum('status', [ 'open', 'closed', 'suspended' ]).notNullable(); table.enum('status', [ 'open', 'closed', 'suspended' ]).notNullable();
}) })
......
...@@ -48,6 +48,8 @@ project.get('/:uuid', async (req, res) => { ...@@ -48,6 +48,8 @@ project.get('/:uuid', async (req, res) => {
.select({ .select({
id: 'projects.id', id: 'projects.id',
name: 'projects.name', name: 'projects.name',
text: 'projects.text',
color: 'projects.color',
status: 'projects.status', status: 'projects.status',
team_id: 'tms.team_id', team_id: 'tms.team_id',
}) })
...@@ -134,15 +136,96 @@ project.get('/:uuid/tasks', async (req, res) => { ...@@ -134,15 +136,96 @@ project.get('/:uuid/tasks', async (req, res) => {
} }
}); });
project.get('/:uuid/assigned', async (req, res) => {
try {
const id = req.params.uuid;
if (validate(id)) {
const users = await database('team_members')
.innerJoin('team_projects', 'team_members.team_id', 'team_projects.team_id')
.innerJoin('tasks', 'team_projects.project_id', 'tasks.project_id')
.innerJoin('task_assignees', 'tasks.id', 'task_assignees.task_id')
.innerJoin('users', 'task_assignees.user_id', 'users.id')
.select({
id: 'users.id',
username: 'users.user_name',
email: 'users.email',
realname: 'users.real_name',
})
.sum({ time: 'task_assignees.time' })
.where({
'team_members.user_id': req.body.token.id,
'team_projects.project_id': id,
})
.groupBy('users.id');
res.status(200).json({
status: 'success',
tasks: users,
});
} else {
res.status(400).json({
status: 'error',
message: 'malformed uuid',
});
}
} catch (e) {
console.log(e);
res.status(400).json({
status: 'error',
message: 'failed to get assignees',
});
}
});
project.get('/:uuid/work', async (req, res) => {
try {
const id = req.params.uuid;
if (validate(id)) {
const since = (req.query.since ?? 0) as number;
const work = await database({ ut: 'team_members' })
.innerJoin('team_projects', 'ut.team_id', 'team_projects.team_id')
.innerJoin('tasks', 'team_projects.project_id', 'tasks.project_id')
.innerJoin('workhours', 'tasks.id', 'workhours.task_id')
.select({
id: 'workhours.id',
task: 'workhours.task_id',
user: 'workhours.user_id',
started: 'workhours.started',
finished: 'workhours.finished',
})
.where({
'ut.user_id': req.body.token.id,
'team_projects.project_id': id,
})
.andWhere('workhours.started', '>=', since)
.groupBy('workhours.id');
res.status(200).json({
status: 'success',
work: work,
});
} else {
res.status(400).json({
status: 'error',
message: 'malformed uuid',
});
}
} catch (e) {
res.status(400).json({
status: 'error',
message: 'failed get work',
});
}
});
interface AddProjectBody { interface AddProjectBody {
teams: Array<string>; teams: Array<string>;
name: string; name: string;
text: string;
color: string; color: string;
token: Token; token: Token;
} }
project.post('/', async (req, res) => { project.post('/', async (req, res) => {
if (isOfType<AddProjectBody>(req.body, [['teams', 'object'], ['name', 'string'], ['color', 'string']])) { if (isOfType<AddProjectBody>(req.body, [['teams', 'object'], ['name', 'string'], ['text', 'string'], ['color', 'string']])) {
try { try {
const team_ids = req.body.teams; const team_ids = req.body.teams;
for (const team_id of team_ids) { for (const team_id of team_ids) {
...@@ -173,6 +256,8 @@ project.post('/', async (req, res) => { ...@@ -173,6 +256,8 @@ project.post('/', async (req, res) => {
await transaction('projects').insert({ await transaction('projects').insert({
id: project_id, id: project_id,
name: req.body.name, name: req.body.name,
text: req.body.text,
color: req.body.color,
status: 'open', status: 'open',
}); });
await transaction('team_projects').insert( await transaction('team_projects').insert(
...@@ -211,6 +296,7 @@ interface UpdateProjectBody { ...@@ -211,6 +296,7 @@ interface UpdateProjectBody {
remove_teams?: Array<string>; remove_teams?: Array<string>;
add_teams?: Array<string>; add_teams?: Array<string>;
name?: string; name?: string;
text?: string;
color?: string; color?: string;
status?: string; status?: string;
token: Token; token: Token;
...@@ -245,6 +331,7 @@ project.put('/:uuid', async (req, res) => { ...@@ -245,6 +331,7 @@ project.put('/:uuid', async (req, res) => {
await transaction('projects') await transaction('projects')
.update({ .update({
name: req.body.name, name: req.body.name,
text: req.body.text,
color: req.body.color, color: req.body.color,
status: req.body.status, status: req.body.status,
}).where({ }).where({
......
...@@ -257,6 +257,46 @@ task.get('/:uuid/comments', async (req, res) => { ...@@ -257,6 +257,46 @@ task.get('/:uuid/comments', async (req, res) => {
} }
}); });
task.get('/:uuid/work', async (req, res) => {
try {
const id = req.params.uuid;
if (validate(id)) {
const since = (req.query.since ?? 0) as number;
const work = await database({ ut: 'team_members' })
.innerJoin('team_projects', 'ut.team_id', 'team_projects.team_id')
.innerJoin('tasks', 'team_projects.project_id', 'tasks.project_id')
.innerJoin('workhours', 'tasks.id', 'workhours.task_id')
.select({
id: 'workhours.id',
task: 'workhours.task_id',
user: 'workhours.user_id',
started: 'workhours.started',
finished: 'workhours.finished',
})
.where({
'ut.user_id': req.body.token.id,
'tasks.id': id,
})
.andWhere('workhours.started', '>=', since)
.groupBy('workhours.id');
res.status(200).json({
status: 'success',
work: work,
});
} else {
res.status(400).json({
status: 'error',
message: 'malformed uuid',
});
}
} catch (e) {
res.status(400).json({
status: 'error',
message: 'failed get work',
});
}
});
task.get('/:uuid', async (req, res) => { task.get('/:uuid', async (req, res) => {
try { try {
const id = req.params.uuid; const id = req.params.uuid;
......
...@@ -260,6 +260,45 @@ team.get('/:uuid/projects', async (req, res) => { ...@@ -260,6 +260,45 @@ team.get('/:uuid/projects', async (req, res) => {
} }
}); });
team.get('/:uuid/work', async (req, res) => {
try {
const id = req.params.uuid;
if (validate(id)) {
const since = (req.query.since ?? 0) as number;
const work = await database({ ut: 'team_members' })
.innerJoin('team_members', 'ut.team_id', 'team_members.team_id')
.innerJoin('workhours', 'team_members.user_id', 'workhours.user_id')
.select({
id: 'workhours.id',
task: 'workhours.task_id',
user: 'workhours.user_id',
started: 'workhours.started',
finished: 'workhours.finished',
})
.where({
'ut.user_id': req.body.token.id,
'ut.team_id': id,
})
.andWhere('workhours.started', '>=', since)
.groupBy('workhours.id');
res.status(200).json({
status: 'success',
work: work,
});
} else {
res.status(400).json({
status: 'error',
message: 'malformed uuid',
});
}
} catch (e) {
res.status(400).json({
status: 'error',
message: 'failed get work',
});
}
});
interface AddRoleBody { interface AddRoleBody {
name: string; name: string;
token: Token; token: Token;
......
...@@ -108,6 +108,34 @@ user.get('/tasks', async (req, res) => { ...@@ -108,6 +108,34 @@ user.get('/tasks', async (req, res) => {
} }
}); });
user.get('/work', async (req, res) => {
try {
const since = (req.query.since ?? 0) as number;
const work = await database('workhours')
.select({
id: 'workhours.id',
task: 'workhours.task_id',
user: 'workhours.user_id',
started: 'workhours.started',
finished: 'workhours.finished',
})
.where({
'workhours.user_id': req.body.token.id,
})
.andWhere('workhours.started', '>=', since)
.groupBy('workhours.id');
res.status(200).json({
status: 'success',
work: work,
});
} catch (e) {
res.status(400).json({
status: 'error',
message: 'failed get work',
});
}
});
interface UserUpdateBody { interface UserUpdateBody {
token: Token; token: Token;
realname?: string; realname?: string;
......
import express from 'express'; import express from 'express';
import { v4 as uuid, validate } from 'uuid';
import { requireVerification } from './auth'; import database from '../database';
import { requireVerification, Token } from './auth';
import { isOfType } from '../util';
const work = express(); const work = express();
work.use(requireVerification); work.use(requireVerification);
interface AddWorkBody {
task: string;
token: Token;
}
work.post('/start', async (req, res) => {
if (isOfType<AddWorkBody>(req.body, [['task', 'string']])) {
try {
const task_id = req.body.task;
if (validate(task_id)) {
const task = await database('team_members')
.innerJoin('team_projects', 'team_members.team_id', 'team_projects.team_id')
.innerJoin('tasks', 'team_projects.project_id', 'tasks.project_id')
.select({ id: 'tasks.id' })
.where({
'team_members.user_id': req.body.token.id,
'tasks.id': task_id,
});
if (task.length >= 1) {
const work_id = uuid();
await database.transaction(async transaction => {
await transaction('workhours')
.update({
finished: new Date(),
})
.where({
user_id: req.body.token.id,
finished: null,
});
await transaction('workhours')
.insert({
id: work_id,
task_id: task_id,
user_id: req.body.token.id,
started: new Date(),
finished: null,
});
});
res.status(200).json({
status: 'success',
id: work_id,
});
} else {
res.status(404).json({
status: 'error',
message: 'task not found',
});
}
} else {
res.status(400).json({
status: 'error',
message: 'malformed uuid',
});
}
} catch (e) {
res.status(400).json({
status: 'error',
message: 'failed to create work',
});
}
} else {
res.status(400).json({
status: 'error',
message: 'missing request fields',
});
}
});
work.put('/finish', async (req, res) => {
try {
const work = await database('workhours')
.update({
finished: new Date(),
})
.where({
user_id: req.body.token.id,
finished: null,
});
if (work >= 1) {
res.status(200).json({
status: 'success',
});
} else {
res.status(200).json({
status: 'error',
message: 'no work to finish',
});
}
} catch (e) {
res.status(400).json({
status: 'error',
message: 'failed to finish work',
});
}
});
export default work; export default work;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment