Deduplikace typů a sloučení kontejnerů

- Zavedení yarn workspaces
- Sloučení klienta a serveru do jednoho Docker kontejneru
- Společný dockerfile, builder
- Zbavení se nginx (není již potřeba)
This commit is contained in:
2023-07-22 19:37:03 +02:00
parent 0d0c5cb946
commit 3c0e8b2297
31 changed files with 1638 additions and 2527 deletions

View File

@@ -8,11 +8,16 @@ import dotenv from 'dotenv';
import path from 'path';
import { getMenuSladovnicka, getMenuTechTower, getMenuUMotliku } from "./restaurants";
import { getQr } from "./qr";
import { Restaurants } from "./types";
import { generateToken, getLogin, verify } from "./auth";
import { Restaurants } from "../../types";
const ENVIRONMENT = process.env.NODE_ENV || 'production'
dotenv.config({ path: path.resolve(__dirname, `../.env.${ENVIRONMENT}`) });
const ENVIRONMENT = process.env.NODE_ENV || 'production';
dotenv.config({ path: path.resolve(__dirname, `./.env.${ENVIRONMENT}`) });
// Validace nastavení JWT tokenu - nemá bez něj smysl vůbec povolit server spustit
if (!process.env.JWT_SECRET) {
throw Error("Není vyplněna proměnná prostředí JWT_SECRET");
}
const app = express();
const server = require("http").createServer(app);
@@ -30,6 +35,8 @@ app.use(cors({
origin: '*'
}));
app.use(express.static('public'))
const parseToken = (req: any) => {
if (req?.headers?.authorization) {
return req.headers.authorization.split(' ')[1];
@@ -95,7 +102,7 @@ app.get("/api/data", (req, res) => {
/** Vrátí obědové menu pro dostupné podniky. */
app.get("/api/food", async (req, res) => {
const mock = !!req.query?.mock;
const mock = !!process.env.MOCK_DATA;
const date = new Date();
const data = {
[Restaurants.SLADOVNICKA]: await getMenuSladovnicka(date, mock),

View File

@@ -1,6 +1,6 @@
/** Notifikace pro gotify*/
import axios, { AxiosError, AxiosResponse } from 'axios';
import { GotifyServer, NotififaceInput, NotifikaceData, UdalostEnum } from "./types";
import { GotifyServer, NotififaceInput, NotifikaceData } from '../../types';
import axios, { AxiosError } from 'axios';
import dotenv from 'dotenv';
import path from 'path';

View File

@@ -4,7 +4,7 @@ import path from "path";
import fs from "fs";
import { load } from 'cheerio';
import { formatDate } from "./utils";
import { Food } from "./types";
import { Food } from "../../types";
// Fráze v názvech jídel, které naznačují že se jedná o polévku
const SOUP_NAMES = ['polévka', 'česnečka', 'česnekový krém', 'cibulačka', 'vývar']

View File

@@ -1,8 +1,8 @@
import { ClientData, Locations, Order, Pizza, PizzaDayState, PizzaOrder, PizzaSize, UdalostEnum } from "./types";
import { db } from "./database";
import { formatDate, getHumanDate, getIsWeekend } from "./utils";
import { callNotifikace } from "./notifikace";
import { generateQr } from "./qr";
import { ClientData, PizzaDayState, UdalostEnum, Pizza, PizzaSize, Order, PizzaOrder, Locations } from "../../types";
/** Vrátí dnešní datum, případně fiktivní datum pro účely vývoje a testování. */
function getToday(): Date {

View File

@@ -1,108 +0,0 @@
import exp from "constants";
export interface Choices {
[location: string]: string[],
}
/** Velikost konkrétní pizzy */
export interface PizzaSize {
varId: number, // unikátní ID varianty pizzy
size: string, // velikost pizzy, např. "30cm"
pizzaPrice: number, // cena samotné pizzy
boxPrice: number, // cena krabice
price: number, // celková cena (pizza + krabice)
}
/** Jedna konkrétní pizza */
export interface Pizza {
name: string, // název pizzy
ingredients: string[], // seznam ingrediencí
sizes: PizzaSize[], // dostupné velikosti pizzy
}
/** Objednávka jedné konkrétní pizzy */
export interface PizzaOrder {
varId: number, // unikátní ID varianty pizzy
name: string, // název pizzy
size: string, // velikost pizzy jako string (30cm)
price: number, // cena pizzy v Kč, včetně krabice
}
/** Celková objednávka jednoho člověka */
export interface Order {
customer: string, // jméno objednatele
pizzaList: PizzaOrder[], // seznam objednaných pizz
totalPrice: number, // celková cena všech objednaných pizz a krabic
hasQr?: boolean, // true, pokud je k objednávce vygenerován QR kód pro platbu
note?: string, // volitelná uživatelská poznámka k objednávce
}
/** Stav pizza dne */
export enum PizzaDayState {
NOT_CREATED, // Pizza day nebyl založen
CREATED, // Pizza day je založen
LOCKED, // Objednávky uzamčeny
ORDERED, // Pizzy objednány
DELIVERED // Pizzy doručeny
}
/** Informace o pizza day pro dnešní den */
interface PizzaDay {
state: PizzaDayState, // stav pizza dne
creator: string, // jméno zakladatele
orders: Order[], // seznam objednávek jednotlivých lidí
}
/** Veškerá data pro zobrazení na klientovi */
export interface ClientData {
date: string, // dnešní datum pro zobrazení
isWeekend: boolean, // příznak, zda je dnes víkend
choices: Choices, // seznam voleb
pizzaDay?: PizzaDay, // pizza day pro dnešní den, pokud existuje
}
/** Jídlo z obědového menu restaurace. */
export interface Food {
amount?: string, // množství standardní porce, např. 0,33l nebo 150g
name: string, // název/popis jídla
price: string, // cena ve formátu '135 Kč'
isSoup: boolean, // příznak, zda se jedná o polévku
}
/** Výčtový typ pro restaurace, pro které umíme získat a parsovat obědové menu. */
export enum Restaurants {
SLADOVNICKA = 'sladovnicka',
UMOTLIKU = 'uMotliku',
TECHTOWER = 'techTower',
}
export enum Locations {
SLADOVNICKA = 'Sladovnická',
UMOTLIKU = 'U Motlíků',
TECHTOWER = 'TechTower',
SPSE = 'SPŠE',
PIZZA = 'Pizza day',
OBJEDNAVAM = 'Budu objednávat',
NEOBEDVAM = 'Mám vlastní/neobědvám',
}
export enum UdalostEnum {
ZAHAJENA_PIZZA = "Zahájen pizza day",
OBJEDNANA_PIZZA = "Objednána pizza"
}
export interface NotififaceInput {
udalost: UdalostEnum,
user: string,
}
export interface NotifikaceData {
input: NotififaceInput,
gotify?: boolean,
teams?: boolean,
}
export interface GotifyServer {
server: string;
api_keys: string[];
}