diff --git a/server/src/setupTests.ts b/server/src/setupTests.ts
index 6418b7a9c033be3f8742384168d47541ac4bfc70..6fc5d068dc6ef76d189d6701b630c3e6e054ab06 100644
--- a/server/src/setupTests.ts
+++ b/server/src/setupTests.ts
@@ -177,7 +177,7 @@ async function loadTestData() {
                 status: 'open',
                 priority: 'urgent',
                 created: Date.parse('2020-10-15'),
-                edited: Date.parse('2020-10-20'),
+                edited: Date.parse('2020-11-20'),
             }
         ]);
     await database('task_requirements')
diff --git a/server/src/v1/auth.test.ts b/server/src/v1/auth.test.ts
index cdcace98a8796143497c994536097a075758bbab..67aaf839c1e6cf02e2973e52532617fb416cd538 100644
--- a/server/src/v1/auth.test.ts
+++ b/server/src/v1/auth.test.ts
@@ -101,7 +101,7 @@ describe('successful user registration', () => {
             .delete()
             .where({ 'users.user_name': 'user2' });
     });
-})
+});
 
 describe('password can be changed', () => {
     let response: Response;
diff --git a/server/src/v1/comment.test.ts b/server/src/v1/comment.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b763c1f766f02283091ceb762d3468c86253f761
--- /dev/null
+++ b/server/src/v1/comment.test.ts
@@ -0,0 +1,26 @@
+
+import supertest from 'supertest';
+
+import { api } from '../api';
+import { generateAuthToken } from './auth';
+
+const request = supertest(api);
+
+describe('GET /comment/:uuid', () => {
+    test('returns information for the requested comments', async () => {
+        const resp = await request
+            .get('/v1/comment/00000000-0000-4000-8000-000000000000')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.comment).toEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            text: 'Comment0',
+            created: Date.parse('2020-10-10T00:00:00'),
+            edited: Date.parse('2020-10-10T01:00:00'),
+        });
+    });
+});
+
diff --git a/server/src/v1/project.test.ts b/server/src/v1/project.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3ee499bc2d98de7bb9fad87626936da33cea4652
--- /dev/null
+++ b/server/src/v1/project.test.ts
@@ -0,0 +1,324 @@
+
+import supertest from 'supertest';
+
+import { api } from '../api';
+import { generateAuthToken } from './auth';
+
+const request = supertest(api);
+
+describe('GET /project', () => {
+    test('returns all projects the user can see', async () => {
+        const resp = await request
+            .get('/v1/project')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.projects.length).toEqual(3);
+    });
+
+    test('includes projects of team 0', async () => {
+        const resp = await request
+            .get('/v1/project')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.projects).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            name: 'Project0',
+            text: 'Project0 Text',
+            color: '#00f',
+            status: 'open',
+            deadline: '2020-10-10',
+        });
+        expect(resp.body.projects).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            name: 'Project2',
+            text: 'Project2 Text',
+            color: '#f00',
+            status: 'suspended',
+            deadline: null,
+        });
+    });
+
+    test('includes projects of team 2', async () => {
+        const resp = await request
+            .get('/v1/project')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.projects).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000001',
+            name: 'Project1',
+            text: 'Project1 Text',
+            color: '#0f0',
+            status: 'closed',
+            deadline: null,
+        });
+    });
+});
+
+describe('GET /project/:uuid', () => {
+    test('returns information for the requested project', async () => {
+        const resp = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000000')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.project).toEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            name: 'Project0',
+            text: 'Project0 Text',
+            color: '#00f',
+            status: 'open',
+            deadline: '2020-10-10',
+            teams: [ '00000000-0000-4000-8000-000000000000' ],
+        });
+    });
+});
+
+describe('GET /project/:uuid/tasks', () => {
+    test('returns all the tasks in the project', async () => {
+        const resp = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/tasks')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks.length).toEqual(4);
+    });
+
+    test('contains open tasks', async () => {
+        const resp = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/tasks')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task2',
+            text: 'Task2 Text',
+            icon: '2',
+            status: 'open',
+            priority: 'low',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-10-20'),
+            assigned: [],
+            dependencies: [ '00000000-0000-4000-8000-000000000005' ],
+            requirements: [],
+        });
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000005',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task5',
+            text: 'Task5 Text',
+            icon: '5',
+            status: 'open',
+            priority: 'urgent',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-11-20'),
+            assigned: [ { user: '00000000-0000-4000-8000-000000000000', time: 120, finished: false } ],
+            dependencies: [ ],
+            requirements: [
+                { role: '00000000-0000-4000-8000-000000000000', time: 60 },
+                { role: '00000000-0000-4000-8000-000000000001', time: 30 },
+            ],
+        });
+    });
+
+    test('contains closed tasks', async () => {
+        const resp = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/tasks')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000003',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task3',
+            text: 'Task3 Text',
+            icon: '3',
+            status: 'closed',
+            priority: 'urgent',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-10-20'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [ ],
+        });
+    });
+
+    test('contains suspended tasks', async () => {
+        const resp = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/tasks')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000004',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task4',
+            text: 'Task4 Text',
+            icon: '4',
+            status: 'suspended',
+            priority: 'urgent',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-10-20'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [ ],
+        });
+    });
+});
+
+describe('GET /project/:uuid/assigned', () => {
+    test('returns all users that are assigned to one of the projects tasks', async () => {
+        const resp = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/assigned')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.assigned.length).toEqual(1);
+    });
+
+    test('contains the user information', async () => {
+        const resp = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/assigned')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.assigned).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            username: 'user0',
+            email: 'test0@example.com',
+            realname: 'Testing Tester',
+            time: 120,
+        });
+    });
+});
+
+describe('GET /project/:uuid/work', () => {
+    test('returns all the work items done for the projects tasks', async () => {
+        const resp = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/work')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work.length).toEqual(3);
+    });
+
+    test('containt all finished work information', async () => {
+        const resp = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/work')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            started: Date.parse('2020-10-10T12:00:00'),
+            finished: Date.parse('2020-10-10T13:00:00'),
+        });
+        expect(resp.body.work).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000001',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            started: Date.parse('2020-10-10T13:00:00'),
+            finished: Date.parse('2020-10-10T14:00:00'),
+        });
+    });
+
+    test('containt all unfinished work information', async () => {
+        const resp = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/work')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            started: Date.parse('2020-10-11T12:00:00'),
+            finished: null,
+        });
+    });
+
+    test('can be limited in time with from date', async () => {
+        const resp = await request
+            .get(`/v1/project/00000000-0000-4000-8000-000000000002/work?since=${Date.parse('2020-10-10T20:00:00')}`)
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work.length).toEqual(1);
+    });
+
+    test('can be limited in time with to date', async () => {
+        const resp = await request
+            .get(`/v1/project/00000000-0000-4000-8000-000000000002/work?to=${Date.parse('2020-10-10T20:00:00')}`)
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work.length).toEqual(2);
+    });
+});
+
+describe('GET /project/:uuid/activity', () => {
+    test('returns time worked for all days', async () => {
+        const response = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/activity')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+        expect(response.body.activity.length).toEqual(1);
+    });
+
+    test('returns the total amount of work for each day', async () => {
+        const response = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/activity')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+        expect(response.body.activity[0].day).toEqual('2020-10-10');
+        expect(response.body.activity[0].time).toEqual(120 * 60 * 1000);
+    });
+
+    test('can be limited in time with from date', async () => {
+        const response = await request
+            .get(`/v1/project/00000000-0000-4000-8000-000000000002/activity?since=${Date.parse('2020-10-10T20:00:00')}`)
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+        expect(response.body.activity.length).toEqual(0);
+    });
+});
+
+describe('GET /project/:uuid/completion', () => {
+    test('returns completion for all tasks of the project', async () => {
+        const response = await request
+            .get('/v1/project/00000000-0000-4000-8000-000000000002/completion')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+        expect(response.body.completion).toEqual({
+            open: 1,
+            closed: 1,
+            suspended: 1,
+            overdue: 1,
+        });
+    });
+
+    test('can be limited in time with from date', async () => {
+        const response = await request
+            .get(`/v1/project/00000000-0000-4000-8000-000000000002/completion?since=${Date.parse('2020-10-30T20:00:00')}`)
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+        expect(response.body.completion).toEqual({
+            open: 0,
+            closed: 0,
+            suspended: 0,
+            overdue: 1,
+        });
+    });
+});
+
diff --git a/server/src/v1/project.ts b/server/src/v1/project.ts
index 600a7170aa296854d32a92418ad5d1b39973ca1f..cf3422cddbc582a4ff98555b7e7377fe1e9a29ac 100644
--- a/server/src/v1/project.ts
+++ b/server/src/v1/project.ts
@@ -30,7 +30,10 @@ project.get('/', async (req, res) => {
             .groupBy('projects.id');
         res.status(200).json({
             status: 'success',
-            projects: projects,
+            projects: projects.map(project => ({
+                ...project,
+                deadline: project.deadline && (new Date(project.deadline)).toISOString().substr(0, 10),
+            })),
         });
     } catch (e) {
         res.status(400).json({
@@ -72,7 +75,7 @@ project.get('/:uuid', async (req, res) => {
                         text: projects[0].text,
                         status: projects[0].status,
                         color: projects[0].color,
-                        deadline: projects[0].deadline,
+                        deadline: projects[0].deadline && (new Date(projects[0].deadline)).toISOString().substr(0, 10),
                         teams: projects.map(task => task.team_id),
                     }
                 });
@@ -448,7 +451,7 @@ project.put('/:uuid', async (req, res) => {
                                     text: req.body.text,
                                     color: req.body.color,
                                     status: req.body.status,
-                                    deadline: req.body.deadline,
+                                    deadline: req.body.deadline ? (new Date(req.body.deadline)).toISOString().substr(0, 10) : null,
                                 }).where({
                                     id: id,
                                 });
diff --git a/server/src/v1/task.test.ts b/server/src/v1/task.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7561db6b7627a1e951314dd08eafaeabd449e179
--- /dev/null
+++ b/server/src/v1/task.test.ts
@@ -0,0 +1,519 @@
+
+import supertest from 'supertest';
+
+import { api } from '../api';
+import { generateAuthToken } from './auth';
+
+const request = supertest(api);
+
+describe('GET /task', () => {
+    test('returns all tasks the user can see', async () => {
+        const resp = await request
+            .get('/v1/task')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks.length).toEqual(6);
+    });
+
+    test('includes tasks of project 0', async () => {
+        const resp = await request
+            .get('/v1/task')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            project: '00000000-0000-4000-8000-000000000000',
+            name: 'Task0',
+            text: 'Task0 Text',
+            icon: '0',
+            status: 'open',
+            priority: 'medium',
+            created: Date.parse('2020-10-05'),
+            edited: Date.parse('2020-10-10'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [
+                { role: '00000000-0000-4000-8000-000000000000', time: 30 },
+            ],
+        });
+    });
+
+    test('includes tasks of project 1', async () => {
+        const resp = await request
+            .get('/v1/task')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000001',
+            project: '00000000-0000-4000-8000-000000000001',
+            name: 'Task1',
+            text: 'Task1 Text',
+            icon: '1',
+            status: 'closed',
+            priority: 'high',
+            created: Date.parse('2020-10-10'),
+            edited: Date.parse('2020-10-15'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [
+                { role: '00000000-0000-4000-8000-000000000001', time: 30 },
+            ],
+        });
+    });
+
+    test('includes tasks of project 2', async () => {
+        const resp = await request
+            .get('/v1/task')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task2',
+            text: 'Task2 Text',
+            icon: '2',
+            status: 'open',
+            priority: 'low',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-10-20'),
+            assigned: [],
+            dependencies: [ '00000000-0000-4000-8000-000000000005' ],
+            requirements: [],
+        });
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000005',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task5',
+            text: 'Task5 Text',
+            icon: '5',
+            status: 'open',
+            priority: 'urgent',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-11-20'),
+            assigned: [ { user: '00000000-0000-4000-8000-000000000000', time: 120, finished: false } ],
+            dependencies: [ ],
+            requirements: [
+                { role: '00000000-0000-4000-8000-000000000000', time: 60 },
+                { role: '00000000-0000-4000-8000-000000000001', time: 30 },
+            ],
+        });
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000003',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task3',
+            text: 'Task3 Text',
+            icon: '3',
+            status: 'closed',
+            priority: 'urgent',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-10-20'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [ ],
+        });
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000004',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task4',
+            text: 'Task4 Text',
+            icon: '4',
+            status: 'suspended',
+            priority: 'urgent',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-10-20'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [ ],
+        });
+    });
+});
+
+describe('GET /task/open', () => {
+    test('returns all open tasks the user can see', async () => {
+        const resp = await request
+            .get('/v1/task/open')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks.length).toEqual(3);
+    });
+
+    test('includes tasks of project 0', async () => {
+        const resp = await request
+            .get('/v1/task/open')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            project: '00000000-0000-4000-8000-000000000000',
+            name: 'Task0',
+            text: 'Task0 Text',
+            icon: '0',
+            status: 'open',
+            priority: 'medium',
+            created: Date.parse('2020-10-05'),
+            edited: Date.parse('2020-10-10'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [
+                { role: '00000000-0000-4000-8000-000000000000', time: 30 },
+            ],
+        });
+    });
+
+    test('includes tasks of project 2', async () => {
+        const resp = await request
+            .get('/v1/task/open')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task2',
+            text: 'Task2 Text',
+            icon: '2',
+            status: 'open',
+            priority: 'low',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-10-20'),
+            assigned: [],
+            dependencies: [ '00000000-0000-4000-8000-000000000005' ],
+            requirements: [],
+        });
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000005',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task5',
+            text: 'Task5 Text',
+            icon: '5',
+            status: 'open',
+            priority: 'urgent',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-11-20'),
+            assigned: [ { user: '00000000-0000-4000-8000-000000000000', time: 120, finished: false } ],
+            dependencies: [ ],
+            requirements: [
+                { role: '00000000-0000-4000-8000-000000000000', time: 60 },
+                { role: '00000000-0000-4000-8000-000000000001', time: 30 },
+            ],
+        });
+    });
+});
+
+describe('GET /task/closed', () => {
+    test('returns all closed tasks the user can see', async () => {
+        const resp = await request
+            .get('/v1/task/closed')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks.length).toEqual(2);
+    });
+
+    test('includes tasks of project 1', async () => {
+        const resp = await request
+            .get('/v1/task/closed')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000001',
+            project: '00000000-0000-4000-8000-000000000001',
+            name: 'Task1',
+            text: 'Task1 Text',
+            icon: '1',
+            status: 'closed',
+            priority: 'high',
+            created: Date.parse('2020-10-10'),
+            edited: Date.parse('2020-10-15'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [
+                { role: '00000000-0000-4000-8000-000000000001', time: 30 },
+            ],
+        });
+    });
+
+    test('includes tasks of project 2', async () => {
+        const resp = await request
+            .get('/v1/task/closed')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000003',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task3',
+            text: 'Task3 Text',
+            icon: '3',
+            status: 'closed',
+            priority: 'urgent',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-10-20'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [ ],
+        });
+    });
+});
+
+describe('GET /task/suspended', () => {
+    test('returns all suspended tasks the user can see', async () => {
+        const resp = await request
+            .get('/v1/task/suspended')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks.length).toEqual(1);
+    });
+
+    test('includes tasks of project 2', async () => {
+        const resp = await request
+            .get('/v1/task/suspended')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000004',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task4',
+            text: 'Task4 Text',
+            icon: '4',
+            status: 'suspended',
+            priority: 'urgent',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-10-20'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [ ],
+        });
+    });
+});
+
+describe('GET /task/possible', () => {
+    test('returns all open tasks without dependencies the user can see', async () => {
+        const resp = await request
+            .get('/v1/task/possible')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks.length).toEqual(2);
+    });
+
+    test('includes tasks of project 0', async () => {
+        const resp = await request
+            .get('/v1/task/possible')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            project: '00000000-0000-4000-8000-000000000000',
+            name: 'Task0',
+            text: 'Task0 Text',
+            icon: '0',
+            status: 'open',
+            priority: 'medium',
+            created: Date.parse('2020-10-05'),
+            edited: Date.parse('2020-10-10'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [
+                { role: '00000000-0000-4000-8000-000000000000', time: 30 },
+            ],
+        });
+    });
+
+    test('includes tasks of project 2', async () => {
+        const resp = await request
+            .get('/v1/task/possible')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.tasks).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000005',
+            project: '00000000-0000-4000-8000-000000000002',
+            name: 'Task5',
+            text: 'Task5 Text',
+            icon: '5',
+            status: 'open',
+            priority: 'urgent',
+            created: Date.parse('2020-10-15'),
+            edited: Date.parse('2020-11-20'),
+            assigned: [ { user: '00000000-0000-4000-8000-000000000000', time: 120, finished: false } ],
+            dependencies: [ ],
+            requirements: [
+                { role: '00000000-0000-4000-8000-000000000000', time: 60 },
+                { role: '00000000-0000-4000-8000-000000000001', time: 30 },
+            ],
+        });
+    });
+});
+
+describe('GET /task/:uuid', () => {
+    test('returns the information for a task', async () => {
+        const resp = await request
+            .get('/v1/task/00000000-0000-4000-8000-000000000000')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.task).toEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            project: '00000000-0000-4000-8000-000000000000',
+            name: 'Task0',
+            text: 'Task0 Text',
+            icon: '0',
+            status: 'open',
+            priority: 'medium',
+            created: Date.parse('2020-10-05'),
+            edited: Date.parse('2020-10-10'),
+            assigned: [ ],
+            dependencies: [ ],
+            requirements: [
+                { role: '00000000-0000-4000-8000-000000000000', time: 30 },
+            ],
+        });
+    });
+});
+
+describe('GET /task/:uuid/comments', () => {
+    test('returns all the comments for a task', async () => {
+        const resp = await request
+            .get('/v1/task/00000000-0000-4000-8000-000000000005/comments')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.comments.length).toEqual(3);
+    });
+
+    test('contains the information for the comments', async () => {
+        const resp = await request
+            .get('/v1/task/00000000-0000-4000-8000-000000000005/comments')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.comments).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            text: 'Comment0',
+            created: Date.parse('2020-10-10T00:00:00'),
+            edited: Date.parse('2020-10-10T01:00:00'),
+        });
+        expect(resp.body.comments).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000001',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000001',
+            text: 'Comment1',
+            created: Date.parse('2020-10-10T03:00:00'),
+            edited: Date.parse('2020-10-10T04:00:00'),
+        });
+        expect(resp.body.comments).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000001',
+            text: 'Comment2',
+            created: Date.parse('2020-10-10T05:00:00'),
+            edited: Date.parse('2020-10-10T05:00:00'),
+        });
+    });
+});
+
+describe('GET /task/:uuid/work', () => {
+    test('returns all the work items done for the tasks', async () => {
+        const resp = await request
+            .get('/v1/task/00000000-0000-4000-8000-000000000005/work')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work.length).toEqual(3);
+    });
+
+    test('containt all finished work information', async () => {
+        const resp = await request
+            .get('/v1/task/00000000-0000-4000-8000-000000000005/work')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            started: Date.parse('2020-10-10T12:00:00'),
+            finished: Date.parse('2020-10-10T13:00:00'),
+        });
+        expect(resp.body.work).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000001',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            started: Date.parse('2020-10-10T13:00:00'),
+            finished: Date.parse('2020-10-10T14:00:00'),
+        });
+    });
+
+    test('containt all unfinished work information', async () => {
+        const resp = await request
+            .get('/v1/task/00000000-0000-4000-8000-000000000005/work')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            started: Date.parse('2020-10-11T12:00:00'),
+            finished: null,
+        });
+    });
+
+    test('can be limited in time with from date', async () => {
+        const resp = await request
+            .get(`/v1/task/00000000-0000-4000-8000-000000000005/work?since=${Date.parse('2020-10-10T20:00:00')}`)
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work.length).toEqual(1);
+    });
+
+    test('can be limited in time with to date', async () => {
+        const resp = await request
+            .get(`/v1/task/00000000-0000-4000-8000-000000000005/work?to=${Date.parse('2020-10-10T20:00:00')}`)
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work.length).toEqual(2);
+    });
+});
+
+describe('GET /task/:uuid/assigned', () => {
+    test('returns all users that are assigned to the tasks', async () => {
+        const resp = await request
+            .get('/v1/task/00000000-0000-4000-8000-000000000005/assigned')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.assigned.length).toEqual(1);
+    });
+
+    test('contains the user information', async () => {
+        const resp = await request
+            .get('/v1/task/00000000-0000-4000-8000-000000000005/assigned')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.assigned).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            username: 'user0',
+            email: 'test0@example.com',
+            realname: 'Testing Tester',
+            time: 120,
+        });
+    });
+});
+
diff --git a/server/src/v1/task.ts b/server/src/v1/task.ts
index 30aaa0d3f22067630b36ebb897d2b1d4d0e4a2f3..f452ad893a8764cff96b0fdbf74ca83ae9432b0d 100644
--- a/server/src/v1/task.ts
+++ b/server/src/v1/task.ts
@@ -69,7 +69,7 @@ export function generateFromFlatResult(results: any[]): Task[] {
                 grouped_tasks[row.id].assigned.push({
                     user: row.assigned_user,
                     time: row.assigned_time,
-                    finished: row.assigned_finished,
+                    finished: row.assigned_finished ? true : false,
                 });
             }
         }
