summary refs log tree commit diff
path: root/src/api/routes/budgetRoutes.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/routes/budgetRoutes.js')
-rw-r--r--src/api/routes/budgetRoutes.js110
1 files changed, 79 insertions, 31 deletions
diff --git a/src/api/routes/budgetRoutes.js b/src/api/routes/budgetRoutes.js

index bcb9711..e522442 100644 --- a/src/api/routes/budgetRoutes.js +++ b/src/api/routes/budgetRoutes.js
@@ -3,7 +3,7 @@ import { requireUser, requireRole } from '#api/middlewares/index.js'; -import { UserType } from '#db/schemas/index.js'; +import { DbSpendHistory, UserType } from '#db/schemas/index.js'; import { RouteDescription, RouteMethod, @@ -11,14 +11,25 @@ import { } from '#api/RouteDescription.js'; import { getUserById } from '#db/dbAccess/index.js'; import { SafeNSoundError } from '#util/error.js'; +import Joi from 'joi'; + +const budgetModifySchema = new Joi.object({ + venue: Joi.string().required().max(100), + reason: Joi.string().required().max(500), + amount: Joi.number().required().min(0), + createdAt: Joi.forbidden() +}); /** * @type {RouteDescription} */ export const getBudgetByUserRoute = { - path: '/budget/:id', + path: '/user/:id/budget', methods: { get: new RouteMethod({ + exampleHeaders: { + Authorization: 'Bearer {{accessToken}}' + }, middlewares: [requireMonitor], description: 'Get the budget for a monitored user', async method(req, res) { @@ -33,40 +44,40 @@ export const getBudgetByUserRoute = { const user = await getUserById(req.params.id); res.send({ balance: user.balance }); } - }) - } -}; - -/** - * @type {RouteDescription} - */ -export const addBudgetByUserRoute = { - path: '/budget/:id/add', - methods: { - get: new RouteMethod({ - description: 'Add budget to a monitored user', + }), + patch: new RouteMethod({ + exampleHeaders: { + Authorization: 'Bearer {{accessToken}}' + }, + exampleBody: { + venue: 'Monitor 123', + reason: 'Just short for a coke to deal with diabetes', + amount: 0.15 + }, middlewares: [requireMonitor], + description: 'Add budget for a monitored user', async method(req, res) { - if (req.user.type !== UserType.ADMIN) { - if (!req.user.monitoredUsers.includes(req.params.id)) - throw new SafeNSoundError({ - errCode: 'UNAUTHORIZED', - message: - "You do not have permission to add budget to this user's account." - }); - } - - const user = await getUserById(req.params.id); - const amount = parseFloat(req.query.amount); - if (isNaN(amount) || amount <= 0) { + if ( + req.user.type !== UserType.ADMIN && + !req.user.monitoredUsers.includes(req.params.id) + ) throw new SafeNSoundError({ - errCode: 'INVALID_AMOUNT', - message: 'Invalid amount specified.' + errCode: 'UNAUTHORIZED', + message: + "You do not have permission to update this user's budget." }); - } - user.balance += amount; + let data = await budgetModifySchema.validateAsync(req.body); + const user = await getUserById(req.params.id); + user.balance += data.amount; + let histEntry = await DbSpendHistory.create({ + venue: data.venue, + reason: data.reason, + amount: data.amount + }); + user.spendHistory.push(histEntry._id); await user.save(); + res.send({ balance: user.balance }); } }) @@ -76,14 +87,51 @@ export const addBudgetByUserRoute = { /** * @type {RouteDescription} */ -export const getBudgetRoute = { +export const userBudgetRoute = { path: '/budget/@me', methods: { get: new RouteMethod({ + exampleHeaders: { + Authorization: 'Bearer {{accessToken}}' + }, middlewares: [requireUser], async method(req, res) { res.send({ currentBalance: req.user.balance }); } + }), + patch: new RouteMethod({ + exampleHeaders: { + Authorization: 'Bearer {{accessToken}}' + }, + exampleBody: { + venue: 'The Store', + reason: 'Bought a coke', + amount: 0.85 + }, + middlewares: [requireUser], + description: 'Spend part of budget', + async method(req, res) { + let data = await budgetModifySchema.validateAsync(req.body); + + if (data.amount > req.user.balance) { + throw new SafeNSoundError({ + errCode: 'INSUFFICIENT_FUNDS', + message: + 'You do not have enough funds to complete this transaction.' + }); + } + + req.user.balance -= data.amount; + let histEntry = await DbSpendHistory.create({ + venue: data.venue, + reason: data.reason, + amount: data.amount + }); + req.user.spendHistory.push(histEntry._id); + await req.user.save(); + + res.send({ balance: req.user.balance }); + } }) } };