Skip to content

Commit

Permalink
Merge pull request #59 from yeha98555/feature/delete-expired-order
Browse files Browse the repository at this point in the history
Feature/delete-expired-order
  • Loading branch information
yurychang committed Jun 13, 2023
2 parents 8f7c374 + 9c0e3b3 commit 07c4380
Show file tree
Hide file tree
Showing 16 changed files with 70 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ MONGODB_CONNECT_STRING=mongodb+srv://<user>:<password>@rabbit.xb8tvht.mongodb.ne
# production
MONGODB_ENDPOINT=<docdb.amazonaws.com.endpoint>

# redis
REDIS_CONNECT_STRING=redis://127.0.0.1:6379/0

JWT_SECRET=secert

LOG_FILE_DIR=logs
Expand Down
1 change: 1 addition & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import './registerMongoosePlugins';
import './connections';
import './redis/orderExpireSubscriber';
import express, { Request, Response, NextFunction } from 'express';
import morgan from 'morgan';
import cors from 'cors';
Expand Down
2 changes: 1 addition & 1 deletion src/connections/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import mongoose from 'mongoose';
import connectToDocDB from './docdb';
import './redis';

if (process.env.NODE_ENV === 'development') {
const DB = process.env.MONGODB_CONNECT_STRING.replace(
Expand All @@ -13,4 +14,3 @@ if (process.env.NODE_ENV === 'development') {
} else {
connectToDocDB();
}

3 changes: 3 additions & 0 deletions src/connections/redis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { Redis } from 'ioredis';

export const redis = new Redis(process.env.REDIS_CONNECT_STRING);
Empty file removed src/controllers/.gitkeep
Empty file.
1 change: 1 addition & 0 deletions src/d/environment.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ declare namespace NodeJS {
PAYMENT_RETURN_URL: string;
TICKET_CHECKING_KEY: string;
TICKET_CHECKING_IV: string;
REDIS_CONNECT_STRING: string;
}
}
2 changes: 1 addition & 1 deletion src/enums/orderStatus.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export enum OrderStatus {
TEMP,
PENDING,
SUCCESS,
CANCELLED,
}
2 changes: 1 addition & 1 deletion src/models/order.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const orderSchema = new Schema(
},
status: {
type: Number,
default: OrderStatus.TEMP,
default: OrderStatus.PENDING,
validate: toValidate(z.nativeEnum(OrderStatus)),
},
price: { type: Number, required: true },
Expand Down
33 changes: 33 additions & 0 deletions src/redis/orderExpireSubscriber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { Redis } from 'ioredis';
import { redis } from '@/connections/redis';
import OrderModel from '@/models/order';
import { OrderStatus } from '@/enums/orderStatus';
import SeatReservationModel from '@/models/seatReservation';

const sub = new Redis(redis.options);
const redisDB = redis.options.db;

const channel = `__keyevent@${redisDB}__:expired`;
export const key = (orderId: string) => `order-expire-checking-${orderId}`;

const isOrderExpiredEvent = (key: string) =>
key.startsWith('order-expire-checking-');
const getOrderId = (key: string) => key.replace('order-expire-checking-', '');

sub.subscribe(channel, (err) => {
if (err) {
throw err;
}
});

sub.on('message', (channel, key) => {
isOrderExpiredEvent(key) && onOrderExpire(getOrderId(key));
});

async function onOrderExpire(orderId: string) {
const order = await OrderModel.findById(orderId);
if (!order || order.status !== OrderStatus.PENDING) return;

await SeatReservationModel.findByIdAndDelete(order.seat_reservation_id);
await order.deleteOne();
}
20 changes: 16 additions & 4 deletions src/services/order/addOrder.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import { Types } from 'mongoose';
import * as d from 'date-fns';

import { NotFoundException } from '@/exceptions/NotFoundException';
import ActivityModel from '@/models/activity';
import OrderModel from '@/models/order';

import { Types } from 'mongoose';
import createOrderNo from './createOrderNo';
import UserModel from '@/models/user';
import * as d from 'date-fns';
import { EventNotOnSaleException } from '@/exceptions/EventNotOnSale';
import { redis } from '@/connections/redis';
import { key } from '@/redis/orderExpireSubscriber';
import reserveSeats from '../reserveSeats';
import createOrderNo from './createOrderNo';

const orderExpireTime = 1200; // seconds

const addOrder = async (
userId: string,
Expand Down Expand Up @@ -64,6 +68,8 @@ const addOrder = async (
throw error;
}

setOrderExpireEvent(order._id.toString(), orderExpireTime);

const user = await UserModel.findById(userId);

return {
Expand Down Expand Up @@ -96,4 +102,10 @@ const addOrder = async (
};
};

function setOrderExpireEvent(orderId: string, expire: number) {
const k = key(orderId);
redis.set(k, '');
redis.expire(k, expire);
}

export default addOrder;
3 changes: 2 additions & 1 deletion src/services/order/addSeats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ const addSeats = async ({
subAreaId: string;
amount: number;
}) => {
if (order.status !== OrderStatus.TEMP) throw new OrderCannotModifyException();
if (order.status !== OrderStatus.PENDING)
throw new OrderCannotModifyException();

const activity = await ActivityModel.findOne({
_id: order.activity_id,
Expand Down
3 changes: 2 additions & 1 deletion src/services/order/cancelOrder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ const cancelOrder = async (userId: string, orderNo: string) => {
const order = await OrderModel.findOne({ user_id: userId }).byNo(orderNo);

if (!order) throw new NotFoundException();
if (order.status !== OrderStatus.TEMP) throw new OrderCannotModifyException();
if (order.status !== OrderStatus.PENDING)
throw new OrderCannotModifyException();

await SeatReservationModel.findByIdAndDelete(order.seat_reservation_id);
await order.deleteOne();
Expand Down
3 changes: 2 additions & 1 deletion src/services/order/deleteSeat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ const deleteSeat = async ({
row: number;
seat: number;
}) => {
if (order.status !== OrderStatus.TEMP) throw new OrderCannotModifyException();
if (order.status !== OrderStatus.PENDING)
throw new OrderCannotModifyException();

const reservation = await SeatReservationModel.findById(
order.seat_reservation_id,
Expand Down
2 changes: 1 addition & 1 deletion src/services/order/getOrders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const getOrders = async ({
user_id: new Types.ObjectId(userId),
status:
status === 'unpaid'
? OrderStatus.TEMP
? OrderStatus.PENDING
: { $in: [OrderStatus.SUCCESS, OrderStatus.CANCELLED] },
};

Expand Down
3 changes: 2 additions & 1 deletion src/services/order/payment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ const payment = async (userId: string, orderNo: string) => {
.populate<{ activity_id: Activity }>('activity_id', 'name start_at');

if (!order) throw new NotFoundException();
if (order.status !== OrderStatus.TEMP) throw new OrderCannotModifyException();
if (order.status !== OrderStatus.PENDING)
throw new OrderCannotModifyException();

// Calculate the number of tickets
const seatReservation = await SeatReservationModel.findById(
Expand Down
2 changes: 1 addition & 1 deletion src/services/order/paymentNotify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const paymentNotify = async (tradeInfo: string) => {

// Ensure info.Result.Status is not undefined
const status =
info.Status === 'SUCCESS' ? OrderStatus.SUCCESS : OrderStatus.TEMP;
info.Status === 'SUCCESS' ? OrderStatus.SUCCESS : OrderStatus.PENDING;

const order = await OrderModel.findOne({}).byNo(info.Result.MerchantOrderNo);

Expand Down

0 comments on commit 07c4380

Please sign in to comment.