From e611d369951b2860df5b803a9bd70789c9b4d41b Mon Sep 17 00:00:00 2001 From: Martin Berka Date: Wed, 8 Jan 2025 17:58:49 +0100 Subject: [PATCH] =?UTF-8?q?Otypov=C3=A1n=C3=AD=20request=C5=AF=20na=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/src/api/EasterEggApi.ts | 2 +- client/src/api/FoodApi.ts | 13 +++---- client/src/api/PizzaDayApi.ts | 22 ++++++------ client/src/api/VotingApi.ts | 6 ++-- server/src/routes/foodRoutes.ts | 18 +++++----- server/src/routes/pizzaDayRoutes.ts | 23 ++++++------ server/src/routes/votingRoutes.ts | 7 ++-- server/src/service.ts | 42 +++++++++++----------- types/RequestTypes.ts | 56 +++++++++++++++++++++++++++++ types/index.ts | 3 +- 10 files changed, 126 insertions(+), 66 deletions(-) create mode 100644 types/RequestTypes.ts diff --git a/client/src/api/EasterEggApi.ts b/client/src/api/EasterEggApi.ts index b43a372..e16af03 100644 --- a/client/src/api/EasterEggApi.ts +++ b/client/src/api/EasterEggApi.ts @@ -4,7 +4,7 @@ import { api } from "./Api"; const EASTER_EGGS_API_PREFIX = '/api/easterEggs'; export const getEasterEgg = async (): Promise => { - return await api.get(`${EASTER_EGGS_API_PREFIX}`); + return await api.get(`${EASTER_EGGS_API_PREFIX}`); } export const getImage = async (url: string) => { diff --git a/client/src/api/FoodApi.ts b/client/src/api/FoodApi.ts index 26241a2..bad4465 100644 --- a/client/src/api/FoodApi.ts +++ b/client/src/api/FoodApi.ts @@ -1,27 +1,28 @@ +import { AddChoiceRequest, ChangeDepartureTimeRequest, RemoveChoiceRequest, RemoveChoicesRequest, UpdateNoteRequest } from "../types"; import { api } from "./Api"; const FOOD_API_PREFIX = '/api/food'; export const addChoice = async (locationIndex: number, foodIndex?: number, dayIndex?: number) => { - return await api.post(`${FOOD_API_PREFIX}/addChoice`, { locationIndex, foodIndex, dayIndex }); + return await api.post(`${FOOD_API_PREFIX}/addChoice`, { locationIndex, foodIndex, dayIndex }); } export const removeChoices = async (locationIndex: number, dayIndex?: number) => { - return await api.post(`${FOOD_API_PREFIX}/removeChoices`, { locationIndex, dayIndex }); + return await api.post(`${FOOD_API_PREFIX}/removeChoices`, { locationIndex, dayIndex }); } export const removeChoice = async (locationIndex: number, foodIndex: number, dayIndex?: number) => { - return await api.post(`${FOOD_API_PREFIX}/removeChoice`, { locationIndex, foodIndex, dayIndex }); + return await api.post(`${FOOD_API_PREFIX}/removeChoice`, { locationIndex, foodIndex, dayIndex }); } export const updateNote = async (note?: string, dayIndex?: number) => { - return await api.post(`${FOOD_API_PREFIX}/updateNote`, { note, dayIndex }); + return await api.post(`${FOOD_API_PREFIX}/updateNote`, { note, dayIndex }); } export const changeDepartureTime = async (time: string, dayIndex?: number) => { - return await api.post(`${FOOD_API_PREFIX}/changeDepartureTime`, { time, dayIndex }); + return await api.post(`${FOOD_API_PREFIX}/changeDepartureTime`, { time, dayIndex }); } export const jdemeObed = async () => { - return await api.post(`${FOOD_API_PREFIX}/jdemeObed`, undefined); + return await api.post(`${FOOD_API_PREFIX}/jdemeObed`); } diff --git a/client/src/api/PizzaDayApi.ts b/client/src/api/PizzaDayApi.ts index 89ede1e..3db215d 100644 --- a/client/src/api/PizzaDayApi.ts +++ b/client/src/api/PizzaDayApi.ts @@ -1,44 +1,44 @@ -import { PizzaOrder } from "../types"; +import { AddPizzaRequest, FinishDeliveryRequest, PizzaOrder, RemovePizzaRequest, UpdatePizzaDayNoteRequest, UpdatePizzaFeeRequest } from "../types"; import { api } from "./Api"; const PIZZADAY_API_PREFIX = '/api/pizzaDay'; export const createPizzaDay = async () => { - return await api.post(`${PIZZADAY_API_PREFIX}/create`, undefined); + return await api.post(`${PIZZADAY_API_PREFIX}/create`); } export const deletePizzaDay = async () => { - return await api.post(`${PIZZADAY_API_PREFIX}/delete`, undefined); + return await api.post(`${PIZZADAY_API_PREFIX}/delete`); } export const lockPizzaDay = async () => { - return await api.post(`${PIZZADAY_API_PREFIX}/lock`, undefined); + return await api.post(`${PIZZADAY_API_PREFIX}/lock`); } export const unlockPizzaDay = async () => { - return await api.post(`${PIZZADAY_API_PREFIX}/unlock`, undefined); + return await api.post(`${PIZZADAY_API_PREFIX}/unlock`); } export const finishOrder = async () => { - return await api.post(`${PIZZADAY_API_PREFIX}/finishOrder`, undefined); + return await api.post(`${PIZZADAY_API_PREFIX}/finishOrder`); } export const finishDelivery = async (bankAccount?: string, bankAccountHolder?: string) => { - return await api.post(`${PIZZADAY_API_PREFIX}/finishDelivery`, { bankAccount, bankAccountHolder }); + return await api.post(`${PIZZADAY_API_PREFIX}/finishDelivery`, { bankAccount, bankAccountHolder }); } export const addPizza = async (pizzaIndex: number, pizzaSizeIndex: number) => { - return await api.post(`${PIZZADAY_API_PREFIX}/add`, { pizzaIndex, pizzaSizeIndex }); + return await api.post(`${PIZZADAY_API_PREFIX}/add`, { pizzaIndex, pizzaSizeIndex }); } export const removePizza = async (pizzaOrder: PizzaOrder) => { - return await api.post(`${PIZZADAY_API_PREFIX}/remove`, { pizzaOrder }); + return await api.post(`${PIZZADAY_API_PREFIX}/remove`, { pizzaOrder }); } export const updatePizzaDayNote = async (note?: string) => { - return await api.post(`${PIZZADAY_API_PREFIX}/updatePizzaDayNote`, { note }); + return await api.post(`${PIZZADAY_API_PREFIX}/updatePizzaDayNote`, { note }); } export const updatePizzaFee = async (login: string, text?: string, price?: number) => { - return await api.post(`${PIZZADAY_API_PREFIX}/updatePizzaFee`, { login, text, price }); + return await api.post(`${PIZZADAY_API_PREFIX}/updatePizzaFee`, { login, text, price }); } diff --git a/client/src/api/VotingApi.ts b/client/src/api/VotingApi.ts index 7a47c53..7a32030 100644 --- a/client/src/api/VotingApi.ts +++ b/client/src/api/VotingApi.ts @@ -1,12 +1,12 @@ -import { FeatureRequest } from "../types"; +import { FeatureRequest, UpdateFeatureVoteRequest } from "../types"; import { api } from "./Api"; const VOTING_API_PREFIX = '/api/voting'; export const getFeatureVotes = async () => { - return await api.get(`${VOTING_API_PREFIX}/getVotes`); + return await api.get(`${VOTING_API_PREFIX}/getVotes`); } export const updateFeatureVote = async (option: FeatureRequest, active: boolean) => { - return await api.post(`${VOTING_API_PREFIX}/updateVote`, { option, active }); + return await api.post(`${VOTING_API_PREFIX}/updateVote`, { option, active }); } \ No newline at end of file diff --git a/server/src/routes/foodRoutes.ts b/server/src/routes/foodRoutes.ts index 9a2987d..9921e32 100644 --- a/server/src/routes/foodRoutes.ts +++ b/server/src/routes/foodRoutes.ts @@ -1,10 +1,10 @@ -import express from "express"; +import express, { Request } from "express"; import { getLogin, getTrusted } from "../auth"; import { addChoice, addVolatileData, getDateForWeekIndex, getToday, removeChoice, removeChoices, updateDepartureTime, updateNote } from "../service"; import { getDayOfWeekIndex, parseToken } from "../utils"; import { getWebsocket } from "../websocket"; import { callNotifikace } from "../notifikace"; -import { UdalostEnum } from "../../../types"; +import { AddChoiceRequest, ChangeDepartureTimeRequest, IDayIndex, RemoveChoiceRequest, RemoveChoicesRequest, UdalostEnum, UpdateNoteRequest } from "../../../types"; /** * Ověří a vrátí index dne v týdnu z požadavku, za předpokladu, že byl předán, a je zároveň @@ -13,12 +13,12 @@ import { UdalostEnum } from "../../../types"; * @param req request * @returns index dne v týdnu */ -const parseValidateFutureDayIndex = (req: any) => { +const parseValidateFutureDayIndex = (req: Request<{}, any, IDayIndex>) => { if (req.body.dayIndex == null) { throw Error(`Nebyl předán index dne v týdnu.`); } const todayDayIndex = getDayOfWeekIndex(getToday()); - const dayIndex = parseInt(req.body.dayIndex); + const dayIndex = req.body.dayIndex; if (isNaN(dayIndex)) { throw Error(`Neplatný index dne v týdnu: ${req.body.dayIndex}`); } @@ -30,7 +30,7 @@ const parseValidateFutureDayIndex = (req: any) => { const router = express.Router(); -router.post("/addChoice", async (req, res, next) => { +router.post("/addChoice", async (req: Request<{}, any, AddChoiceRequest>, res, next) => { const login = getLogin(parseToken(req)); const trusted = getTrusted(parseToken(req)); if (req.body.locationIndex > -1) { @@ -53,7 +53,7 @@ router.post("/addChoice", async (req, res, next) => { return res.status(400); // TODO přidat popis chyby }); -router.post("/removeChoices", async (req, res, next) => { +router.post("/removeChoices", async (req: Request<{}, any, RemoveChoicesRequest>, res, next) => { const login = getLogin(parseToken(req)); const trusted = getTrusted(parseToken(req)); let date = undefined; @@ -73,7 +73,7 @@ router.post("/removeChoices", async (req, res, next) => { } catch (e: any) { next(e) } }); -router.post("/removeChoice", async (req, res, next) => { +router.post("/removeChoice", async (req: Request<{}, any, RemoveChoiceRequest>, res, next) => { const login = getLogin(parseToken(req)); const trusted = getTrusted(parseToken(req)); let date = undefined; @@ -93,7 +93,7 @@ router.post("/removeChoice", async (req, res, next) => { } catch (e: any) { next(e) } }); -router.post("/updateNote", async (req, res, next) => { +router.post("/updateNote", async (req: Request<{}, any, UpdateNoteRequest>, res, next) => { const login = getLogin(parseToken(req)); const trusted = getTrusted(parseToken(req)); const note = req.body.note; @@ -117,7 +117,7 @@ router.post("/updateNote", async (req, res, next) => { } catch (e: any) { next(e) } }); -router.post("/changeDepartureTime", async (req, res, next) => { +router.post("/changeDepartureTime", async (req: Request<{}, any, ChangeDepartureTimeRequest>, res, next) => { const login = getLogin(parseToken(req)); let date = undefined; if (req.body.dayIndex != null) { diff --git a/server/src/routes/pizzaDayRoutes.ts b/server/src/routes/pizzaDayRoutes.ts index e20a44a..1f1627c 100644 --- a/server/src/routes/pizzaDayRoutes.ts +++ b/server/src/routes/pizzaDayRoutes.ts @@ -1,14 +1,15 @@ -import express from "express"; +import express, { Request } from "express"; import { getLogin } from "../auth"; import { createPizzaDay, deletePizzaDay, getPizzaList, addPizzaOrder, removePizzaOrder, lockPizzaDay, unlockPizzaDay, finishPizzaOrder, finishPizzaDelivery, updatePizzaDayNote, updatePizzaFee } from "../pizza"; import { parseToken } from "../utils"; import { getWebsocket } from "../websocket"; import { addVolatileData } from "../service"; +import { AddPizzaRequest, FinishDeliveryRequest, RemovePizzaRequest, UpdatePizzaDayNoteRequest, UpdatePizzaFeeRequest } from "../../../types"; const router = express.Router(); /** Založí pizza day pro aktuální den, za předpokladu že dosud neexistuje. */ -router.post("/create", async (req, res) => { +router.post("/create", async (req: Request<{}, any, undefined>, res) => { const login = getLogin(parseToken(req)); const data = await createPizzaDay(login); res.status(200).json(data); @@ -16,13 +17,13 @@ router.post("/create", async (req, res) => { }); /** Smaže pizza day pro aktuální den, za předpokladu že existuje. */ -router.post("/delete", async (req, res) => { +router.post("/delete", async (req: Request<{}, any, undefined>, res) => { const login = getLogin(parseToken(req)); const data = await deletePizzaDay(login); getWebsocket().emit("message", await addVolatileData(data)); }); -router.post("/add", async (req, res) => { +router.post("/add", async (req: Request<{}, any, AddPizzaRequest>, res) => { const login = getLogin(parseToken(req)); if (isNaN(req.body?.pizzaIndex)) { throw Error("Nebyl předán index pizzy"); @@ -47,7 +48,7 @@ router.post("/add", async (req, res) => { res.status(200).json({}); }); -router.post("/remove", async (req, res) => { +router.post("/remove", async (req: Request<{}, any, RemovePizzaRequest>, res) => { const login = getLogin(parseToken(req)); if (!req.body?.pizzaOrder) { throw Error("Nebyla předána objednávka"); @@ -57,35 +58,35 @@ router.post("/remove", async (req, res) => { res.status(200).json({}); }); -router.post("/lock", async (req, res) => { +router.post("/lock", async (req: Request<{}, any, undefined>, res) => { const login = getLogin(parseToken(req)); const data = await lockPizzaDay(login); getWebsocket().emit("message", await addVolatileData(data)); res.status(200).json({}); }); -router.post("/unlock", async (req, res) => { +router.post("/unlock", async (req: Request<{}, any, undefined>, res) => { const login = getLogin(parseToken(req)); const data = await unlockPizzaDay(login); getWebsocket().emit("message", await addVolatileData(data)); res.status(200).json({}); }); -router.post("/finishOrder", async (req, res) => { +router.post("/finishOrder", async (req: Request<{}, any, undefined>, res) => { const login = getLogin(parseToken(req)); const data = await finishPizzaOrder(login); getWebsocket().emit("message", await addVolatileData(data)); res.status(200).json({}); }); -router.post("/finishDelivery", async (req, res) => { +router.post("/finishDelivery", async (req: Request<{}, any, FinishDeliveryRequest>, res) => { const login = getLogin(parseToken(req)); const data = await finishPizzaDelivery(login, req.body.bankAccount, req.body.bankAccountHolder); getWebsocket().emit("message", await addVolatileData(data)); res.status(200).json({}); }); -router.post("/updatePizzaDayNote", async (req, res, next) => { +router.post("/updatePizzaDayNote", async (req: Request<{}, any, UpdatePizzaDayNoteRequest>, res, next) => { const login = getLogin(parseToken(req)); try { if (req.body.note && req.body.note.length > 70) { @@ -97,7 +98,7 @@ router.post("/updatePizzaDayNote", async (req, res, next) => { } catch (e: any) { next(e) } }); -router.post("/updatePizzaFee", async (req, res, next) => { +router.post("/updatePizzaFee", async (req: Request<{}, any, UpdatePizzaFeeRequest>, res, next) => { const login = getLogin(parseToken(req)); if (!req.body.login) { return res.status(400).json({ error: "Nebyl předán login cílového uživatele" }); diff --git a/server/src/routes/votingRoutes.ts b/server/src/routes/votingRoutes.ts index b8e0da9..2aa6672 100644 --- a/server/src/routes/votingRoutes.ts +++ b/server/src/routes/votingRoutes.ts @@ -1,17 +1,18 @@ -import express from "express"; +import express, { Request, Response } from "express"; import { getLogin } from "../auth"; import { parseToken } from "../utils"; import { getUserVotes, updateFeatureVote } from "../voting"; +import { FeatureRequest, UpdateFeatureVoteRequest } from "../../../types"; const router = express.Router(); -router.get("/getVotes", async (req, res) => { +router.get("/getVotes", async (req: Request<{}, any, undefined>, res: Response) => { const login = getLogin(parseToken(req)); const data = await getUserVotes(login); res.status(200).json(data); }); -router.post("/updateVote", async (req, res, next) => { +router.post("/updateVote", async (req: Request<{}, any, UpdateFeatureVoteRequest>, res, next) => { const login = getLogin(parseToken(req)); if (req.body?.option == null || req.body?.active == null) { res.status(400).json({ error: "Chybné parametry volání" }); diff --git a/server/src/service.ts b/server/src/service.ts index 57ef4c7..e2f148b 100644 --- a/server/src/service.ts +++ b/server/src/service.ts @@ -192,19 +192,19 @@ export async function initIfNeeded(date?: Date) { * * @param login login uživatele * @param trusted příznak, zda se jedná o ověřeného uživatele - * @param location vybrané "umístění" + * @param locationIndex vybrané "umístění" * @param date datum, ke kterému se volba vztahuje * @returns */ -export async function removeChoices(login: string, trusted: boolean, location: Locations, date?: Date) { +export async function removeChoices(login: string, trusted: boolean, locationIndex: number, date?: Date) { const selectedDay = formatDate(date ?? getToday()); let data: DayData = await storage.getData(selectedDay); validateTrusted(data, login, trusted); - if (location in data.choices) { - if (login in data.choices[location]) { - delete data.choices[location][login] - if (Object.keys(data.choices[location]).length === 0) { - delete data.choices[location] + if (locationIndex in data.choices) { + if (login in data.choices[locationIndex]) { + delete data.choices[locationIndex][login] + if (Object.keys(data.choices[locationIndex]).length === 0) { + delete data.choices[locationIndex] } await storage.setData(selectedDay, data); } @@ -218,20 +218,20 @@ export async function removeChoices(login: string, trusted: boolean, location: L * * @param login login uživatele * @param trusted příznak, zda se jedná o ověřeného uživatele - * @param location vybrané "umístění" + * @param locationIndex vybrané "umístění" * @param foodIndex index jídla v jídelním lístku daného umístění, pokud existuje * @param date datum, ke kterému se volba vztahuje * @returns */ -export async function removeChoice(login: string, trusted: boolean, location: Locations, foodIndex: number, date?: Date) { +export async function removeChoice(login: string, trusted: boolean, locationIndex: number, foodIndex: number, date?: Date) { const selectedDay = formatDate(date ?? getToday()); let data: DayData = await storage.getData(selectedDay); validateTrusted(data, login, trusted); - if (location in data.choices) { - if (login in data.choices[location]) { - const index = data.choices[location][login].options.indexOf(foodIndex); + if (locationIndex in data.choices) { + if (login in data.choices[locationIndex]) { + const index = data.choices[locationIndex][login].options.indexOf(foodIndex); if (index > -1) { - data.choices[location][login].options.splice(index, 1) + data.choices[locationIndex][login].options.splice(index, 1) await storage.setData(selectedDay, data); } } @@ -285,13 +285,13 @@ function validateTrusted(data: ClientData, login: string, trusted: boolean) { * * @param login login uživatele * @param trusted příznak, zda se jedná o ověřeného uživatele - * @param location vybrané "umístění" + * @param locationIndex vybrané "umístění" * @param foodIndex volitelný index jídla v daném umístění * @param trusted příznak, zda se jedná o ověřeného uživatele * @param date datum, ke kterému se volba vztahuje * @returns aktuální data */ -export async function addChoice(login: string, trusted: boolean, location: Locations, foodIndex?: number, date?: Date) { +export async function addChoice(login: string, trusted: boolean, locationIndex: number, foodIndex?: number, date?: Date) { const usedDate = date ?? getToday(); await initIfNeeded(usedDate); const selectedDate = formatDate(usedDate); @@ -301,17 +301,17 @@ export async function addChoice(login: string, trusted: boolean, location: Locat if (foodIndex == null) { data = await removeChoiceIfPresent(login, selectedDate); } - if (!(location in data.choices)) { - data.choices[location] = {}; + if (!(locationIndex in data.choices)) { + data.choices[locationIndex] = {}; } - if (!(login in data.choices[location])) { - data.choices[location][login] = { + if (!(login in data.choices[locationIndex])) { + data.choices[locationIndex][login] = { trusted, options: [] }; } - if (foodIndex != null && !data.choices[location][login].options.includes(foodIndex)) { - data.choices[location][login].options.push(foodIndex); + if (foodIndex != null && !data.choices[locationIndex][login].options.includes(foodIndex)) { + data.choices[locationIndex][login].options.push(foodIndex); } await storage.setData(selectedDate, data); return data; diff --git a/types/RequestTypes.ts b/types/RequestTypes.ts new file mode 100644 index 0000000..75d191b --- /dev/null +++ b/types/RequestTypes.ts @@ -0,0 +1,56 @@ +import { FeatureRequest, PizzaOrder } from "./Types"; + +export interface IDayIndex { + dayIndex?: number, +} + +export interface AddChoiceRequest extends IDayIndex { + locationIndex: number, + foodIndex?: number, +} + +export interface RemoveChoicesRequest extends IDayIndex { + locationIndex: number, +} + +export interface RemoveChoiceRequest extends IDayIndex { + locationIndex: number, + foodIndex: number, +} + +export interface UpdateNoteRequest extends IDayIndex { + note?: string, +} + +export interface ChangeDepartureTimeRequest extends IDayIndex { + time: string, +} + +export interface FinishDeliveryRequest { + bankAccount?: string, + bankAccountHolder?: string, +} + +export interface AddPizzaRequest { + pizzaIndex: number, + pizzaSizeIndex: number, +} + +export interface RemovePizzaRequest { + pizzaOrder: PizzaOrder, +} + +export interface UpdatePizzaDayNoteRequest { + note?: string, +} + +export interface UpdatePizzaFeeRequest { + login: string, + text?: string, + price?: number, +} + +export interface UpdateFeatureVoteRequest { + option: FeatureRequest, + active: boolean, +} \ No newline at end of file diff --git a/types/index.ts b/types/index.ts index 0e7bf42..7401e5b 100644 --- a/types/index.ts +++ b/types/index.ts @@ -1 +1,2 @@ -export * from './Types'; \ No newline at end of file +export * from './Types'; +export * from './RequestTypes'; \ No newline at end of file