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 });
+ }
})
}
};
|