Spaces:
Paused
Paused
added rejection limit
Browse files- prisma/schema.prisma +2 -0
- src/controllers/admin.js +27 -4
- src/controllers/threads.js +18 -2
prisma/schema.prisma
CHANGED
|
@@ -57,6 +57,7 @@ model ExchangeThread {
|
|
| 57 |
status String @default("PENDING") // PENDING | ACCEPTED | REJECTED
|
| 58 |
giverAccepted Boolean @default(false)
|
| 59 |
receiverAccepted Boolean @default(false)
|
|
|
|
| 60 |
createdAt DateTime @default(now())
|
| 61 |
updatedAt DateTime @updatedAt
|
| 62 |
|
|
@@ -119,5 +120,6 @@ model SystemSettings {
|
|
| 119 |
id String @id @default("singleton")
|
| 120 |
cronExpression String @default("*/10 * * * *")
|
| 121 |
matchAmount Int @default(2)
|
|
|
|
| 122 |
updatedAt DateTime @updatedAt
|
| 123 |
}
|
|
|
|
| 57 |
status String @default("PENDING") // PENDING | ACCEPTED | REJECTED
|
| 58 |
giverAccepted Boolean @default(false)
|
| 59 |
receiverAccepted Boolean @default(false)
|
| 60 |
+
rejectedByWorkspaceId String?
|
| 61 |
createdAt DateTime @default(now())
|
| 62 |
updatedAt DateTime @updatedAt
|
| 63 |
|
|
|
|
| 120 |
id String @id @default("singleton")
|
| 121 |
cronExpression String @default("*/10 * * * *")
|
| 122 |
matchAmount Int @default(2)
|
| 123 |
+
rejectLimit Int @default(5)
|
| 124 |
updatedAt DateTime @updatedAt
|
| 125 |
}
|
src/controllers/admin.js
CHANGED
|
@@ -73,7 +73,30 @@ const getUsers = async (req, res) => {
|
|
| 73 |
}
|
| 74 |
}
|
| 75 |
});
|
| 76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
} catch (err) {
|
| 78 |
console.error(err);
|
| 79 |
res.status(500).json({ error: 'Server error' });
|
|
@@ -212,12 +235,12 @@ const getSettings = async (req, res) => {
|
|
| 212 |
};
|
| 213 |
|
| 214 |
const updateSettings = async (req, res) => {
|
| 215 |
-
const { cronExpression, matchAmount } = req.body;
|
| 216 |
try {
|
| 217 |
const settings = await prisma.systemSettings.upsert({
|
| 218 |
where: { id: 'singleton' },
|
| 219 |
-
update: { cronExpression, matchAmount },
|
| 220 |
-
create: { id: 'singleton', cronExpression, matchAmount },
|
| 221 |
});
|
| 222 |
|
| 223 |
// Also re-initialize the cron job with the new expression
|
|
|
|
| 73 |
}
|
| 74 |
}
|
| 75 |
});
|
| 76 |
+
|
| 77 |
+
const usersWithCounts = await Promise.all(users.map(async (u) => {
|
| 78 |
+
let rejectedIn = 0;
|
| 79 |
+
let rejectedOut = 0;
|
| 80 |
+
|
| 81 |
+
if (u.teamMemberships && u.teamMemberships.length > 0) {
|
| 82 |
+
const wsId = u.teamMemberships[0].workspaceId;
|
| 83 |
+
const rejectedThreads = await prisma.exchangeThread.findMany({
|
| 84 |
+
where: { rejectedByWorkspaceId: wsId, status: 'REJECTED' }
|
| 85 |
+
});
|
| 86 |
+
for (const t of rejectedThreads) {
|
| 87 |
+
if (t.receiverWorkspaceId === wsId) rejectedIn++;
|
| 88 |
+
if (t.giverWorkspaceId === wsId) rejectedOut++;
|
| 89 |
+
}
|
| 90 |
+
}
|
| 91 |
+
|
| 92 |
+
return {
|
| 93 |
+
...u,
|
| 94 |
+
rejectedIn,
|
| 95 |
+
rejectedOut
|
| 96 |
+
};
|
| 97 |
+
}));
|
| 98 |
+
|
| 99 |
+
res.json({ users: usersWithCounts });
|
| 100 |
} catch (err) {
|
| 101 |
console.error(err);
|
| 102 |
res.status(500).json({ error: 'Server error' });
|
|
|
|
| 235 |
};
|
| 236 |
|
| 237 |
const updateSettings = async (req, res) => {
|
| 238 |
+
const { cronExpression, matchAmount, rejectLimit } = req.body;
|
| 239 |
try {
|
| 240 |
const settings = await prisma.systemSettings.upsert({
|
| 241 |
where: { id: 'singleton' },
|
| 242 |
+
update: { cronExpression, matchAmount, rejectLimit },
|
| 243 |
+
create: { id: 'singleton', cronExpression, matchAmount, rejectLimit },
|
| 244 |
});
|
| 245 |
|
| 246 |
// Also re-initialize the cron job with the new expression
|
src/controllers/threads.js
CHANGED
|
@@ -83,6 +83,9 @@ const getThreads = async (req, res) => {
|
|
| 83 |
else if (filter === 'out') {
|
| 84 |
where = { giverWorkspaceId: wsId, status: { not: 'REJECTED' } };
|
| 85 |
}
|
|
|
|
|
|
|
|
|
|
| 86 |
|
| 87 |
const threads = await prisma.exchangeThread.findMany({
|
| 88 |
where,
|
|
@@ -105,7 +108,10 @@ const getThreads = async (req, res) => {
|
|
| 105 |
orderBy: { updatedAt: 'desc' },
|
| 106 |
});
|
| 107 |
|
| 108 |
-
|
|
|
|
|
|
|
|
|
|
| 109 |
} catch (err) {
|
| 110 |
console.error(err);
|
| 111 |
res.status(500).json({ error: 'Server error' });
|
|
@@ -176,9 +182,19 @@ const updateThreadStatus = async (req, res) => {
|
|
| 176 |
let receiverAccepted = thread.receiverAccepted;
|
| 177 |
|
| 178 |
if (status === 'REJECTED') {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 179 |
newStatus = 'REJECTED';
|
| 180 |
newStage = 'NEW';
|
| 181 |
-
updateData = { status: newStatus, stage: newStage };
|
| 182 |
} else if (status === 'ACCEPTED') {
|
| 183 |
if (isGiver) giverAccepted = true;
|
| 184 |
if (isReceiver) receiverAccepted = true;
|
|
|
|
| 83 |
else if (filter === 'out') {
|
| 84 |
where = { giverWorkspaceId: wsId, status: { not: 'REJECTED' } };
|
| 85 |
}
|
| 86 |
+
else if (filter === 'rejected') {
|
| 87 |
+
where = { rejectedByWorkspaceId: wsId, status: 'REJECTED' };
|
| 88 |
+
}
|
| 89 |
|
| 90 |
const threads = await prisma.exchangeThread.findMany({
|
| 91 |
where,
|
|
|
|
| 108 |
orderBy: { updatedAt: 'desc' },
|
| 109 |
});
|
| 110 |
|
| 111 |
+
let settings = await prisma.systemSettings.findUnique({ where: { id: 'singleton' } });
|
| 112 |
+
const rejectLimit = settings ? settings.rejectLimit : 5;
|
| 113 |
+
|
| 114 |
+
res.json({ threads, workspaceId: wsId, rejectLimit });
|
| 115 |
} catch (err) {
|
| 116 |
console.error(err);
|
| 117 |
res.status(500).json({ error: 'Server error' });
|
|
|
|
| 182 |
let receiverAccepted = thread.receiverAccepted;
|
| 183 |
|
| 184 |
if (status === 'REJECTED') {
|
| 185 |
+
let settings = await prisma.systemSettings.findUnique({ where: { id: 'singleton' } });
|
| 186 |
+
const rejectLimit = settings ? settings.rejectLimit : 5;
|
| 187 |
+
|
| 188 |
+
const rejectedCount = await prisma.exchangeThread.count({
|
| 189 |
+
where: { rejectedByWorkspaceId: member.workspaceId, status: 'REJECTED' }
|
| 190 |
+
});
|
| 191 |
+
if (rejectedCount >= rejectLimit) {
|
| 192 |
+
return res.status(403).json({ error: `Cannot reject more than ${rejectLimit} requests` });
|
| 193 |
+
}
|
| 194 |
+
|
| 195 |
newStatus = 'REJECTED';
|
| 196 |
newStage = 'NEW';
|
| 197 |
+
updateData = { status: newStatus, stage: newStage, rejectedByWorkspaceId: member.workspaceId };
|
| 198 |
} else if (status === 'ACCEPTED') {
|
| 199 |
if (isGiver) giverAccepted = true;
|
| 200 |
if (isReceiver) receiverAccepted = true;
|