replacing db to caching Hash Obj
This commit is contained in:
parent
931d41d04c
commit
9e437999f7
6 changed files with 105 additions and 27 deletions
20
README.md
20
README.md
|
@ -25,21 +25,13 @@ init POSTGRES Database -
|
|||
CREATE DATABASE drop_shopping;
|
||||
|
||||
create tables -
|
||||
timeSlots -
|
||||
CREATE TABLE time_slots (
|
||||
CREATE TABLE deliveries (
|
||||
id SERIAL PRIMARY KEY,
|
||||
start_time TIME NOT NULL,
|
||||
end_time TIME NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
holidays -
|
||||
CREATE TABLE holidays (
|
||||
id SERIAL PRIMARY KEY,
|
||||
holiday_date DATE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
user_id INTEGER NOT NULL,
|
||||
slot_id INTEGER NOT NULL,
|
||||
delivery_date DATE NOT NULL,
|
||||
address TEXT NOT NULL,
|
||||
status VARCHAR(10) NOT NULL
|
||||
);
|
||||
|
||||
|
||||
|
|
12
package-lock.json
generated
12
package-lock.json
generated
|
@ -20,6 +20,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.16.0",
|
||||
"@types/pg": "^8.6.6",
|
||||
"nodemon": "^2.0.22",
|
||||
"ts-node-dev": "^2.0.0",
|
||||
"typescript": "^5.0.4"
|
||||
|
@ -134,6 +135,17 @@
|
|||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.16.0.tgz",
|
||||
"integrity": "sha512-BsAaKhB+7X+H4GnSjGhJG9Qi8Tw+inU9nJDwmD5CgOmBLEI6ArdhikpLX7DjbjDRDTbqZzU2LSQNZg8WGPiSZQ=="
|
||||
},
|
||||
"node_modules/@types/pg": {
|
||||
"version": "8.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.6.tgz",
|
||||
"integrity": "sha512-O2xNmXebtwVekJDD+02udOncjVcMZQuTEQEMpKJ0ZRf5E7/9JJX3izhKUcUifBkyKpljyUM6BTgy2trmviKlpw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"pg-protocol": "*",
|
||||
"pg-types": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/qs": {
|
||||
"version": "6.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^18.16.0",
|
||||
"@types/pg": "^8.6.6",
|
||||
"nodemon": "^2.0.22",
|
||||
"ts-node-dev": "^2.0.0",
|
||||
"typescript": "^5.0.4"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import express from 'express';
|
||||
const stam = 'fds'
|
||||
import routes from './routes';
|
||||
|
||||
const app = express();
|
||||
|
|
|
@ -1,42 +1,114 @@
|
|||
import { Request, Response } from 'express';
|
||||
import { resolveAddress } from './geocoding';
|
||||
import { Address, AvailableTimeslots } from './types';
|
||||
import { randomUUID } from 'crypto';
|
||||
// DOME
|
||||
import { getAvailableTimeSlots } from './services/timeslotsService';
|
||||
import { getHolidays } from './services/holidaysService';
|
||||
|
||||
const env = require('dotenv');
|
||||
|
||||
// create a hashing for caching delivery slots. this needs to be a caching db.
|
||||
const deliveriesCache = new Map();
|
||||
// create a hashing for caching timeslots. this needs to be a caching db.
|
||||
const slotsInUse = new Map();
|
||||
|
||||
export const resolveAddressHandler = (req: Request, res: Response) => {
|
||||
console.info("resolveAddressHandler called");
|
||||
if (!req.body.searchTerm) {
|
||||
res.status(400).json({ error: 'Missing searchTerm' });
|
||||
return;
|
||||
}
|
||||
const address: Promise<Address> = resolveAddress(req.body.searchTerm);
|
||||
address.then((result) => {
|
||||
console.info("resolveAddressHandler result: ", result);
|
||||
res.status(200).json(result);
|
||||
})
|
||||
};
|
||||
|
||||
export const timeslotsHandler = async (req: Request, res: Response) => {
|
||||
// TODO: Implement timeslots functionality
|
||||
if (!req.body.address) {
|
||||
res.status(400).json({ error: 'Missing address' });
|
||||
return;
|
||||
}
|
||||
const address: Address = req.body.address;
|
||||
const timeSlots: AvailableTimeslots[] = await availableTimeSlots(address);
|
||||
const availableTimeSlotsResult = await filterOutHolidaysByCountryCode(address, timeSlots);
|
||||
const availableTimeSlotsResult: AvailableTimeslots[] = await filterOutHolidaysByCountryCode(address, timeSlots);
|
||||
|
||||
availableTimeSlotsResult.forEach((timeSlot, index) => {
|
||||
if (slotsInUse.has(timeSlot.id) && slotsInUse.get(timeSlot.id).length >= 2) {
|
||||
availableTimeSlotsResult.splice(index, 1);
|
||||
}
|
||||
});
|
||||
res.status(200).json(availableTimeSlotsResult);
|
||||
};
|
||||
|
||||
export const deliveriesHandler = (req: Request, res: Response) => {
|
||||
// TODO: Implement deliveries functionality
|
||||
const userId = req.body.userId;
|
||||
const slotId = req.body.timeslotId;
|
||||
|
||||
// Idea: validate userId and slotId needed
|
||||
if (!userId || !slotId) {
|
||||
res.status(400).json({ error: 'Missing userId or slotId' });
|
||||
return;
|
||||
}
|
||||
|
||||
// Idea: check if user has already booked a delivery
|
||||
// if (deliveriesCache.has(userId) && deliveriesCache.get(userId).slotId === slotId) {
|
||||
// res.status(400).json({ error: 'User has already booked a delivery' });
|
||||
// return;
|
||||
// }
|
||||
|
||||
// Idea: check if timeslot is already full in cache
|
||||
if (slotsInUse.has(slotId) && slotsInUse.get(slotId).length >= 2) {
|
||||
res.status(400).json({ error: 'This timeslot is already full' });
|
||||
return;
|
||||
}
|
||||
const deliveryId = randomUUID();
|
||||
|
||||
// Idea: create new delivery for user
|
||||
const delivery = {
|
||||
_id: deliveryId,
|
||||
userId,
|
||||
slotId,
|
||||
deliveryCreatedDate: new Date()
|
||||
};
|
||||
if (slotsInUse.has(slotId)) {
|
||||
slotsInUse.get(slotId).push(deliveryId);
|
||||
} else {
|
||||
slotsInUse.set(slotId, [deliveryId]);
|
||||
}
|
||||
deliveriesCache.set(deliveryId, delivery);
|
||||
|
||||
console.log("deliveriesCache", deliveriesCache)
|
||||
console.log("slotsInUse", slotsInUse)
|
||||
res.status(200).json(delivery);
|
||||
};
|
||||
|
||||
|
||||
export const cancelDeliveryHandler = (req: Request, res: Response) => {
|
||||
// TODO: Implement cancel delivery functionality
|
||||
// DELETE /deliveries/:deliveryId
|
||||
const deliveryId = req.params.deliveryId;
|
||||
|
||||
if (!deliveryId) {
|
||||
res.status(400).json({ error: 'Missing deliveryId' });
|
||||
return;
|
||||
}
|
||||
|
||||
// remove from deliveriesCache and extract slotId
|
||||
const delivery = deliveriesCache.get(deliveryId);
|
||||
if (!delivery) {
|
||||
res.status(400).json({ error: 'Delivery not found' });
|
||||
return;
|
||||
}
|
||||
const slotId = delivery.slotId;
|
||||
deliveriesCache.delete(deliveryId);
|
||||
// remove from slotsInUse by slotId
|
||||
const slot = slotsInUse.get(slotId);
|
||||
const index = slot.indexOf(deliveryId);
|
||||
if (index > -1) {
|
||||
slot.splice(index, 1);
|
||||
}
|
||||
res.status(200).json(delivery);
|
||||
};
|
||||
|
||||
export const dailyDeliveriesHandler = (req: Request, res: Response) => {
|
||||
|
@ -49,13 +121,12 @@ export const weeklyDeliveriesHandler = (req: Request, res: Response) => {
|
|||
|
||||
|
||||
|
||||
async function filterOutHolidaysByCountryCode(address: Address, availableTimeSlot: AvailableTimeslots[]) {
|
||||
async function filterOutHolidaysByCountryCode(address: Address, availableTimeSlot: AvailableTimeslots[]): Promise<AvailableTimeslots[]> {
|
||||
const countryCode = address.code;
|
||||
const holidays = await getHolidays();
|
||||
|
||||
const filteredAvailableTimeSlot = [];
|
||||
|
||||
|
||||
console.log(availableTimeSlot)
|
||||
holidays.forEach((holiday) => {
|
||||
if (holiday.country === countryCode) {
|
||||
|
@ -77,6 +148,7 @@ async function availableTimeSlots(address: Address) {
|
|||
for (const timeslot of timeslots.courier_available_timeslots) {
|
||||
if (timeslot.supported_postcodes.includes(address.postcode)) {
|
||||
availableTimeSlot.push({
|
||||
id: timeslot.id,
|
||||
start_time: timeslot.start_time,
|
||||
end_time: timeslot.end_time
|
||||
});
|
||||
|
|
|
@ -4,10 +4,10 @@ import { resolveAddressHandler, timeslotsHandler, deliveriesHandler, cancelDeliv
|
|||
const router = express.Router();
|
||||
|
||||
router.post('/resolve-address', resolveAddressHandler);
|
||||
router.delete('/deliveries/:deliveryId', cancelDeliveryHandler);
|
||||
router.post('/timeslots', timeslotsHandler);
|
||||
router.get('/deliveries/daily', dailyDeliveriesHandler);
|
||||
router.get('/deliveries/weekly', weeklyDeliveriesHandler);
|
||||
router.post('/deliveries', deliveriesHandler);
|
||||
router.delete('/deliveries/:id', cancelDeliveryHandler);
|
||||
|
||||
export default router;
|
Loading…
Reference in a new issue