From d44824e563d0b6dc4a15692e2d7a872d5b3cd232 Mon Sep 17 00:00:00 2001 From: data Date: Wed, 3 Jul 2019 14:27:19 -0400 Subject: [PATCH 1/4] add articles and tags --- api/articles.js | 54 ++++++++++++++++++++++++++++++++++++++++++++ api/index.js | 2 ++ api/projects.js | 4 ++-- api/tags.js | 54 ++++++++++++++++++++++++++++++++++++++++++++ api/tasks.js | 4 ++-- db/models/article.js | 15 ++++++++++++ db/models/index.js | 6 ++++- db/models/tag.js | 11 +++++++++ db/seed.js | 11 ++++++++- 9 files changed, 155 insertions(+), 6 deletions(-) create mode 100644 api/articles.js create mode 100644 api/tags.js create mode 100644 db/models/article.js create mode 100644 db/models/tag.js diff --git a/api/articles.js b/api/articles.js new file mode 100644 index 0000000..f7ef716 --- /dev/null +++ b/api/articles.js @@ -0,0 +1,54 @@ +const router = require('express').Router() +const { Project, Task, Article, Tag } = require('../db/models') +module.exports = router + +/* CREATE */ +router.post('/', async (req, res, next) => { + try { + const article = await Article.create(req.body) + res.json(article) + } catch (err) { + next(err) + } +}) + +/* READ */ +router.get('/', async (req, res, next) => { + try { + const articles = await Article.findAll() + res.send(articles) + } catch (err) { + next(err) + } +}) + +router.get('/:id', async (req, res, next) => { + try { + const article = await Article.findByPk(req.params.id) + res.json(article) + } catch (err) { + next(err) + } +}) + +/* UPDATE */ +router.put('/:id', async (req, res, next) => { + try { + const article = await Article.findByPk(req.params.id) + await article.update(req.body) + res.json(article) + } catch (err) { + next(err) + } +}) + +/* DELETE */ +router.post('/:id/delete', async (req, res, next) => { + try { + const article = await Article.findByPk(req.params.id) + await article.destroy({ force: true }) + res.json(article) + } catch (err) { + next(err) + } +}) diff --git a/api/index.js b/api/index.js index b3c9127..f53c504 100755 --- a/api/index.js +++ b/api/index.js @@ -4,6 +4,8 @@ const ascii = require('../ascii') router.use('/tasks', require('./tasks')) router.use('/projects', require('./projects')) +router.use('/articles', require('./articles')) +router.use('/tags', require('./tags')) router.get('/', async (req, res, next) => { try { diff --git a/api/projects.js b/api/projects.js index dc85907..05f7be6 100644 --- a/api/projects.js +++ b/api/projects.js @@ -1,5 +1,5 @@ const router = require('express').Router() -const { Project, Task } = require('../db/models') +const { Project, Task, Article, Tag } = require('../db/models') module.exports = router /* CREATE */ @@ -46,7 +46,7 @@ router.put('/:id', async (req, res, next) => { router.post('/:id/delete', async (req, res, next) => { try { const project = await Project.findByPk(req.params.id) - project.destroy({ force: true }) + await project.destroy({ force: true }) await Task.destroy({ where: { projectId: req.params.id, diff --git a/api/tags.js b/api/tags.js new file mode 100644 index 0000000..8be62a7 --- /dev/null +++ b/api/tags.js @@ -0,0 +1,54 @@ +const router = require('express').Router() +const { Project, Task, Article, Tag } = require('../db/models') +module.exports = router + +/* CREATE */ +router.post('/', async (req, res, next) => { + try { + const tag = await Tag.create(req.body) + res.json(tag) + } catch (err) { + next(err) + } +}) + +/* READ */ +router.get('/', async (req, res, next) => { + try { + const tags = await Tag.findAll() + res.send(tags) + } catch (err) { + next(err) + } +}) + +router.get('/:id', async (req, res, next) => { + try { + const tag = await Tag.findByPk(req.params.id) + res.json(tag) + } catch (err) { + next(err) + } +}) + +/* UPDATE */ +router.put('/:id', async (req, res, next) => { + try { + const tag = await Tag.findByPk(req.params.id) + await tag.update(req.body) + res.json(tag) + } catch (err) { + next(err) + } +}) + +/* DELETE */ +router.post('/:id/delete', async (req, res, next) => { + try { + const tag = await Tag.findByPk(req.params.id) + await tag.destroy({ force: true }) + res.json(tag) + } catch (err) { + next(err) + } +}) diff --git a/api/tasks.js b/api/tasks.js index 5ac1e7c..70ca882 100755 --- a/api/tasks.js +++ b/api/tasks.js @@ -1,5 +1,5 @@ const router = require('express').Router() -const { Project, Task } = require('../db/models') +const { Project, Task, Article, Tag } = require('../db/models') module.exports = router /* CREATE */ @@ -53,7 +53,7 @@ router.put('/:id', async (req, res, next) => { router.post('/:id/delete', async (req, res, next) => { try { const task = await Task.findByPk(req.params.id) - task.destroy({ force: true }) + await task.destroy({ force: true }) res.json(task) } catch (err) { next(err) diff --git a/db/models/article.js b/db/models/article.js new file mode 100644 index 0000000..13a2267 --- /dev/null +++ b/db/models/article.js @@ -0,0 +1,15 @@ +const Sequelize = require('sequelize') +const db = require('../db') + +const Article = db.define('articles', { + title: { + type: Sequelize.STRING, + allowNull: false, + }, + text: { + type: Sequelize.TEXT, + allowNull: true, + }, +}) + +module.exports = Article diff --git a/db/models/index.js b/db/models/index.js index 9c2cd3f..90c55c3 100755 --- a/db/models/index.js +++ b/db/models/index.js @@ -1,9 +1,13 @@ const Task = require('./task') const Project = require('./project') const User = require('./user') +const Article = require('./article') +const Tag = require('./tag') Project.hasMany(Task) Task.belongsTo(Project) +Article.hasMany(Tag) +Tag.belongsTo(Article) User.belongsToMany(Project, { through: 'projectUser' }) Project.hasMany(User) @@ -11,4 +15,4 @@ Project.hasMany(User) Task.belongsToMany(User, { through: 'userTask' }) User.hasMany(Task) -module.exports = { Task, Project, User } +module.exports = { Task, Project, User, Article, Tag } diff --git a/db/models/tag.js b/db/models/tag.js new file mode 100644 index 0000000..bd3338a --- /dev/null +++ b/db/models/tag.js @@ -0,0 +1,11 @@ +const Sequelize = require('sequelize') +const db = require('../db') + +const Tag = db.define('tags', { + name: { + type: Sequelize.STRING, + allowNull: false, + }, +}) + +module.exports = Tag diff --git a/db/seed.js b/db/seed.js index b7d967a..15d123c 100755 --- a/db/seed.js +++ b/db/seed.js @@ -1,5 +1,5 @@ const db = require('../db') -const { Task, Project, User } = require('./models') +const { Task, Project, User, Article, Tag } = require('./models') const testTasks = [ { @@ -26,6 +26,10 @@ const testUsers = [ { name: 'dn', email: 'dn@ap.org' }, ] +const testArticles = [{ title: 'latest news', text: 'waddup?!' }] + +const testTags = [{ name: 'dox', articleId: 1 }] + async function runSeed() { await db.sync({ force: true }) console.log('db synced!') @@ -48,6 +52,11 @@ async function runSeed() { await u1.addTasks([t1, t2]) await u2.addTask(t3) + const projects = await Project.bulkCreate(testProjects) + const tasks = await Task.bulkCreate(testTasks) + const articles = await Article.bulkCreate(testArticles) + const tags = await Tag.bulkCreate(testTags) + console.log('seeded successfully') } catch (err) { console.error(err) -- 2.49.0 From 9ed521c2988278ef06eb077311538ba6d61c897f Mon Sep 17 00:00:00 2001 From: data Date: Thu, 4 Jul 2019 09:16:49 -0400 Subject: [PATCH 2/4] add Comments and Votes --- api/comments.js | 34 ++++++++++++++++++++++++++++ api/index.js | 3 +++ api/votes.js | 53 ++++++++++++++++++++++++++++++++++++++++++++ db/models/comment.js | 11 +++++++++ db/models/index.js | 14 +++++++++++- db/models/vote.js | 9 ++++++++ db/seed.js | 22 +++++++++++++----- 7 files changed, 139 insertions(+), 7 deletions(-) create mode 100644 api/comments.js create mode 100644 api/votes.js create mode 100644 db/models/comment.js create mode 100644 db/models/vote.js diff --git a/api/comments.js b/api/comments.js new file mode 100644 index 0000000..54e4a69 --- /dev/null +++ b/api/comments.js @@ -0,0 +1,34 @@ +const router = require('express').Router() +const { Comment, User, Vote } = require('../db/models') + +module.exports = router + + +router.get('/', async (req, res, next) => { + try { + const comments = await Comment.findAll({ + attributes: ['id', 'text']}) + res.send(comments) + } catch (err) { + next(err) + } +}) + +router.get('/:id', async (req, res, next) => { + try { + const comment = await Comment.findByPk(req.params.id, { + attributes: ['id', 'text']}) + res.json(comment) + } catch (err) { + next(err) + } +}) + +router.post('/', async (req, res, next) => { + try { + const comment = await Comment.create(req.body) + res.json(comment) + } catch (err) { + next(err) + } +}) diff --git a/api/index.js b/api/index.js index f53c504..b9c1704 100755 --- a/api/index.js +++ b/api/index.js @@ -6,6 +6,9 @@ router.use('/tasks', require('./tasks')) router.use('/projects', require('./projects')) router.use('/articles', require('./articles')) router.use('/tags', require('./tags')) +router.use('/comments', require('./comments')) +router.use('/votes', require('./votes')) +router.use('/users', require('./users')) router.get('/', async (req, res, next) => { try { diff --git a/api/votes.js b/api/votes.js new file mode 100644 index 0000000..ad522de --- /dev/null +++ b/api/votes.js @@ -0,0 +1,53 @@ +const router = require('express').Router() +const { Comment, User, Vote } = require('../db/models') +module.exports = router + +router.get('/', async (req, res, next) => { + try { + const votes = await Vote.findAll() + res.send(votes) + } catch (err) { + next(err) + } +}) + +router.post('/', async (req, res, next) => { + const {userId, commentId, upvote, downvote} = req.body + try { + const votes = await Vote.create({userId, commentId, upvote, downvote}) + res.send(votes) + } catch (err) { + next(err) + } +}) + +router.get('/:id', async (req, res, next) => { + try { + const vote = await Vote.findByPk(+req.params.id) + res.json(vote) + } catch (err) { + next(err) + } +}) + +router.post('/:id/delete', async (req, res, next) => { + try { + const vote = await Vote.findByPk(+req.params.id) + await vote.destroy() + res.json(vote) + } catch (err) { + next(err) + } +}) + +router.put('/:id/update', async (req, res, next) => { + const upvote = req.body.downvote + const downvote = req.body.upvote + try { + const vote = await Vote.findByPk(+req.params.id) + await vote.update({upvote, downvote}) + res.json(vote) + } catch (err) { + next(err) + } +}) diff --git a/db/models/comment.js b/db/models/comment.js new file mode 100644 index 0000000..2cc827f --- /dev/null +++ b/db/models/comment.js @@ -0,0 +1,11 @@ +const Sequelize = require('sequelize') +const db = require('../db') + +const Comment = db.define('comments', { + text: { + type: Sequelize.TEXT, + allowNull: false, + }, +}) + +module.exports = Comment diff --git a/db/models/index.js b/db/models/index.js index 90c55c3..dd8533e 100755 --- a/db/models/index.js +++ b/db/models/index.js @@ -3,11 +3,23 @@ const Project = require('./project') const User = require('./user') const Article = require('./article') const Tag = require('./tag') +const Comment = require('./comment') +const Vote = require('./vote') +User.hasMany(Article) +User.hasMany(Comment) +User.hasMany(Vote) Project.hasMany(Task) Task.belongsTo(Project) +Article.hasMany(Comment) Article.hasMany(Tag) +Article.belongsTo(User) Tag.belongsTo(Article) +Comment.belongsTo(Article) +Comment.belongsTo(User) +Comment.hasMany(Vote) +Vote.belongsTo(Comment) +Vote.belongsTo(User) User.belongsToMany(Project, { through: 'projectUser' }) Project.hasMany(User) @@ -15,4 +27,4 @@ Project.hasMany(User) Task.belongsToMany(User, { through: 'userTask' }) User.hasMany(Task) -module.exports = { Task, Project, User, Article, Tag } +module.exports = { Task, Project, User, Article, Tag, Comment, Vote } diff --git a/db/models/vote.js b/db/models/vote.js new file mode 100644 index 0000000..820b8e9 --- /dev/null +++ b/db/models/vote.js @@ -0,0 +1,9 @@ +const Sequelize = require('sequelize') +const db = require('../db') + +const Vote = db.define('votes', { + upvote: Sequelize.INTEGER, + downvote: Sequelize.INTEGER, +}) + +module.exports = Vote diff --git a/db/seed.js b/db/seed.js index 15d123c..c5ae2b6 100755 --- a/db/seed.js +++ b/db/seed.js @@ -1,5 +1,5 @@ const db = require('../db') -const { Task, Project, User, Article, Tag } = require('./models') +const { Task, Project, User, Article, Tag, Comment, Vote } = require('./models') const testTasks = [ { @@ -28,7 +28,11 @@ const testUsers = [ const testArticles = [{ title: 'latest news', text: 'waddup?!' }] -const testTags = [{ name: 'dox', articleId: 1 }] +const testTags = [{ name: 'dox' }] + +const testComments = [{ text: 'pretty good' }] + +const testVotes = [{ upvote: 0, downvote: 1 }] async function runSeed() { await db.sync({ force: true }) @@ -52,10 +56,16 @@ async function runSeed() { await u1.addTasks([t1, t2]) await u2.addTask(t3) - const projects = await Project.bulkCreate(testProjects) - const tasks = await Task.bulkCreate(testTasks) - const articles = await Article.bulkCreate(testArticles) - const tags = await Tag.bulkCreate(testTags) + const a1 = await Article.create(testArticles[0]) + const t4 = await Tag.create(testTags[0]) + const c1 = await Comment.create(testComments[0]) + const v1 = await Vote.create(testVotes[0]) + + await a1.setUser(u1) + await a1.addTag(t4) + await a1.addComment(c1) + await c1.setUser(u2) + await c1.addVote(v1) console.log('seeded successfully') } catch (err) { -- 2.49.0 From d4d4f1a6e3dedcd044459ad0d902004882b50f80 Mon Sep 17 00:00:00 2001 From: data Date: Wed, 10 Jul 2019 20:46:05 +0200 Subject: [PATCH 3/4] add /remove tags to articles --- api/articles.js | 4 ++- api/tags.js | 64 +++++++++++++++++++++++++++++++++++++++------- db/models/index.js | 14 +++++++--- 3 files changed, 69 insertions(+), 13 deletions(-) diff --git a/api/articles.js b/api/articles.js index f7ef716..4639564 100644 --- a/api/articles.js +++ b/api/articles.js @@ -15,7 +15,9 @@ router.post('/', async (req, res, next) => { /* READ */ router.get('/', async (req, res, next) => { try { - const articles = await Article.findAll() + const articles = await Article.findAll({ + include: { model: Tag }, + }) res.send(articles) } catch (err) { next(err) diff --git a/api/tags.js b/api/tags.js index 8be62a7..ba873ea 100644 --- a/api/tags.js +++ b/api/tags.js @@ -5,8 +5,32 @@ module.exports = router /* CREATE */ router.post('/', async (req, res, next) => { try { - const tag = await Tag.create(req.body) - res.json(tag) + // find or create tag and add article relation + var tag = await Tag.findOne({ + where: { name: req.body.name }, + include: { model: Article }, + }) + if (!tag) { + const newTag = { name: req.body.name } + tag = await Tag.create(newTag, { include: { model: Article } }) + } + tag.addArticle(req.body.articleId) + + // find selected article and add tag relation + var article = await Article.findByPk(req.body.articleId, { + include: { model: Tag }, + }) + article.addTag(tag.id) + + // update article and tag after adding the relation + article = await Article.findByPk(req.body.articleId, { + include: { model: Tag }, + }) + tag = await Tag.findOne({ + where: { name: req.body.name }, + include: { model: Article }, + }) + res.json({ tag: tag, article: article }) } catch (err) { next(err) } @@ -15,7 +39,9 @@ router.post('/', async (req, res, next) => { /* READ */ router.get('/', async (req, res, next) => { try { - const tags = await Tag.findAll() + const tags = await Tag.findAll({ + include: { model: Article }, + }) res.send(tags) } catch (err) { next(err) @@ -29,14 +55,34 @@ router.get('/:id', async (req, res, next) => { } catch (err) { next(err) } -}) +}) // remove tag from article -/* UPDATE */ -router.put('/:id', async (req, res, next) => { +/* UPDATE */ router.put('/:id', async (req, res, next) => { try { - const tag = await Tag.findByPk(req.params.id) - await tag.update(req.body) - res.json(tag) + //const tag = await Tag.findByPk(req.params.id) + //await tag.update(req.body) + //res.json(tag) + + // find or create tag and add article relation + var tag = await Tag.findByPk(req.body.id, { + include: { model: Article }, + }) + tag.removeArticle(req.body.articleId) + + // find selected article and add tag relation + var article = await Article.findByPk(req.body.articleId, { + include: { model: Tag }, + }) + article.removeTag(tag.id) + + // update article and tag after adding the relation + article = await Article.findByPk(req.body.articleId, { + include: { model: Tag }, + }) + tag = await Tag.findByPk(req.body.id, { + include: { model: Article }, + }) + res.json({ tag: tag, article: article }) } catch (err) { next(err) } diff --git a/db/models/index.js b/db/models/index.js index dd8533e..ee7ca68 100755 --- a/db/models/index.js +++ b/db/models/index.js @@ -12,9 +12,9 @@ User.hasMany(Vote) Project.hasMany(Task) Task.belongsTo(Project) Article.hasMany(Comment) -Article.hasMany(Tag) +Article.belongsToMany(Tag, { through: 'articleTags' }) Article.belongsTo(User) -Tag.belongsTo(Article) +Tag.belongsToMany(Article, { through: 'articleTags' }) Comment.belongsTo(Article) Comment.belongsTo(User) Comment.hasMany(Vote) @@ -27,4 +27,12 @@ Project.hasMany(User) Task.belongsToMany(User, { through: 'userTask' }) User.hasMany(Task) -module.exports = { Task, Project, User, Article, Tag, Comment, Vote } +module.exports = { + Task, + Project, + User, + Article, + Tag, + Comment, + Vote, +} -- 2.49.0 From f56c686eb2f105047b15634415843d52e6e1da68 Mon Sep 17 00:00:00 2001 From: data Date: Sat, 13 Jul 2019 13:10:56 +0200 Subject: [PATCH 4/4] comment threading --- api/comments.js | 7 ++++--- db/models/index.js | 5 +++++ db/seed.js | 27 ++++++++++++++++++++++++--- package.json | 3 ++- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/api/comments.js b/api/comments.js index 54e4a69..d7964c7 100644 --- a/api/comments.js +++ b/api/comments.js @@ -3,11 +3,11 @@ const { Comment, User, Vote } = require('../db/models') module.exports = router - router.get('/', async (req, res, next) => { try { const comments = await Comment.findAll({ - attributes: ['id', 'text']}) + include: ['replies', 'user'], + }) res.send(comments) } catch (err) { next(err) @@ -17,7 +17,8 @@ router.get('/', async (req, res, next) => { router.get('/:id', async (req, res, next) => { try { const comment = await Comment.findByPk(req.params.id, { - attributes: ['id', 'text']}) + attributes: ['id', 'text'], + }) res.json(comment) } catch (err) { next(err) diff --git a/db/models/index.js b/db/models/index.js index ee7ca68..8cb8486 100755 --- a/db/models/index.js +++ b/db/models/index.js @@ -18,6 +18,11 @@ Tag.belongsToMany(Article, { through: 'articleTags' }) Comment.belongsTo(Article) Comment.belongsTo(User) Comment.hasMany(Vote) +Comment.belongsTo(Comment, { as: 'parent' }) +Comment.hasMany(Comment, { + as: { singular: 'reply', plural: 'replies' }, + foreignKey: 'parentId', +}) Vote.belongsTo(Comment) Vote.belongsTo(User) diff --git a/db/seed.js b/db/seed.js index c5ae2b6..0d1f755 100755 --- a/db/seed.js +++ b/db/seed.js @@ -30,7 +30,12 @@ const testArticles = [{ title: 'latest news', text: 'waddup?!' }] const testTags = [{ name: 'dox' }] -const testComments = [{ text: 'pretty good' }] +const tc1 = { text: 'pretty good' } +const tc2 = { text: 'yeah!' } +const tc3 = { text: 'could be more detailed tho' } +const tc4 = { text: 'BUT THE INSECTS' } +const tc5 = { text: 'HAHAHAHAHA' } +const tc6 = { text: 'oh shut up' } const testVotes = [{ upvote: 0, downvote: 1 }] @@ -58,14 +63,30 @@ async function runSeed() { const a1 = await Article.create(testArticles[0]) const t4 = await Tag.create(testTags[0]) - const c1 = await Comment.create(testComments[0]) + const c1 = await Comment.create(tc1) + const c2 = await Comment.create(tc2) + const c3 = await Comment.create(tc3) + const c4 = await Comment.create(tc4) + const c5 = await Comment.create(tc5) + const c6 = await Comment.create(tc6) const v1 = await Vote.create(testVotes[0]) await a1.setUser(u1) await a1.addTag(t4) - await a1.addComment(c1) + await a1.addComments(c1, c2, c3, c4, c5, c6) + await c1.setUser(u2) + await c2.setUser(u1) + await c3.setUser(u2) + await c4.setUser(u1) + await c5.setUser(u1) + await c6.setUser(u2) + await c1.addVote(v1) + await c1.addReply(2) + await c2.addReplies([c3, c4]) + await c5.setParent(c4) + await c6.setParent(c1) console.log('seeded successfully') } catch (err) { diff --git a/package.json b/package.json index 4433bf8..55302b9 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,8 @@ "morgan": "^1.9.1", "nodemon": "^1.19.1", "pg": "^7.11.0", - "sequelize": "^5.8.11" + "sequelize": "^5.8.11", + "uuid": "^3.3.2" }, "scripts": { "seed": "node db/seed.js", -- 2.49.0