Skip to content

Commit

Permalink
🥅 add error handler
Browse files Browse the repository at this point in the history
  • Loading branch information
thinktapper committed Nov 20, 2022
1 parent 8bde4a1 commit 1a53b3d
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 16 deletions.
20 changes: 20 additions & 0 deletions prisma/migrations/20221120122140_uniques/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
Warnings:
- A unique constraint covering the columns `[id,organizerId]` on the table `Feast` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[id,shepherdId]` on the table `Herd` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[id,feastId,googleId]` on the table `Place` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[id,userId,placeId]` on the table `Vote` will be added. If there are existing duplicate values, this will fail.
*/
-- CreateIndex
CREATE UNIQUE INDEX "Feast_id_organizerId_key" ON "Feast"("id", "organizerId");

-- CreateIndex
CREATE UNIQUE INDEX "Herd_id_shepherdId_key" ON "Herd"("id", "shepherdId");

-- CreateIndex
CREATE UNIQUE INDEX "Place_id_feastId_googleId_key" ON "Place"("id", "feastId", "googleId");

-- CreateIndex
CREATE UNIQUE INDEX "Vote_id_userId_placeId_key" ON "Vote"("id", "userId", "placeId");
8 changes: 8 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ model Feast {
closed Boolean @default(false)
winner Place? @relation(name: "winner", fields: [winnerId], references: [id])
winnerId String?
@@unique([id, organizerId])
}

model Herd {
Expand All @@ -58,6 +60,8 @@ model Herd {
members User[] @relation(name: "herds")
feasts Feast[]
@@unique([id, shepherdId])
}

model Place {
Expand All @@ -79,6 +83,8 @@ model Place {
votes Vote[]
wonFeasts Feast[] @relation(name: "winner")
@@unique([id, feastId, googleId])
}

model Vote {
Expand All @@ -91,6 +97,8 @@ model Vote {
place Place @relation(fields: [placeId], references: [id])
placeId String
voteType VoteType
@@unique([id, userId, placeId])
}

enum VoteType {
Expand Down
83 changes: 83 additions & 0 deletions src/handlers/herd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import prisma from '../db'

// Get all herds
export const getAllHerds = async (req, res) => {
const user = await prisma.user.findUnique({
where: {
id: req.user.id,
},
include: {
herds: true,
},
})

res.json({ ok: true, herds: user.herds })
}

// Get created herds
export const getShepHerds = async (req, res) => {
const user = await prisma.user.findUnique({
where: {
id: req.user.id,
},
include: {
shepHerds: true,
},
})

res.json({ ok: true, data: { shepHerds: user.shepHerds } })
}

// Get one herd
export const getHerd = async (req, res) => {
const id = req.params.id
const herd = await prisma.herd.findFirst({
where: {
id,
members: {
some: {
id: req.user.id,
},
},
},
})
res.json({ ok: true, data: { herd } })
}

// Create a herd
export const createHerd = async (req, res) => {
const herd = await prisma.herd.create({
data: {
name: req.body.name,
shepherdId: req.user.id,
},
})
res.json({ ok: true, data: { herd } })
}

// Update a herd
export const updateHerd = async (req, res) => {
const updated = await prisma.herd.update({
where: {
id_shepherdId: {
id: req.params.id,
shepherdId: req.user.id,
},
},
data: req.body,
})
res.json({ ok: true, data: { updated } })
}

// Delete a herd
export const deleteHerd = async (req, res) => {
const deleted = await prisma.herd.delete({
where: {
id_shepherdId: {
id: req.params.id,
shepherdId: req.user.id,
},
},
})
res.json({ ok: true, data: { deleted } })
}
27 changes: 16 additions & 11 deletions src/handlers/user.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import prisma from '../db'
import { comparePwds, hashPwd, createJWT } from '../modules/auth'

export const signup = async (req, res) => {
const hashedPwd = await hashPwd(req.body.password)
const user = await prisma.user.create({
data: {
username: req.body.username,
email: req.body.email,
password: hashedPwd,
},
})
export const signup = async (req, res, next) => {
try {
const hashedPwd = await hashPwd(req.body.password)
const user = await prisma.user.create({
data: {
username: req.body.username,
email: req.body.email,
password: hashedPwd,
},
})

const token = createJWT(user)
res.json({ ok: true, token })
const token = createJWT(user)
res.json({ ok: true, token })
} catch (err) {
err.type = 'input'
next(err)
}
}

export const login = async (req, res) => {
Expand Down
23 changes: 18 additions & 5 deletions src/router.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,35 @@
import { Router } from 'express'
import { body, oneOf, validationResult } from 'express-validator'
import {
createHerd,
deleteHerd,
getAllHerds,
getHerd,
getShepHerds,
updateHerd,
} from './handlers/herd'
import { handleInputErrors } from './modules/middleware'

const router = Router()

// HERD
router.get('/herd', () => {})
router.get('/herd/:id', () => {})
router.get('/herd', getShepHerds)
router.get('/herd/:id', getHerd)
router.put(
'/herd/:id',
body('name').optional(),
body('members').optional(),
body('feasts').optional(),
handleInputErrors,
() => {},
updateHerd,
)
router.post(
'/herd',
body('name').exists().isString(),
handleInputErrors,
() => {},
createHerd,
)
router.delete('/herd/:id', () => {})
router.delete('/herd/:id', deleteHerd)

// FEAST
router.get('/feast', (req, res) => {
Expand Down Expand Up @@ -64,4 +72,9 @@ router.put('/vote/:id', () => {})
router.post('/vote', () => {})
router.delete('/vote/:id', () => {})

router.use((err, req, res, next) => {
console.log(err)
res.json({ ok: false, message: 'Oops, DB error' })
})

export default router
10 changes: 10 additions & 0 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,14 @@ app.use('/api', protect, router)
app.post('/user', signup)
app.post('/login', login)

app.use((err, req, res, next) => {
if (err.type === 'auth') {
res.json({ ok: false, message: 'Unauthorized' })
} else if (err.type === 'input') {
res.json({ ok: false, message: 'Invalid input' })
} else {
res.json({ ok: false, message: 'Something went wrong' })
}
})

export default app

0 comments on commit 1a53b3d

Please sign in to comment.