Migrace serveru na OpenAPI
All checks were successful
ci/woodpecker/push/workflow Pipeline was successful

This commit is contained in:
Martin Berka 2025-03-20 23:50:47 +01:00
parent d366882f6b
commit 739c7707e1
16 changed files with 31 additions and 84 deletions

View File

@ -9,6 +9,8 @@ WORKDIR /build
COPY types/package.json ./types/
COPY types/yarn.lock ./types/
COPY types/api.yml ./types/
COPY types/schemas ./types/schemas/
COPY types/paths ./types/paths/
COPY types/openapi-ts.config.ts ./types/
# Zkopírování závislostí - server
@ -46,7 +48,6 @@ COPY client/src ./client/src
COPY client/public ./client/public
# Zkopírování společných typů
COPY types/RequestTypes.ts ./types/
COPY types/index.ts ./types/
# Vygenerování společných typů z OpenAPI

View File

@ -1,4 +1,4 @@
import { WeeklyStats, LunchChoice } from "../../types";
import { WeeklyStats, LunchChoice } from "../../types/gen/types.gen";
// Mockovací data pro podporované podniky, na jeden týden
const MOCK_DATA = {

View File

@ -4,7 +4,7 @@ import { generateQr } from "./qr";
import getStorage from "./storage";
import { downloadPizzy } from "./chefie";
import { getClientData, getToday, initIfNeeded } from "./service";
import { Pizza, ClientData, PizzaDayState, PizzaSize, PizzaOrder, PizzaVariant, UdalostEnum } from "../../types";
import { Pizza, ClientData, PizzaDayState, PizzaSize, PizzaOrder, PizzaVariant, UdalostEnum } from "../../types/gen/types.gen";
const storage = getStorage();

View File

@ -2,7 +2,7 @@ import axios from "axios";
import { load } from 'cheerio';
import { getMenuSladovnickaMock, getMenuTechTowerMock, getMenuUMotlikuMock, getMenuZastavkaUmichalaMock, getMenuSenkSerikovaMock } from "./mock";
import { formatDate } from "./utils";
import { Food } from "../../types";
import { Food } from "../../types/gen/types.gen";
// Fráze v názvech jídel, které naznačují že se jedná o polévku
const SOUP_NAMES = [

View File

@ -3,7 +3,7 @@ import { getLogin } from "../auth";
import { parseToken } from "../utils";
import path from "path";
import fs from "fs";
import { EasterEgg } from "../../../types";
import { EasterEgg } from "../../../types/gen/types.gen";
const EASTER_EGGS_JSON_PATH = path.join(__dirname, "../../.easter-eggs.json");
const IMAGES_PATH = '../../resources/easterEggs';

View File

@ -4,7 +4,7 @@ import { addChoice, getDateForWeekIndex, getToday, removeChoice, removeChoices,
import { getDayOfWeekIndex, parseToken } from "../utils";
import { getWebsocket } from "../websocket";
import { callNotifikace } from "../notifikace";
import { AddChoiceRequest, ChangeDepartureTimeRequest, IDayIndex, RemoveChoiceRequest, RemoveChoicesRequest, UdalostEnum, UpdateNoteRequest } from "../../../types";
import { AddChoiceData, ChangeDepartureTimeData, RemoveChoiceData, RemoveChoicesData, UdalostEnum, UpdateNoteData } from "../../../types/gen/types.gen";
/**
* 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,7 +13,7 @@ import { AddChoiceRequest, ChangeDepartureTimeRequest, IDayIndex, RemoveChoiceRe
* @param req request
* @returns index dne v týdnu
*/
const parseValidateFutureDayIndex = (req: Request<{}, any, IDayIndex>) => {
const parseValidateFutureDayIndex = (req: Request<{}, any, AddChoiceData["body"] | UpdateNoteData["body"]>) => {
if (req.body.dayIndex == null) {
throw Error(`Nebyl předán index dne v týdnu.`);
}
@ -30,7 +30,7 @@ const parseValidateFutureDayIndex = (req: Request<{}, any, IDayIndex>) => {
const router = express.Router();
router.post("/addChoice", async (req: Request<{}, any, AddChoiceRequest>, res, next) => {
router.post("/addChoice", async (req: Request<{}, any, AddChoiceData["body"]>, res, next) => {
const login = getLogin(parseToken(req));
const trusted = getTrusted(parseToken(req));
let date = undefined;
@ -50,7 +50,7 @@ router.post("/addChoice", async (req: Request<{}, any, AddChoiceRequest>, res, n
} catch (e: any) { next(e) }
});
router.post("/removeChoices", async (req: Request<{}, any, RemoveChoicesRequest>, res, next) => {
router.post("/removeChoices", async (req: Request<{}, any, RemoveChoicesData["body"]>, res, next) => {
const login = getLogin(parseToken(req));
const trusted = getTrusted(parseToken(req));
let date = undefined;
@ -70,7 +70,7 @@ router.post("/removeChoices", async (req: Request<{}, any, RemoveChoicesRequest>
} catch (e: any) { next(e) }
});
router.post("/removeChoice", async (req: Request<{}, any, RemoveChoiceRequest>, res, next) => {
router.post("/removeChoice", async (req: Request<{}, any, RemoveChoiceData["body"]>, res, next) => {
const login = getLogin(parseToken(req));
const trusted = getTrusted(parseToken(req));
let date = undefined;
@ -90,7 +90,7 @@ router.post("/removeChoice", async (req: Request<{}, any, RemoveChoiceRequest>,
} catch (e: any) { next(e) }
});
router.post("/updateNote", async (req: Request<{}, any, UpdateNoteRequest>, res, next) => {
router.post("/updateNote", async (req: Request<{}, any, UpdateNoteData["body"]>, res, next) => {
const login = getLogin(parseToken(req));
const trusted = getTrusted(parseToken(req));
const note = req.body.note;
@ -114,7 +114,7 @@ router.post("/updateNote", async (req: Request<{}, any, UpdateNoteRequest>, res,
} catch (e: any) { next(e) }
});
router.post("/changeDepartureTime", async (req: Request<{}, any, ChangeDepartureTimeRequest>, res, next) => {
router.post("/changeDepartureTime", async (req: Request<{}, any, ChangeDepartureTimeData["body"]>, res, next) => {
const login = getLogin(parseToken(req));
let date = undefined;
if (req.body.dayIndex != null) {

View File

@ -3,7 +3,7 @@ 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 { AddPizzaRequest, FinishDeliveryRequest, RemovePizzaRequest, UpdatePizzaDayNoteRequest, UpdatePizzaFeeRequest } from "../../../types";
import { AddPizzaData, FinishDeliveryData, RemovePizzaData, UpdatePizzaDayNoteData, UpdatePizzaFeeData } from "../../../types";
const router = express.Router();
@ -22,7 +22,7 @@ router.post("/delete", async (req: Request<{}, any, undefined>, res) => {
getWebsocket().emit("message", data);
});
router.post("/add", async (req: Request<{}, any, AddPizzaRequest>, res) => {
router.post("/add", async (req: Request<{}, any, AddPizzaData["body"]>, res) => {
const login = getLogin(parseToken(req));
if (isNaN(req.body?.pizzaIndex)) {
throw Error("Nebyl předán index pizzy");
@ -47,7 +47,7 @@ router.post("/add", async (req: Request<{}, any, AddPizzaRequest>, res) => {
res.status(200).json({});
});
router.post("/remove", async (req: Request<{}, any, RemovePizzaRequest>, res) => {
router.post("/remove", async (req: Request<{}, any, RemovePizzaData["body"]>, res) => {
const login = getLogin(parseToken(req));
if (!req.body?.pizzaOrder) {
throw Error("Nebyla předána objednávka");
@ -78,14 +78,14 @@ router.post("/finishOrder", async (req: Request<{}, any, undefined>, res) => {
res.status(200).json({});
});
router.post("/finishDelivery", async (req: Request<{}, any, FinishDeliveryRequest>, res) => {
router.post("/finishDelivery", async (req: Request<{}, any, FinishDeliveryData["body"]>, res) => {
const login = getLogin(parseToken(req));
const data = await finishPizzaDelivery(login, req.body.bankAccount, req.body.bankAccountHolder);
getWebsocket().emit("message", data);
res.status(200).json({});
});
router.post("/updatePizzaDayNote", async (req: Request<{}, any, UpdatePizzaDayNoteRequest>, res, next) => {
router.post("/updatePizzaDayNote", async (req: Request<{}, any, UpdatePizzaDayNoteData["body"]>, res, next) => {
const login = getLogin(parseToken(req));
try {
if (req.body.note && req.body.note.length > 70) {
@ -97,7 +97,7 @@ router.post("/updatePizzaDayNote", async (req: Request<{}, any, UpdatePizzaDayNo
} catch (e: any) { next(e) }
});
router.post("/updatePizzaFee", async (req: Request<{}, any, UpdatePizzaFeeRequest>, res, next) => {
router.post("/updatePizzaFee", async (req: Request<{}, any, UpdatePizzaFeeData["body"]>, 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" });

View File

@ -2,7 +2,7 @@ import express, { Request, Response } from "express";
import { getLogin } from "../auth";
import { parseToken } from "../utils";
import { getStats } from "../stats";
import { WeeklyStats } from "../../../types";
import { WeeklyStats } from "../../../types/gen/types.gen";
const router = express.Router();

View File

@ -1,18 +1,18 @@
import express, { Request, Response } from "express";
import express, { Request } from "express";
import { getLogin } from "../auth";
import { parseToken } from "../utils";
import { getUserVotes, updateFeatureVote } from "../voting";
import { FeatureRequest, UpdateFeatureVoteRequest } from "../../../types";
import { GetVotesData, UpdateVoteData } from "../../../types";
const router = express.Router();
router.get("/getVotes", async (req: Request<{}, any, undefined>, res: Response<FeatureRequest[]>) => {
router.get("/getVotes", async (req: Request<{}, any, GetVotesData["body"]>, res) => {
const login = getLogin(parseToken(req));
const data = await getUserVotes(login);
res.status(200).json(data);
});
router.post("/updateVote", async (req: Request<{}, any, UpdateFeatureVoteRequest>, res, next) => {
router.post("/updateVote", async (req: Request<{}, any, UpdateVoteData["body"]>, 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í" });

View File

@ -2,7 +2,7 @@ import { InsufficientPermissions, formatDate, getDayOfWeekIndex, getFirstWorkDay
import getStorage from "./storage";
import { getMenuSladovnicka, getMenuTechTower, getMenuZastavkaUmichala, getMenuSenkSerikova } from "./restaurants";
import { getTodayMock } from "./mock";
import { ClientData, DepartureTime, LunchChoice, Restaurant, RestaurantDayMenu, WeekMenu } from "../../types";
import { ClientData, DepartureTime, LunchChoice, Restaurant, RestaurantDayMenu, WeekMenu } from "../../types/gen/types.gen";
const storage = getStorage();
const MENU_PREFIX = 'menu';

View File

@ -1,4 +1,4 @@
import { DailyStats, LunchChoice, WeeklyStats } from "../../types";
import { DailyStats, LunchChoice, WeeklyStats } from "../../types/gen/types.gen";
import { getStatsMock } from "./mock";
import { getClientData } from "./service";
import getStorage from "./storage";

View File

@ -1,4 +1,4 @@
import { LunchChoice, LunchChoices } from "../../types";
import { LunchChoice, LunchChoices } from "../../types/gen/types.gen";
const DAY_OF_WEEK_FORMAT = new Intl.DateTimeFormat(undefined, { weekday: 'long' });

View File

@ -1,4 +1,4 @@
import { FeatureRequest } from "../../types";
import { FeatureRequest } from "../../types/gen/types.gen";
import getStorage from "./storage";
interface VotingData {

View File

@ -1,56 +0,0 @@
import { FeatureRequest, LunchChoice, PizzaVariant } from "../types";
export type ILocationKey = {
locationKey: LunchChoice,
}
export type IDayIndex = {
dayIndex?: number,
}
export type AddChoiceRequest = IDayIndex & ILocationKey & {
foodIndex?: number,
}
export type RemoveChoicesRequest = IDayIndex & ILocationKey;
export type RemoveChoiceRequest = IDayIndex & ILocationKey & {
foodIndex: number,
}
export type UpdateNoteRequest = IDayIndex & {
note?: string,
}
export type ChangeDepartureTimeRequest = IDayIndex & {
time: string,
}
export type FinishDeliveryRequest = {
bankAccount?: string,
bankAccountHolder?: string,
}
export type AddPizzaRequest = {
pizzaIndex: number,
pizzaSizeIndex: number,
}
export type RemovePizzaRequest = {
pizzaOrder: PizzaVariant,
}
export type UpdatePizzaDayNoteRequest = {
note?: string,
}
export type UpdatePizzaFeeRequest = {
login: string,
text?: string,
price?: number,
}
export type UpdateFeatureVoteRequest = {
option: FeatureRequest,
active: boolean,
}

View File

@ -1,2 +1 @@
export * from './RequestTypes';
export * from './gen';

View File

@ -7,6 +7,9 @@ post:
application/json:
schema:
type: object
required:
- option
- active
properties:
option:
description: Hlasovací možnost, kterou uživatel zvolil.