8aef00ab05
CI / Generate TypeScript types (push) Successful in 21s
CI / Build server (push) Successful in 25s
CI / Server unit tests (push) Successful in 55s
CI / Build client (push) Successful in 33s
CI / Playwright E2E tests (push) Successful in 1m20s
CI / Build and push Docker image (push) Successful in 35s
CI / Notify (push) Successful in 2s
157 lines
6.6 KiB
TypeScript
157 lines
6.6 KiB
TypeScript
import express, { Request } from "express";
|
|
import { getLogin } from "../auth";
|
|
import { parseToken } from "../utils";
|
|
import { getWebsocket } from "../websocket";
|
|
import { createGroup, deleteGroup, addGroupMember, removeGroupMember, updateGroupMember, setGroupState, updateGroupTimes, updateGroupFees } from "../groups";
|
|
import { GroupState } from "../../../types/gen/types.gen";
|
|
|
|
const router = express.Router();
|
|
|
|
function broadcastExtra(data: any) {
|
|
getWebsocket().emit("message", data);
|
|
}
|
|
|
|
router.post("/create", async (req: Request, res, next) => {
|
|
const login = getLogin(parseToken(req));
|
|
const { name } = req.body ?? {};
|
|
if (!name || typeof name !== 'string') {
|
|
return res.status(400).json({ error: 'Nebyl předán název skupiny' });
|
|
}
|
|
try {
|
|
const data = await createGroup(login, name);
|
|
broadcastExtra(data);
|
|
res.status(200).json(data);
|
|
} catch (e: any) { next(e); }
|
|
});
|
|
|
|
router.post("/delete", async (req: Request, res, next) => {
|
|
const login = getLogin(parseToken(req));
|
|
const { id } = req.body ?? {};
|
|
if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' });
|
|
try {
|
|
const data = await deleteGroup(login, id);
|
|
broadcastExtra(data);
|
|
res.status(200).json(data);
|
|
} catch (e: any) { next(e); }
|
|
});
|
|
|
|
router.post("/addMember", async (req: Request, res, next) => {
|
|
const login = getLogin(parseToken(req));
|
|
const { id, login: targetLogin } = req.body ?? {};
|
|
if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' });
|
|
if (targetLogin !== undefined && (typeof targetLogin !== 'string' || targetLogin.trim() === '')) {
|
|
return res.status(400).json({ error: 'Neplatný login uživatele' });
|
|
}
|
|
const target = targetLogin ?? login;
|
|
try {
|
|
const data = await addGroupMember(login, id, target);
|
|
broadcastExtra(data);
|
|
res.status(200).json(data);
|
|
} catch (e: any) { next(e); }
|
|
});
|
|
|
|
router.post("/removeMember", async (req: Request, res, next) => {
|
|
const login = getLogin(parseToken(req));
|
|
const { id, login: targetLogin } = req.body ?? {};
|
|
if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' });
|
|
if (!targetLogin) return res.status(400).json({ error: 'Nebyl předán login uživatele' });
|
|
try {
|
|
const data = await removeGroupMember(login, id, targetLogin);
|
|
broadcastExtra(data);
|
|
res.status(200).json(data);
|
|
} catch (e: any) { next(e); }
|
|
});
|
|
|
|
router.post("/updateMember", async (req: Request, res, next) => {
|
|
const login = getLogin(parseToken(req));
|
|
const { id, login: targetLogin, amount, note, surchargeText, surchargeAmount } = req.body ?? {};
|
|
if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' });
|
|
if (!targetLogin) return res.status(400).json({ error: 'Nebyl předán login uživatele' });
|
|
const patch: Record<string, any> = {};
|
|
if (amount !== undefined) {
|
|
if (!Number.isInteger(amount) || amount < 0) {
|
|
return res.status(400).json({ error: 'Neplatná částka' });
|
|
}
|
|
patch.amount = amount;
|
|
}
|
|
if (note !== undefined) {
|
|
if (typeof note !== 'string') return res.status(400).json({ error: 'Neplatná poznámka' });
|
|
patch.note = note;
|
|
}
|
|
if (surchargeText !== undefined) {
|
|
if (typeof surchargeText !== 'string') return res.status(400).json({ error: 'Neplatný text příplatku' });
|
|
patch.surchargeText = surchargeText;
|
|
}
|
|
if (surchargeAmount !== undefined) {
|
|
if (!Number.isInteger(surchargeAmount) || surchargeAmount < 0) {
|
|
return res.status(400).json({ error: 'Neplatná výše příplatku' });
|
|
}
|
|
patch.surchargeAmount = surchargeAmount;
|
|
}
|
|
try {
|
|
const data = await updateGroupMember(login, id, targetLogin, patch);
|
|
broadcastExtra(data);
|
|
res.status(200).json(data);
|
|
} catch (e: any) { next(e); }
|
|
});
|
|
|
|
router.post("/setState", async (req: Request, res, next) => {
|
|
const login = getLogin(parseToken(req));
|
|
const { id, state } = req.body ?? {};
|
|
if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' });
|
|
if (!state || !Object.values(GroupState).includes(state)) {
|
|
return res.status(400).json({ error: 'Neplatný stav skupiny' });
|
|
}
|
|
try {
|
|
const data = await setGroupState(login, id, state as GroupState);
|
|
broadcastExtra(data);
|
|
res.status(200).json(data);
|
|
} catch (e: any) { next(e); }
|
|
});
|
|
|
|
router.post("/updateFees", async (req: Request, res, next) => {
|
|
const login = getLogin(parseToken(req));
|
|
const { id, fees, shipping, tip, discountType, discountValue } = req.body ?? {};
|
|
if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' });
|
|
if (fees !== undefined && (!Number.isInteger(fees) || fees < 0)) {
|
|
return res.status(400).json({ error: 'Neplatná výše poplatků' });
|
|
}
|
|
if (shipping !== undefined && (!Number.isInteger(shipping) || shipping < 0)) {
|
|
return res.status(400).json({ error: 'Neplatná výše dopravy' });
|
|
}
|
|
if (tip !== undefined && (!Number.isInteger(tip) || tip < 0)) {
|
|
return res.status(400).json({ error: 'Neplatná výše spropitného' });
|
|
}
|
|
if (discountType !== undefined && discountType !== '' && !['percent', 'fixed'].includes(discountType)) {
|
|
return res.status(400).json({ error: 'Neplatný typ slevy' });
|
|
}
|
|
if (discountValue !== undefined && (!Number.isInteger(discountValue) || discountValue < 0)) {
|
|
return res.status(400).json({ error: 'Neplatná výše slevy' });
|
|
}
|
|
try {
|
|
const data = await updateGroupFees(login, id, fees, shipping, tip, discountType, discountValue);
|
|
broadcastExtra(data);
|
|
res.status(200).json(data);
|
|
} catch (e: any) { next(e); }
|
|
});
|
|
|
|
router.post("/updateTimes", async (req: Request, res, next) => {
|
|
const login = getLogin(parseToken(req));
|
|
const { id, orderedAt, deliveryAt } = req.body ?? {};
|
|
if (!id) return res.status(400).json({ error: 'Nebylo předáno ID skupiny' });
|
|
const timeRegex = /^([01]\d|2[0-3]):[0-5]\d$/;
|
|
if (orderedAt !== undefined && orderedAt !== '' && !timeRegex.test(orderedAt)) {
|
|
return res.status(400).json({ error: 'Neplatný formát času objednání (očekáváno HH:MM)' });
|
|
}
|
|
if (deliveryAt !== undefined && deliveryAt !== '' && !timeRegex.test(deliveryAt)) {
|
|
return res.status(400).json({ error: 'Neplatný formát času doručení (očekáváno HH:MM)' });
|
|
}
|
|
try {
|
|
const data = await updateGroupTimes(login, id, orderedAt, deliveryAt);
|
|
broadcastExtra(data);
|
|
res.status(200).json(data);
|
|
} catch (e: any) { next(e); }
|
|
});
|
|
|
|
export default router;
|