Skip to content

Commit

Permalink
added barter payment initiator method with redis queue
Browse files Browse the repository at this point in the history
  • Loading branch information
abhiraj-ku committed Oct 2, 2024
1 parent 1c86135 commit 92e5937
Show file tree
Hide file tree
Showing 6 changed files with 150 additions and 4 deletions.
9 changes: 8 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,8 @@
node_modules
node_modules
*.git
dist
build
package-lock.json
.npm
*.vscode
*.tmp
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@


#ignore specific file
src/utils/constants.js
src/utils/constants.js

*.vscode

build
dist
.npm
99 changes: 99 additions & 0 deletions src/controllers/barterSettlement.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,102 @@ Note: This is completely an Experiment Feature
// TODO: Implement the two step barter payment settlemnt
// TODO: Step 1 is to generate the barter payment by debtor
// TODO: Step 2 is to reject or approve barter settlement by debtor based on their risk appetite

const validateBarterPayInput = require("../helpers/validateBarterPay");
const groupModel = require("../models/groupModel");
const User = require("../models/userModel");
const redisClient = require("./redisServer");
const { promisify } = require("util");
const expireAsync = promisify(redisClient.expire).bind(redisClient);
const queueBarterNotification = require("../services/emailQueueProducer");

const setAsync = promisify(redisClient.set).bind(redisClient);

async function tempUserDataRedis(
debtorId,
creditorId,
groupId,
amount,
barterType
) {
try {
const tempUserData = json.Stringify({
debtorId,
creditorId,
groupId,
amount,
barterType,
status: "pending",
});

await setAsync("tempData", tempUserData);
const deleteAfter = process.env.TEMP_DATA_STORE || 300;
await expireAsync(debtorId, 300);
console.log(`Barter details saved to redis for ${deleteAfter} seconds `);
} catch (error) {
console.error(`Error while saving barter data to redis..`, error);
}
}

// Debtor route
// Debtor initiates the barter option
module.exports.initiateBarterPayment = async (req, res) => {
const { debtorId, groupId, amount, barterType } = req.body;
const creditorId = req.user._id; // the person to whom payment is made

const validationErrors = validateBarterPayInput(
debtorId,
creditorId,
groupId,
amount,
barterType
);

if (validateInput.size > 0) {
return res
.status(400)
.json({ message: "Valiation error in bPay", error: validationErrors });
}
try {
if (amount > req.user.riskApetite) {
return res
.status(400)
.json({ message: "Barter amount exceeds your risk apetite" });
}

// Fetch group and creditor from the database
const group = await groupModel.findById(groupId);
const creditor = await User.findById(creditorId);

if (!group) {
return res.status(404).json({ message: "Group not found." });
}

if (!creditor) {
return res.status(404).json({ message: "Creditor not found." });
}

if (amount > group.maxBarterAmount) {
return res.status(400).json({
message: "Amount exceeds group's barter cap.",
});
}
// Mail the creditor to approve the payment
const mailOptions = {
from: `"SplitBhai Team" <backend.team@splitbhai.com>`,
to: creditor.email,
subject: "New Barter Request",
text: `You have a new barter request from ${req.user.name} for ${amount}. Barter Type: ${barterType}`,
};
await queueBarterNotification(mailOptions);
await tempUserDataRedis(debtorId, creditorId, groupId, amount, barterType);

res.status(201).json({ message: "Barter request initiated successfully." });
} catch (error) {
res.status(500).json({ message: "Server error.", error: err.message });
}
};

// TODO: Creditor approval route implementation
// Creditor "reject","confirm" the barter payment initiated
module.exports.respBarter = async (req, res) => {};
34 changes: 34 additions & 0 deletions src/helpers/validateBarterPay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const validator = require("validator");
const { isMongoId, isFloat, isEmpty } = validator;

function validateBarterPayInput(creditorID, groupID, amount, barterType) {
const errors = new Map();

// Validate creditor ID
if (!isMongoId(creditorID)) {
errors.set("creditorID", "Invalid creditor ID");
}
// Validate Debtor ID
if (!isMongoId(debtorId)) {
errors.set("debtorID", "Invalid debtor ID");
}

// Validate group ID
if (!isMongoId(groupId)) {
errors.set("groupId", "Invalid group ID");
}

// Validate amount
if (!isFloat(amount.toString(), { min: 0 })) {
errors.set("amount", "Amount must be a positive number.");
}

// Validate barterType
if (isEmpty(barterType)) {
errors.set("barterType", "Barter type is required.");
}

return errors;
}

module.exports = validateBarterPayInput;
2 changes: 1 addition & 1 deletion src/models/userModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const userSchema = new mongoose.Schema({
ref: "Event",
},
],
rislApetite: {
riskApetite: {
type: Number,
required: true,
min: 0,
Expand Down
2 changes: 1 addition & 1 deletion src/services/emailServices.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ async function storeuser(name, email) {
await setAsync(email, userData);

const ttl = process.env.REDIS_TTL || 300;
await expireAsync(email, 120);
await expireAsync(email, 300);

console.log(`User details saved to redis for ${ttl} seconds `);
} catch (error) {
Expand Down

0 comments on commit 92e5937

Please sign in to comment.