upd
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: "crm.stream.graff.tech-server",
|
||||
name: "crm.stream.graff.tech-server:3001",
|
||||
exec_mode: "cluster",
|
||||
script: "yarn",
|
||||
args: "start",
|
||||
|
||||
+4
-4
@@ -19,17 +19,17 @@ const port = process.env.PORT || 3000;
|
||||
connectDB();
|
||||
|
||||
app.use(json());
|
||||
app.use(cors());
|
||||
app.use(cors({ origin: "*" }));
|
||||
|
||||
app.use("/app", authMiddleware, appRouter);
|
||||
app.use("/companies", authMiddleware, companiesRouter);
|
||||
app.use("/users", authMiddleware, usersRouter);
|
||||
app.use("/login", loginRouter);
|
||||
app.use("/registration", registrationRouter);
|
||||
app.use("/actions", actionsRouter);
|
||||
app.use("/builds", buildsRouter);
|
||||
app.use("/scheduled_sessions", scheduledSessionsRouter);
|
||||
app.use("/schedules", schedulesRouter);
|
||||
app.use("/app", authMiddleware, appRouter);
|
||||
app.use("/companies", authMiddleware, companiesRouter);
|
||||
app.use("/users", authMiddleware, usersRouter);
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server listening on port ${port}`);
|
||||
|
||||
@@ -16,10 +16,6 @@ const scheduleSchema = new Schema(
|
||||
type: Date,
|
||||
required: true,
|
||||
},
|
||||
endDate: {
|
||||
type: Date,
|
||||
required: true,
|
||||
},
|
||||
startTime: {
|
||||
type: String,
|
||||
required: true,
|
||||
@@ -28,6 +24,9 @@ const scheduleSchema = new Schema(
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
weekends: {
|
||||
type: [String],
|
||||
},
|
||||
sessionDuration: {
|
||||
type: Number,
|
||||
required: true,
|
||||
@@ -36,7 +35,7 @@ const scheduleSchema = new Schema(
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
sessionCount: {
|
||||
sessionsPerDay: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
|
||||
+100
-78
@@ -6,15 +6,15 @@ import Schedule from "../models/Schedule";
|
||||
import BuildUser from "../models/BuildUser";
|
||||
import User from "../models/User";
|
||||
|
||||
const companiesRouter = Router();
|
||||
const router = Router();
|
||||
|
||||
// companiesRouter.get("/", async (_req, res) => {
|
||||
// router.get("/", async (_req, res) => {
|
||||
// const companies = await Company.find();
|
||||
|
||||
// res.json(companies);
|
||||
// });
|
||||
|
||||
companiesRouter.get("/:id", async (req, res) => {
|
||||
router.get("/:id", async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied" });
|
||||
return;
|
||||
@@ -25,7 +25,7 @@ companiesRouter.get("/:id", async (req, res) => {
|
||||
res.json(company);
|
||||
});
|
||||
|
||||
companiesRouter.get("/:id/builds", async (req, res) => {
|
||||
router.get("/:id/builds", async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied" });
|
||||
return;
|
||||
@@ -37,7 +37,7 @@ companiesRouter.get("/:id/builds", async (req, res) => {
|
||||
res.json(builds);
|
||||
});
|
||||
|
||||
companiesRouter.get("/:id/users", async (req, res) => {
|
||||
router.get("/:id/users", async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied" });
|
||||
return;
|
||||
@@ -49,7 +49,7 @@ companiesRouter.get("/:id/users", async (req, res) => {
|
||||
res.json(users);
|
||||
});
|
||||
|
||||
companiesRouter.get("/:id/builds/:buildId/users", async (req, res) => {
|
||||
router.get("/:id/builds/:buildId/users", async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied" });
|
||||
return;
|
||||
@@ -69,44 +69,41 @@ companiesRouter.get("/:id/builds/:buildId/users", async (req, res) => {
|
||||
res.json(users);
|
||||
});
|
||||
|
||||
companiesRouter.get(
|
||||
"/:id/builds/:buildId/scheduled_sessions",
|
||||
async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied" });
|
||||
return;
|
||||
}
|
||||
router.get("/:id/builds/:buildId/scheduled_sessions", async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!req.query.date) {
|
||||
res.json({ error: "Query parameter `date` is required" });
|
||||
return;
|
||||
}
|
||||
if (!req.query.date) {
|
||||
res.json({ error: "Query parameter `date` is required" });
|
||||
return;
|
||||
}
|
||||
|
||||
const date = parseISO(req.query.date as string);
|
||||
const date = parseISO(req.query.date as string);
|
||||
|
||||
const company: any = await Company.findById(req.params.id).populate({
|
||||
path: "builds",
|
||||
const company: any = await Company.findById(req.params.id).populate({
|
||||
path: "builds",
|
||||
match: {
|
||||
_id: req.params.buildId,
|
||||
},
|
||||
populate: {
|
||||
path: "scheduledSessions",
|
||||
match: {
|
||||
_id: req.params.buildId,
|
||||
},
|
||||
populate: {
|
||||
path: "scheduledSessions",
|
||||
match: {
|
||||
startAt: {
|
||||
$gte: startOfDay(date),
|
||||
$lte: endOfDay(date),
|
||||
},
|
||||
startAt: {
|
||||
$gte: startOfDay(date),
|
||||
$lte: endOfDay(date),
|
||||
},
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const { scheduledSessions } = company.builds[0];
|
||||
const { scheduledSessions } = company.builds[0];
|
||||
|
||||
res.json(scheduledSessions);
|
||||
}
|
||||
);
|
||||
res.json(scheduledSessions);
|
||||
});
|
||||
|
||||
// companiesRouter.post(
|
||||
// router.post(
|
||||
// "/:id/builds/:buildId/scheduled_sessions",
|
||||
// async (req, res) => {
|
||||
// if (req.params.id != res.locals.user.companyId) {
|
||||
@@ -129,48 +126,45 @@ companiesRouter.get(
|
||||
// }
|
||||
// );
|
||||
|
||||
companiesRouter.put(
|
||||
"/:id/scheduled_sessions/:scheduledSessionId",
|
||||
async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied" });
|
||||
router.put("/:id/scheduled_sessions/:scheduledSessionId", async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied" });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const scheduledSession = await ScheduledSession.findById(
|
||||
req.params.scheduledSessionId
|
||||
);
|
||||
|
||||
const scheduledSessionAtSameTime = await ScheduledSession.findOne({
|
||||
startAt: scheduledSession?.startAt,
|
||||
userId: req.body.userId,
|
||||
});
|
||||
|
||||
if (scheduledSessionAtSameTime) {
|
||||
res.json({ error: "Scheduled session at same time" });
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const scheduledSession = await ScheduledSession.findById(
|
||||
req.params.scheduledSessionId
|
||||
);
|
||||
|
||||
const scheduledSessionAtSameTime = await ScheduledSession.findOne({
|
||||
startAt: scheduledSession?.startAt,
|
||||
userId: req.body.userId,
|
||||
});
|
||||
|
||||
if (scheduledSessionAtSameTime) {
|
||||
res.json({ error: "Scheduled session at same time" });
|
||||
return;
|
||||
const updatedScheduledSession = await ScheduledSession.findByIdAndUpdate(
|
||||
req.params.scheduledSessionId,
|
||||
req.body,
|
||||
{
|
||||
new: true,
|
||||
upsert: true,
|
||||
}
|
||||
);
|
||||
|
||||
const updatedScheduledSession = await ScheduledSession.findByIdAndUpdate(
|
||||
req.params.scheduledSessionId,
|
||||
req.body,
|
||||
{
|
||||
new: true,
|
||||
upsert: true,
|
||||
}
|
||||
);
|
||||
|
||||
res.json(updatedScheduledSession);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
res.json({ error });
|
||||
}
|
||||
res.json(updatedScheduledSession);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
res.json({ error });
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
companiesRouter.get(
|
||||
router.get(
|
||||
"/:id/builds/:buildId/scheduled_sessions/:scheduledSessionId/availableManagers",
|
||||
async (req, res) => {
|
||||
if (!req.query.startAt) {
|
||||
@@ -225,7 +219,7 @@ companiesRouter.get(
|
||||
}
|
||||
);
|
||||
|
||||
companiesRouter.get("/:id/builds/:buildId/schedules", async (req, res) => {
|
||||
router.get("/:id/builds/:buildId/schedules", async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied" });
|
||||
return;
|
||||
@@ -239,19 +233,47 @@ companiesRouter.get("/:id/builds/:buildId/schedules", async (req, res) => {
|
||||
res.json(schedules);
|
||||
});
|
||||
|
||||
companiesRouter.post("/:id/builds/:buildId/schedules", async (req, res) => {
|
||||
router.post("/:id/builds/:buildId/schedules", async (req, res) => {
|
||||
if (req.params.id != res.locals.user.companyId) {
|
||||
res.json({ error: "Access denied" });
|
||||
return;
|
||||
}
|
||||
|
||||
const schedule = await Schedule.create({
|
||||
companyId: req.params.id,
|
||||
buildId: req.params.buildId,
|
||||
...req.body,
|
||||
});
|
||||
|
||||
res.json(schedule);
|
||||
try {
|
||||
const schedule = await Schedule.create({
|
||||
companyId: req.params.id,
|
||||
buildId: req.params.buildId,
|
||||
...req.body,
|
||||
});
|
||||
res.json(schedule);
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
res.json({ error: error.message });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
router.get(
|
||||
"/:companyId/builds/:buildId/last_scheduled_session",
|
||||
async (req, res) => {
|
||||
const { companyId, buildId } = req.params;
|
||||
|
||||
console.log("companyId", companyId);
|
||||
console.log("buildId", buildId);
|
||||
|
||||
try {
|
||||
const lastScheduledSession = await ScheduledSession.findOne({
|
||||
companyId,
|
||||
buildId,
|
||||
}).sort({ startAt: -1 });
|
||||
|
||||
res.json(lastScheduledSession);
|
||||
} catch (error) {
|
||||
res.json({ error: (error as Error).message });
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const companiesRouter = router;
|
||||
|
||||
export default companiesRouter;
|
||||
|
||||
@@ -5,11 +5,13 @@ import Schedule from "../models/Schedule";
|
||||
import {
|
||||
addMinutes,
|
||||
areIntervalsOverlapping,
|
||||
differenceInMinutes,
|
||||
endOfDay,
|
||||
isValid,
|
||||
parseISO,
|
||||
startOfDay,
|
||||
} from "date-fns";
|
||||
import { isValidObjectId } from "mongoose";
|
||||
|
||||
const scheduledSessionsRouter = Router();
|
||||
|
||||
@@ -23,6 +25,15 @@ scheduledSessionsRouter.get("/", async (_req, res) => {
|
||||
});
|
||||
|
||||
scheduledSessionsRouter.get("/:id", async (req, res) => {
|
||||
const scheduledSessionId = req.params.id;
|
||||
|
||||
if (!isValidObjectId(scheduledSessionId)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Invalid session ID value",
|
||||
});
|
||||
}
|
||||
|
||||
const scheduledSession = await ScheduledSession.findById(req.params.id);
|
||||
|
||||
res.json(scheduledSession);
|
||||
@@ -41,6 +52,14 @@ scheduledSessionsRouter.get("/builds/:buildId", async (req, res) => {
|
||||
|
||||
const buildId = req.params.buildId;
|
||||
const date = req.query.date as string;
|
||||
|
||||
if (!isValidObjectId(buildId)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Invalid build ID value",
|
||||
});
|
||||
}
|
||||
|
||||
const scheduledSessions = await ScheduledSession.find({
|
||||
buildId,
|
||||
startAt: {
|
||||
@@ -77,13 +96,19 @@ scheduledSessionsRouter.get("/:buildId", async (req, res) => {
|
||||
});
|
||||
|
||||
scheduledSessionsRouter.post("/", async (req, res) => {
|
||||
const { buildId, startAt, client } = req.body;
|
||||
const { buildId, startAt, client, duration } = req.body;
|
||||
|
||||
if (!isValidObjectId(buildId)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Invalid build ID value",
|
||||
});
|
||||
}
|
||||
|
||||
if (!buildId || !startAt) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message:
|
||||
"Parameters `buildId`, `startAt` are required!", // Параметры `compamyId`, `buildId`, `startAt`, `client` обязательны!
|
||||
message: "Parameters `buildId`, `startAt` are required!", // Параметры `compamyId`, `buildId`, `startAt`, `client` обязательны!
|
||||
});
|
||||
}
|
||||
|
||||
@@ -96,6 +121,65 @@ scheduledSessionsRouter.post("/", async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
const build = await Build.findById(buildId);
|
||||
|
||||
if (!build) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "An assembly with such a `buildId` was not found", // Сборка с таким `buildId` не найдена
|
||||
});
|
||||
}
|
||||
|
||||
if (duration) {
|
||||
const scheduledSessions = await ScheduledSession.find({
|
||||
buildId,
|
||||
startAt: {
|
||||
$gte: startOfDay(startAtISO),
|
||||
$lte: endOfDay(startAtISO),
|
||||
},
|
||||
});
|
||||
|
||||
const endAtISO = addMinutes(startAtISO, duration);
|
||||
|
||||
if (scheduledSessions.length) {
|
||||
const overlappingSessions = [];
|
||||
|
||||
for (const session of scheduledSessions) {
|
||||
if (
|
||||
areIntervalsOverlapping(
|
||||
{
|
||||
start: session.startAt,
|
||||
end: addMinutes(session.endAt, duration),
|
||||
},
|
||||
{ start: startAtISO, end: endAtISO }
|
||||
)
|
||||
) {
|
||||
overlappingSessions.push(session);
|
||||
}
|
||||
}
|
||||
|
||||
if (overlappingSessions.length >= build.sessionLimit) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message:
|
||||
"It is not possible to create a session because it overlaps with the time of another session", // Невозможно создать сеанс, поскольку он перекрывается со временем другого сеанса.
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const scheduledSession = await ScheduledSession.create({
|
||||
buildId,
|
||||
startAt: startAtISO,
|
||||
endAt: endAtISO,
|
||||
});
|
||||
|
||||
return res.json({
|
||||
status: "success",
|
||||
scheduledSessionId: scheduledSession.id,
|
||||
url: `https://stream.graff.tech/scheduled/${scheduledSession.id}`,
|
||||
});
|
||||
}
|
||||
|
||||
const schedule = await Schedule.findOne({
|
||||
buildId,
|
||||
startDate: { $lte: startAtISO },
|
||||
@@ -109,15 +193,6 @@ scheduledSessionsRouter.post("/", async (req, res) => {
|
||||
});
|
||||
}
|
||||
|
||||
const build = await Build.findById(buildId);
|
||||
|
||||
if (!build) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "An assembly with such a `buildId` was not found", // Сборка с таким `buildId` не найдена
|
||||
});
|
||||
}
|
||||
|
||||
const scheduledSessions = await ScheduledSession.find({
|
||||
buildId,
|
||||
startAt: {
|
||||
@@ -163,18 +238,103 @@ scheduledSessionsRouter.post("/", async (req, res) => {
|
||||
|
||||
res.json({
|
||||
status: "success",
|
||||
scheduledSessionId: scheduledSession.id,
|
||||
url: `https://stream.graff.tech/scheduled/${scheduledSession.id}`,
|
||||
});
|
||||
});
|
||||
|
||||
scheduledSessionsRouter.put("/:id", async (req, res) => {
|
||||
const scheduledSession = await ScheduledSession.findByIdAndUpdate(
|
||||
req.params.id,
|
||||
req.body,
|
||||
{ new: true, upsert: true }
|
||||
const scheduledSessionId = req.params.id;
|
||||
|
||||
if (!isValidObjectId(scheduledSessionId)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Invalid session ID value",
|
||||
});
|
||||
}
|
||||
|
||||
let { startAt, duration }: { startAt: string; duration: number } = req.body;
|
||||
|
||||
if (!startAt && !duration) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Parameter `startAt` or `duration` is required, or both",
|
||||
});
|
||||
}
|
||||
|
||||
if (startAt && !isValid(parseISO(startAt))) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Invalid value of the `startAt` parameter",
|
||||
});
|
||||
}
|
||||
|
||||
function isInteger(num: number) {
|
||||
return (num ^ 0) === num;
|
||||
}
|
||||
|
||||
if (duration && !isInteger(duration)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Parameter `duration` is not an integer",
|
||||
});
|
||||
}
|
||||
|
||||
const scheduledSession = await ScheduledSession.findById(scheduledSessionId);
|
||||
|
||||
if (!scheduledSession) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Session with this ID not found",
|
||||
});
|
||||
}
|
||||
|
||||
if (!duration) {
|
||||
duration = differenceInMinutes(
|
||||
scheduledSession.endAt,
|
||||
scheduledSession.startAt
|
||||
);
|
||||
}
|
||||
|
||||
const endAt = addMinutes(
|
||||
(startAt && parseISO(startAt.toString())) || scheduledSession.startAt,
|
||||
duration
|
||||
);
|
||||
|
||||
res.json(scheduledSession);
|
||||
try {
|
||||
const scheduledSession = await ScheduledSession.findByIdAndUpdate(
|
||||
scheduledSessionId,
|
||||
{ startAt, endAt },
|
||||
{ new: true }
|
||||
);
|
||||
|
||||
res.json({ status: "success", scheduledSession });
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
res.json({ status: "error", message: error.message });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
scheduledSessionsRouter.delete("/:id", async (req, res) => {
|
||||
const scheduledSessionId = req.params.id;
|
||||
|
||||
if (!isValidObjectId(scheduledSessionId)) {
|
||||
return res.json({
|
||||
status: "error",
|
||||
message: "Invalid session ID value",
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
await ScheduledSession.findByIdAndDelete(scheduledSessionId);
|
||||
|
||||
res.json({ status: "success" });
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
res.json({ status: "error", message: error.message });
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default scheduledSessionsRouter;
|
||||
|
||||
Reference in New Issue
Block a user