Migrace z pořadových indexů na unikátní klíče

This commit is contained in:
2025-01-09 22:05:20 +01:00
parent 774cb4f9d2
commit 02de6691a8
7 changed files with 104 additions and 100 deletions

View File

@@ -33,24 +33,21 @@ const router = express.Router();
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) {
let date = undefined;
if (req.body.dayIndex != null) {
let dayIndex;
try {
dayIndex = parseValidateFutureDayIndex(req);
} catch (e: any) {
return res.status(400).json({ error: e.message });
}
date = getDateForWeekIndex(dayIndex);
}
let date = undefined;
if (req.body.dayIndex != null) {
let dayIndex;
try {
const data = await addChoice(login, trusted, req.body.locationIndex, req.body.foodIndex, date);
getWebsocket().emit("message", await addVolatileData(data));
return res.status(200).json(data);
} catch (e: any) { next(e) }
dayIndex = parseValidateFutureDayIndex(req);
} catch (e: any) {
return res.status(400).json({ error: e.message });
}
date = getDateForWeekIndex(dayIndex);
}
return res.status(400); // TODO přidat popis chyby
try {
const data = await addChoice(login, trusted, req.body.locationKey, req.body.foodIndex, date);
getWebsocket().emit("message", await addVolatileData(data));
return res.status(200).json(data);
} catch (e: any) { next(e) }
});
router.post("/removeChoices", async (req: Request<{}, any, RemoveChoicesRequest>, res, next) => {
@@ -67,7 +64,7 @@ router.post("/removeChoices", async (req: Request<{}, any, RemoveChoicesRequest>
date = getDateForWeekIndex(dayIndex);
}
try {
const data = await removeChoices(login, trusted, req.body.locationIndex, date);
const data = await removeChoices(login, trusted, req.body.locationKey, date);
getWebsocket().emit("message", await addVolatileData(data));
res.status(200).json(data);
} catch (e: any) { next(e) }
@@ -87,7 +84,7 @@ router.post("/removeChoice", async (req: Request<{}, any, RemoveChoiceRequest>,
date = getDateForWeekIndex(dayIndex);
}
try {
const data = await removeChoice(login, trusted, req.body.locationIndex, req.body.foodIndex, date);
const data = await removeChoice(login, trusted, req.body.locationKey, req.body.foodIndex, date);
getWebsocket().emit("message", await addVolatileData(data));
res.status(200).json(data);
} catch (e: any) { next(e) }

View File

@@ -1,5 +1,5 @@
import { InsufficientPermissions, formatDate, getDayOfWeekIndex, getFirstWorkDayOfWeek, getHumanDate, getHumanTime, getIsWeekend, getLastWorkDayOfWeek, getWeekNumber } from "./utils";
import { ClientData, Locations, Restaurants, DayMenu, DepartureTime, DayData, WeekMenu } from "../../types";
import { InsufficientPermissions, formatDate, getDayOfWeekIndex, getFirstWorkDayOfWeek, getHumanDate, getIsWeekend, getWeekNumber } from "./utils";
import { ClientData, Restaurants, DayMenu, DepartureTime, DayData, WeekMenu, LocationKey } from "../../types";
import getStorage from "./storage";
import { getMenuSladovnicka, getMenuTechTower, getMenuUMotliku } from "./restaurants";
import { getTodayMock } from "./mock";
@@ -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 locationIndex vybrané "umístění"
* @param locationKey vybrané "umístění"
* @param date datum, ke kterému se volba vztahuje
* @returns
*/
export async function removeChoices(login: string, trusted: boolean, locationIndex: number, date?: Date) {
export async function removeChoices(login: string, trusted: boolean, locationKey: LocationKey, date?: Date) {
const selectedDay = formatDate(date ?? getToday());
let data: DayData = await storage.getData(selectedDay);
validateTrusted(data, login, trusted);
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]
if (locationKey in data.choices) {
if (data.choices[locationKey] && login in data.choices[locationKey]) {
delete data.choices[locationKey][login]
if (Object.keys(data.choices[locationKey]).length === 0) {
delete data.choices[locationKey]
}
await storage.setData(selectedDay, data);
}
@@ -218,20 +218,20 @@ export async function removeChoices(login: string, trusted: boolean, locationInd
*
* @param login login uživatele
* @param trusted příznak, zda se jedná o ověřeného uživatele
* @param locationIndex vybrané "umístění"
* @param locationKey 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, locationIndex: number, foodIndex: number, date?: Date) {
export async function removeChoice(login: string, trusted: boolean, locationKey: LocationKey, foodIndex: number, date?: Date) {
const selectedDay = formatDate(date ?? getToday());
let data: DayData = await storage.getData(selectedDay);
validateTrusted(data, login, trusted);
if (locationIndex in data.choices) {
if (login in data.choices[locationIndex]) {
const index = data.choices[locationIndex][login].options.indexOf(foodIndex);
if (locationKey in data.choices) {
if (data.choices[locationKey] && login in data.choices[locationKey]) {
const index = data.choices[locationKey][login].options.indexOf(foodIndex);
if (index > -1) {
data.choices[locationIndex][login].options.splice(index, 1)
data.choices[locationKey][login].options.splice(index, 1)
await storage.setData(selectedDay, data);
}
}
@@ -247,10 +247,11 @@ export async function removeChoice(login: string, trusted: boolean, locationInde
async function removeChoiceIfPresent(login: string, date: string) {
let data: DayData = await storage.getData(date);
for (const key of Object.keys(data.choices)) {
if (login in data.choices[key]) {
delete data.choices[key][login];
if (Object.keys(data.choices[key]).length === 0) {
delete data.choices[key];
const locationKey = key as LocationKey;
if (data.choices[locationKey] && login in data.choices[locationKey]) {
delete data.choices[locationKey][login];
if (Object.keys(data.choices[locationKey]).length === 0) {
delete data.choices[locationKey];
}
await storage.setData(date, data);
}
@@ -285,13 +286,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 locationIndex vybrané "umístění"
* @param locationKey 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, locationIndex: number, foodIndex?: number, date?: Date) {
export async function addChoice(login: string, trusted: boolean, locationKey: LocationKey, foodIndex?: number, date?: Date) {
const usedDate = date ?? getToday();
await initIfNeeded(usedDate);
const selectedDate = formatDate(usedDate);
@@ -301,17 +302,21 @@ export async function addChoice(login: string, trusted: boolean, locationIndex:
if (foodIndex == null) {
data = await removeChoiceIfPresent(login, selectedDate);
}
if (!(locationIndex in data.choices)) {
data.choices[locationIndex] = {};
// TODO vytáhnout inicializaci "prázdné struktury" do vlastní funkce
if (!(data.choices[locationKey])) {
data.choices[locationKey] = {}
}
if (!(login in data.choices[locationIndex])) {
data.choices[locationIndex][login] = {
if (!(login in data.choices[locationKey])) {
if (!data.choices[locationKey]) {
data.choices[locationKey] = {}
}
data.choices[locationKey][login] = {
trusted,
options: []
};
}
if (foodIndex != null && !data.choices[locationIndex][login].options.includes(foodIndex)) {
data.choices[locationIndex][login].options.push(foodIndex);
if (foodIndex != null && !data.choices[locationKey][login].options.includes(foodIndex)) {
data.choices[locationKey][login].options.push(foodIndex);
}
await storage.setData(selectedDate, data);
return data;

View File

@@ -1,4 +1,4 @@
import { Choices } from "../../types";
import { Choices, LocationKey } from "../../types";
/** Vrátí datum v ISO formátu. */
export function formatDate(date: Date) {
@@ -110,19 +110,19 @@ export const checkBodyParams = (req: any, paramNames: string[]) => {
// TODO umístit do samostatného souboru
export class InsufficientPermissions extends Error { }
export const getUsersByLocation = (data: Choices, login: string): string[] => {
export const getUsersByLocation = (choices: Choices, login: string): string[] => {
const result: string[] = [];
for (const location in data) {
if (data.hasOwnProperty(location)) {
if (data[location][login]) {
for (const username in data[location]) {
if (data[location].hasOwnProperty(username)) {
result.push(username);
}
for (const location of Object.entries(choices)) {
const locationKey = location[0] as LocationKey;
const locationValue = location[1];
if (locationValue[login]) {
for (const username in choices[locationKey]) {
if (choices[locationKey].hasOwnProperty(username)) {
result.push(username);
}
break;
}
break;
}
}