Skip to content

Commit 8677eb4

Browse files
authored
Merge pull request #60 from CodeForBaltimore/revjtanton/issue-6
feat: Adding check-in endpoints Can't wait for reviews.
2 parents 1d6c685 + d56cc55 commit 8677eb4

14 files changed

+188
-50
lines changed

sequelize/migrations/04-create-demo-entity.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ module.exports = {
1717
},
1818
email: {
1919
type: Sequelize.JSON,
20-
},
20+
},
21+
checkIn: {
22+
type: Sequelize.JSON,
23+
},
2124
createdAt: {
2225
allowNull: false,
2326
type: Sequelize.DATE
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
module.exports = {
3+
up: (queryInterface, Sequelize) => {
4+
return queryInterface.createTable('CheckIns', {
5+
id: {
6+
type: Sequelize.UUID,
7+
primaryKey: true,
8+
allowNull: false,
9+
autoIncrement: false,
10+
},
11+
notes : {
12+
type: Sequelize.JSON,
13+
},
14+
createdAt: {
15+
allowNull: false,
16+
type: Sequelize.DATE
17+
},
18+
updatedAt: {
19+
allowNull: false,
20+
type: Sequelize.DATE
21+
}
22+
});
23+
},
24+
down: queryInterface => {
25+
return queryInterface.dropTable('CheckIns');
26+
}
27+
};

sequelize/migrations/05-add-demo-user-contact.js renamed to sequelize/migrations/06-add-demo-user-contact.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ module.exports = {
2020
down: function(queryInterface, Sequelize) {
2121
return queryInterface.removeColumn(
2222
'Contacts',
23-
'user_id'
23+
'UserId'
2424
);
2525
}
2626
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
module.exports = {
3+
up: function(queryInterface, Sequelize) {
4+
return queryInterface.addColumn(
5+
'Contacts',
6+
'EntityId',
7+
{
8+
type: Sequelize.UUID,
9+
references: {
10+
model: 'Entities',
11+
key: 'id'
12+
},
13+
onUpdate: 'CASCADE',
14+
onDelete: 'SET NULL'
15+
}
16+
);
17+
18+
},
19+
20+
down: function(queryInterface, Sequelize) {
21+
return queryInterface.removeColumn(
22+
'Contacts',
23+
'EntityId'
24+
);
25+
}
26+
}
File renamed without changes.

src/models/contact.js

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,18 @@ const contact = (sequelize, DataTypes) => {
1010
defaultValue: UUIDV4
1111
},
1212
UserId: {
13-
type: DataTypes.STRING,
13+
type: DataTypes.UUID,
1414
references: {
1515
model: 'User',
1616
key: 'id',
17+
},
18+
unique: true
19+
},
20+
EntityId: {
21+
type: DataTypes.UUID,
22+
references: {
23+
model: 'Entity',
24+
key: 'id'
1725
}
1826
},
1927
name : {
@@ -33,6 +41,7 @@ const contact = (sequelize, DataTypes) => {
3341

3442
Contact.associate = models => {
3543
Contact.belongsTo(models.User);
44+
Contact.belongsTo(models.Entity);
3645
}
3746

3847
Contact.findById = async (id) => {
@@ -43,6 +52,14 @@ const contact = (sequelize, DataTypes) => {
4352
return contact;
4453
};
4554

55+
Contact.findByUserId = async (UserId) => {
56+
const contact = await Contact.findOne({
57+
where: { UserId }
58+
});
59+
60+
return contact.dataValues;
61+
}
62+
4663
Contact.findByName = async (name) => {
4764
const contact = await Contact.findOne({
4865
where: { name }
@@ -51,14 +68,6 @@ const contact = (sequelize, DataTypes) => {
5168
return contact;
5269
};
5370

54-
// Contact.findByPhone = async (phone) => {
55-
// const contact = await Contact.findOne({
56-
// where: { phone }
57-
// });
58-
59-
// return contact;
60-
// };
61-
6271
return Contact;
6372
};
6473

src/models/entity.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,19 @@ const entity = (sequelize, DataTypes) => {
1818
},
1919
email: {
2020
type: DataTypes.JSON,
21+
},
22+
checkIn: {
23+
type: DataTypes.JSON,
2124
}
2225
},
2326
{
2427
schema: process.env.DATABASE_SCHEMA
2528
});
2629

30+
Entity.associate = models => {
31+
Entity.hasMany(models.Contact);
32+
}
33+
2734
Entity.findById = async (id) => {
2835
const entity = await Entity.findOne({
2936
where: { id }
@@ -40,6 +47,16 @@ const entity = (sequelize, DataTypes) => {
4047
return entity;
4148
};
4249

50+
Entity.findContacts = async (id) => {
51+
const entity = await Entity.findOne({
52+
where: { id }
53+
});
54+
55+
const contacts = await entity.getContacts();
56+
57+
return contacts;
58+
}
59+
4360
return Entity;
4461
};
4562

src/models/user.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const user = (sequelize, DataTypes) => {
7171
* @return {Boolean}
7272
*/
7373
User.validateToken = async token => {
74-
const expiry = jwt.decode(token).exp;
74+
const expiry = jwt.decode(token);
7575
const now = new Date();
7676

7777
if (now.getTime() < expiry * 1000) {

src/routes/contact.js

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Router } from 'express';
2-
import validator from 'validator';
2+
// import validator from 'validator';
33
import utils from '../utils';
44

55
const router = new Router();
@@ -9,7 +9,6 @@ router.get('/', async (req, res) => {
99
try {
1010
if (await utils.validateToken(req, res)) {
1111
const contacts = await req.context.models.Contact.findAll({
12-
attributes: ['id', 'name', 'email', 'phone', 'createdAt', 'updatedAt']
1312
});
1413
return res.send({
1514
_meta: {
@@ -33,7 +32,6 @@ router.get('/:contact_id', async (req, res) => {
3332
where: {
3433
id: req.params.contact_id
3534
},
36-
attributes: ['id', 'name', 'email', 'phone', 'createdAt', 'updatedAt']
3735
});
3836
return res.send(contact);
3937
}
@@ -49,10 +47,8 @@ router.post('/', async (req, res) => {
4947
try {
5048
if (await utils.validateToken(req, res)) {
5149
if (req.body.name !== undefined) {
52-
const { name, phone, email } = req.body;
53-
54-
55-
const contact = await req.context.models.Contact.create({ name, email, phone });
50+
const { name, phone, email, UserId, EntityId } = req.body;
51+
const contact = await req.context.models.Contact.create({ name, email, phone, UserId, EntityId });
5652
return res.send(contact.id + ' created');
5753
}
5854
}
@@ -68,22 +64,23 @@ router.post('/', async (req, res) => {
6864
router.put('/', async (req, res) => {
6965
try {
7066
if (await utils.validateToken(req, res)) {
71-
const { id, name, phone, email, UserId } = req.body;
67+
const { id, name, phone, email, UserId, EntityId } = req.body;
7268

7369
/** @todo validate emails */
7470
// Validating emails
7571
// if (await !utils.validateEmails(email)) res.status(400).send('Invalid input');
76-
72+
7773
const contact = await req.context.models.Contact.findOne({
7874
where: {
7975
id: id
8076
}
8177
});
82-
83-
contact.name = name;
84-
contact.UserId = UserId;
85-
contact.phone = phone;
86-
contact.email = email;
78+
79+
contact.name = (name) ? name : contact.name;
80+
contact.phone = (phone) ? phone : contact.phone;
81+
contact.email = (email) ? email : contact.email;
82+
contact.UserId = (UserId) ? UserId : contact.UserId;
83+
contact.EntityId = (EntityId) ? EntityId : contact.EntityId;
8784
contact.updatedAt = new Date();
8885

8986
await contact.save();
@@ -110,7 +107,8 @@ router.delete('/:contact_id', async (req, res) => {
110107
return res.send(req.params.contact_id + ' deleted');
111108
}
112109
throw new Error('Invalid input');
113-
} catch {
110+
} catch (e) {
111+
console.error(e);
114112
res.status(400).send('Invalid input');
115113
}
116114
});

src/routes/entity.js

Lines changed: 65 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Router } from 'express';
2-
import validator from 'validator';
2+
// import validator from 'validator';
33
import utils from '../utils';
44

55
const router = new Router();
@@ -9,8 +9,8 @@ router.get('/', async (req, res) => {
99
try {
1010
if (await utils.validateToken(req, res)) {
1111
const entities = await req.context.models.Entity.findAll({
12-
attributes: ['id', 'name', 'email', 'phone', 'createdAt', 'updatedAt']
1312
});
13+
1414
return res.send({
1515
_meta: {
1616
total: entities.length
@@ -32,14 +32,27 @@ router.get('/:entity_id', async (req, res) => {
3232
const entity = await req.context.models.Entity.findOne({
3333
where: {
3434
id: req.params.entity_id
35-
},
36-
attributes: ['id', 'name', 'email', 'phone', 'createdAt', 'updatedAt']
35+
}
3736
});
37+
entity.dataValues.contacts = []
38+
39+
const contacts = await req.context.models.Entity.findContacts(req.params.entity_id);
40+
41+
for (let contact of contacts) {
42+
entity.dataValues.contacts.push({
43+
id: contact.dataValues.id,
44+
name: contact.dataValues.name,
45+
});
46+
}
47+
48+
console.log(entity)
49+
3850
return res.send(entity);
3951
}
4052

4153
throw new Error('Invalid input');
42-
} catch {
54+
} catch (e) {
55+
console.error(e);
4356
res.status(400).send('Invalid payload');
4457
}
4558
});
@@ -49,10 +62,18 @@ router.post('/', async (req, res) => {
4962
try {
5063
if (await utils.validateToken(req, res)) {
5164
if (req.body.name !== undefined) {
52-
const { name, phone, email } = req.body;
53-
console.log(email)
65+
let { name, phone, email, checkIn } = req.body;
66+
67+
if (!checkIn) {
68+
checkIn = {
69+
_meta: {
70+
total: 0
71+
},
72+
checkIns: []
73+
}
74+
}
5475

55-
const entity = await req.context.models.Entity.create({ name, email, phone });
76+
const entity = await req.context.models.Entity.create({ name, email, phone, checkIn });
5677
return res.send(entity.id + ' created');
5778
}
5879
}
@@ -68,21 +89,48 @@ router.post('/', async (req, res) => {
6889
router.put('/', async (req, res) => {
6990
try {
7091
if (await utils.validateToken(req, res)) {
71-
const { id, name, phone, email } = req.body;
92+
let { id, name, phone, email, checkIn } = req.body;
7293

7394
/** @todo validate emails */
7495
// Validating emails
7596
// if (await !utils.validateEmails(email)) res.status(400).send('Invalid input');
76-
77-
const entity = await req.context.models.Entity.findOne({
97+
98+
let entity = await req.context.models.Entity.findOne({
7899
where: {
79100
id: id
80101
}
81102
});
82-
83-
entity.name = name;
84-
entity.phone = phone;
85-
entity.email = email;
103+
104+
entity.name = (name) ? name : entity.name;
105+
entity.phone = (phone) ? phone : entity.phone;
106+
entity.email = (email) ? email : entity.email;
107+
/** @todo validate checkIn JSON */
108+
if (entity.checkIn === null && checkIn) {
109+
const checkIns = {
110+
_meta: {
111+
total: 1
112+
},
113+
checkIns: [
114+
checkIn
115+
]
116+
}
117+
118+
entity.checkIn = checkIns;
119+
} else if (entity.checkIn !== null && checkIn) {
120+
let checkIns = entity.checkIn.checkIns;
121+
checkIns.push(checkIn);
122+
let total = entity.checkIn._meta.total + 1
123+
124+
const update = {
125+
_meta: {
126+
total: total
127+
},
128+
checkIns: checkIns
129+
}
130+
131+
entity.checkIn = update;
132+
}
133+
86134
entity.updatedAt = new Date();
87135

88136
await entity.save();
@@ -109,7 +157,8 @@ router.delete('/:entity_id', async (req, res) => {
109157
return res.send(req.params.entity_id + ' deleted');
110158
}
111159
throw new Error('Invalid input');
112-
} catch {
160+
} catch (e) {
161+
console.error(e);
113162
res.status(400).send('Invalid input');
114163
}
115164
});

0 commit comments

Comments
 (0)