diff --git a/server/src/v1/team.test.ts b/server/src/v1/team.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..a81e212c7f484c74248806fb5b9a488281c181d7
--- /dev/null
+++ b/server/src/v1/team.test.ts
@@ -0,0 +1,405 @@
+
+import supertest, { Response } from 'supertest';
+
+import database from '../database';
+import { api } from '../api';
+import { generateAuthToken } from './auth';
+
+const request = supertest(api);
+
+describe('GET /team', () => {
+    test('returns all teams the user is a member of', async () => {
+        const resp = await request
+            .get('/v1/team')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.teams.length).toEqual(2);
+    });
+
+    test('includes teams with a single member', async () => {
+        const resp = await request
+            .get('/v1/team')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.teams).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            name: 'Team0',
+            role: '00000000-0000-4000-8000-000000000000',
+        });
+    });
+
+    test('includes shared teams', async () => {
+        const resp = await request
+            .get('/v1/team')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.teams).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            name: 'Team2',
+            role: '00000000-0000-4000-8000-000000000002',
+        });
+    });
+});
+
+describe('GET /team/:uuid', () => {
+    test('returns the requested teams', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000000')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.team.id).toEqual('00000000-0000-4000-8000-000000000000');
+        expect(resp.body.team.name).toEqual('Team0');
+        expect(resp.body.team.role).toEqual('00000000-0000-4000-8000-000000000000');
+    });
+
+    test('can request teams one is not part of', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000001')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.team.id).toEqual('00000000-0000-4000-8000-000000000001');
+        expect(resp.body.team.name).toEqual('Team1');
+        expect(resp.body.team.role).toBeNull();
+    });
+});
+
+describe('GET /team/:uuid', () => {
+    test('returns the requested teams', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000000')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.team.id).toEqual('00000000-0000-4000-8000-000000000000');
+        expect(resp.body.team.name).toEqual('Team0');
+        expect(resp.body.team.role).toEqual('00000000-0000-4000-8000-000000000000');
+    });
+
+    test('can request teams one is not part of', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000001')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.team.id).toEqual('00000000-0000-4000-8000-000000000001');
+        expect(resp.body.team.name).toEqual('Team1');
+        expect(resp.body.team.role).toBeNull();
+    });
+});
+
+describe('GET /team/:uuid/members', () => {
+    test('returns all the members of the team', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000002/members')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.members.length).toEqual(2);
+    });
+
+    test('contains the user itself', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000002/members')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.members).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            username: 'user0',
+            realname: 'Testing Tester',
+            email: 'test0@example.com',
+            role: { id: '00000000-0000-4000-8000-000000000002', name: 'Role2' },
+        });
+    });
+
+    test('contains other members', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000002/members')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.members).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000001',
+            username: 'user1',
+            realname: 'Tester Testing',
+            email: 'test1@example.com',
+            role: { id: '00000000-0000-4000-8000-000000000003', name: 'Role3' },
+        });
+    });
+});
+
+describe('GET /team/:uuid/roles', () => {
+    test('returns all the roles of the team', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000002/roles')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.roles.length).toEqual(2);
+    });
+
+    test('contains the users own role', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000002/roles')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.roles).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            name: 'Role2',
+        });
+    });
+
+    test('contains other members roles', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000002/roles')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.roles).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000003',
+            name: 'Role3',
+        });
+    });
+});
+
+describe('GET /team/:uuid/projects', () => {
+    test('returns all the projects of the team', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000000/projects')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.projects.length).toEqual(2);
+    });
+
+    test('containt all the projects information', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000000/projects')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.projects).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            name: 'Project0',
+            text: 'Project0 Text',
+            color: '#00f',
+            status: 'open',
+            deadline: '2020-10-10',
+        });
+        expect(resp.body.projects).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            name: 'Project2',
+            text: 'Project2 Text',
+            color: '#f00',
+            status: 'suspended',
+            deadline: null,
+        });
+    });
+});
+
+describe('GET /team/:uuid/work', () => {
+    test('returns all the work items done by teams members', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000000/work')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work.length).toEqual(3);
+    });
+
+    test('containt all finished work information', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000000/work')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000000',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            started: Date.parse('2020-10-10T12:00:00'),
+            finished: Date.parse('2020-10-10T13:00:00'),
+        });
+        expect(resp.body.work).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000001',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            started: Date.parse('2020-10-10T13:00:00'),
+            finished: Date.parse('2020-10-10T14:00:00'),
+        });
+    });
+
+    test('containt all unfinished work information', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000000/work')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work).toContainEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            started: Date.parse('2020-10-11T12:00:00'),
+            finished: null,
+        });
+    });
+
+    test('can be limited in time with from date', async () => {
+        const resp = await request
+            .get(`/v1/team/00000000-0000-4000-8000-000000000000/work?since=${Date.parse('2020-10-10T20:00:00')}`)
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work.length).toEqual(1);
+    });
+
+    test('can be limited in time with to date', async () => {
+        const resp = await request
+            .get(`/v1/team/00000000-0000-4000-8000-000000000000/work?to=${Date.parse('2020-10-10T20:00:00')}`)
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work.length).toEqual(2);
+    });
+});
+
+describe('GET /team/:uuid/activity', () => {
+    test('returns time worked for all days', async () => {
+        const response = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000000/activity')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+        expect(response.body.activity.length).toEqual(1);
+    });
+
+    test('returns the total amount of work for each day', async () => {
+        const response = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000000/activity')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+        expect(response.body.activity[0].day).toEqual('2020-10-10');
+        expect(response.body.activity[0].time).toEqual(120 * 60 * 1000);
+    });
+
+    test('can be limited in time with from date', async () => {
+        const response = await request
+            .get(`/v1/team/00000000-0000-4000-8000-000000000000/activity?since=${Date.parse('2020-10-10T20:00:00')}`)
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+        expect(response.body.activity.length).toEqual(0);
+    });
+});
+
+describe('GET /team/:uuid/completion', () => {
+    test('returns completion for all tasks of all projects', async () => {
+        const response = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000000/completion')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+        expect(response.body.completion).toEqual({
+            open: 2,
+            closed: 1,
+            suspended: 1,
+            overdue: 1,
+        });
+    });
+
+    test('can be limited in time with from date', async () => {
+        const response = await request
+            .get(`/v1/team/00000000-0000-4000-8000-000000000000/completion?since=${Date.parse('2020-10-30T20:00:00')}`)
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+        expect(response.body.completion).toEqual({
+            open: 0,
+            closed: 0,
+            suspended: 0,
+            overdue: 1,
+        });
+    });
+});
+
+describe('POST /team', () => {
+    let response: Response;
+
+    beforeAll(async () => {
+        response = await request
+            .post('/v1/team')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`)
+            .send({
+                name: 'Team20',
+            });
+    });
+
+    test('returns the id of the new team', async () => {
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+        expect(response.body.id).toBeTruthy();
+    });
+
+    test('team can be requested afterwards', async () => {
+        const resp = await request
+            .get(`/v1/team/${response.body.id}`)
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.team.id).toEqual(response.body.id);
+        expect(resp.body.team.name).toEqual('Team20');
+        expect(resp.body.team.role).toBeTruthy();
+    });
+
+    afterAll(async () => {
+        await database('teams')
+            .delete()
+            .where({ 'teams.name': 'Team20' });
+    });
+});
+
+describe('PUT /team/:uuid', () => {
+    let response: Response;
+
+    beforeAll(async () => {
+        response = await request
+            .put('/v1/team/00000000-0000-4000-8000-000000000000')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`)
+            .send({
+                name: 'Team20',
+            });
+    });
+
+    test('returns successfully', async () => {
+        expect(response.status).toEqual(200);
+        expect(response.body.status).toEqual('success');
+    });
+
+    test('team has now the new name', async () => {
+        const resp = await request
+            .get('/v1/team/00000000-0000-4000-8000-000000000000')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.team.id).toEqual('00000000-0000-4000-8000-000000000000');
+        expect(resp.body.team.name).toEqual('Team20');
+        expect(resp.body.team.role).toEqual('00000000-0000-4000-8000-000000000000');
+    });
+
+    afterAll(async () => {
+        await request
+            .put('/v1/team/00000000-0000-4000-8000-000000000000')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`)
+            .send({
+                name: 'Team0',
+            });
+    });
+});
+
diff --git a/server/src/v1/team.ts b/server/src/v1/team.ts
index 9090c106e41d46d693718703199b2f558c11e0a8..fe329decbb45bd6f0e06796bd276f5bfc0265c04 100644
--- a/server/src/v1/team.ts
+++ b/server/src/v1/team.ts
@@ -138,25 +138,23 @@ team.get('/:uuid/', async (req, res) => {
     try {
         const id = req.params.uuid;
         if (validate(id)) {
-            const team = await database('teams')
+            const teams = await database('teams')
                 .leftJoin('team_members', 'teams.id', 'team_members.team_id')
                 .select({
                     id: 'teams.id',
                     name: 'teams.name',
                     role: 'team_members.role_id',
+                    user: 'team_members.user_id',
                 })
                 .where({
-                    'team_members.user_id': req.body.token.id,
-                    'teams.id': id,
-                })
-                .orWhere({
-                    'team_members.user_id': null,
                     'teams.id': id,
                 })
-            if (team.length >= 1) {
+            if (teams.length >= 1) {
+                const team = teams.find(team => team.user === req.body.token.id) ?? { ...teams[0], role: null };
+                delete team.user;
                 res.status(200).json({
                     status: 'success',
-                    team: team[0],
+                    team: team,
                 });
             } else {
                 res.status(404).json({
@@ -294,7 +292,10 @@ team.get('/:uuid/projects', async (req, res) => {
                 });
             res.status(200).json({
                 status: 'success',
-                projects: projects,
+                projects: projects.map(project => ({
+                    ...project,
+                    deadline: project.deadline && (new Date(project.deadline)).toISOString().substr(0, 10),
+                })),
             });
         } else {
             res.status(400).json({
diff --git a/server/src/v1/user.test.ts b/server/src/v1/user.test.ts
index 5652aa2e6ae7e2a83f76bd290c47bc2ed69dcfe0..4efa7f36d00a79edce97ced60ebb1c251e0e848a 100644
--- a/server/src/v1/user.test.ts
+++ b/server/src/v1/user.test.ts
@@ -26,7 +26,7 @@ describe('GET /user/name', () => {
         expect(response.body.status).toEqual('success');
         expect(response.body.user.username).toEqual('user0');
     });
-})
+});
 
 describe('GET /user/:uuid/image', () => {
     test('returns 404 without body if no image is set', async () => {
@@ -46,7 +46,7 @@ describe('GET /user/:uuid/image', () => {
         expect(response.status).toEqual(200);
         expect(response.body).toBeTruthy();
     });
-})
+});
 
 describe('GET /user', () => {
     test('returns the user that is authorized', async () => {
@@ -195,7 +195,7 @@ describe('GET /user/completion', () => {
             open: 0,
             closed: 0,
             suspended: 0,
-            overdue: 0,
+            overdue: 1,
         });
     });
 });
diff --git a/server/src/v1/work.test.ts b/server/src/v1/work.test.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4021bcf27f7e61ce5096c420ae56109a6511c8cf
--- /dev/null
+++ b/server/src/v1/work.test.ts
@@ -0,0 +1,33 @@
+
+import supertest from 'supertest';
+
+import { api } from '../api';
+import { generateAuthToken } from './auth';
+
+const request = supertest(api);
+
+describe('GET /work', () => {
+    test('returns information for the unfinished work', async () => {
+        const resp = await request
+            .get('/v1/work')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000000')}`);
+        expect(resp.status).toEqual(200);
+        expect(resp.body.status).toEqual('success');
+        expect(resp.body.work).toEqual({
+            id: '00000000-0000-4000-8000-000000000002',
+            task: '00000000-0000-4000-8000-000000000005',
+            user: '00000000-0000-4000-8000-000000000000',
+            started: Date.parse('2020-10-11T12:00:00'),
+            finished: null,
+        });
+    });
+
+    test('returns 404 if no work is unfinished', async () => {
+        const resp = await request
+            .get('/v1/work')
+            .set('Authorization', `Bearer ${await generateAuthToken('00000000-0000-4000-8000-000000000001')}`);
+        expect(resp.status).toEqual(404);
+        expect(resp.body.status).toEqual('error');
+    });
+});
+