mirror of
https://github.com/andwati/order-service.git
synced 2026-11-03 09:42:14 +00:00
feat: update order and user repositories to use instance methods for creation and improve session handling; enhance order service with transaction management for payment and cancellation
This commit is contained in:
@@ -4,13 +4,15 @@ import { OrderModel, type OrderDocument } from "../models/order.model.js";
|
||||
export class OrderRepository {
|
||||
static create(
|
||||
data: Omit<OrderDocument, "_id" | "createdAt" | "updatedAt">,
|
||||
session: ClientSession,
|
||||
session?: ClientSession,
|
||||
): Promise<OrderDocument> {
|
||||
return OrderModel.create(data, { session });
|
||||
const order = new OrderModel(data);
|
||||
return order.save({ session: session ?? undefined });
|
||||
}
|
||||
|
||||
static findById(id: string, session?: ClientSession) {
|
||||
return OrderModel.findById(id).session(session ?? null);
|
||||
const query = OrderModel.findById(id);
|
||||
return session ? query.session(session) : query;
|
||||
}
|
||||
|
||||
static findAll() {
|
||||
|
||||
@@ -15,6 +15,7 @@ export class UserRepository {
|
||||
data: Pick<UserDocument, "email" | "passwordHash" | "role">,
|
||||
session?: ClientSession,
|
||||
): Promise<UserDocument> {
|
||||
return UserModel.create([data], { session }).then((res) => res[0]);
|
||||
const user = new UserModel(data);
|
||||
return user.save({ session: session ?? undefined });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,13 +4,86 @@ import { OrderRepository } from "../repositories/order.repo.js";
|
||||
|
||||
export class OrderService {
|
||||
static listOrders(userId: string, role: string) {
|
||||
throw new Error("Method not implemented.");
|
||||
if (String(role).toLowerCase() === "admin") {
|
||||
return OrderRepository.findAll();
|
||||
}
|
||||
|
||||
return OrderRepository.findByUser(userId);
|
||||
}
|
||||
static payOrder(id: string | string[] | undefined) {
|
||||
throw new Error("Method not implemented.");
|
||||
static async payOrder(id: string | string[] | undefined) {
|
||||
if (!id || Array.isArray(id)) {
|
||||
throw { statusCode: 400, message: "Invalid order id" };
|
||||
}
|
||||
|
||||
const session = await mongoose.startSession();
|
||||
session.startTransaction();
|
||||
|
||||
try {
|
||||
const order = await OrderRepository.findById(id, session);
|
||||
|
||||
if (!order) {
|
||||
throw { statusCode: 404, message: "Order not found" };
|
||||
}
|
||||
|
||||
if (order.status === "paid") {
|
||||
throw { statusCode: 409, message: "Order is already paid" };
|
||||
}
|
||||
|
||||
if (order.status === "cancelled") {
|
||||
throw { statusCode: 409, message: "Cannot pay a cancelled order" };
|
||||
}
|
||||
|
||||
order.status = "paid";
|
||||
await OrderRepository.save(order, session);
|
||||
|
||||
await session.commitTransaction();
|
||||
return order;
|
||||
} catch (err) {
|
||||
await session.abortTransaction();
|
||||
throw err;
|
||||
} finally {
|
||||
session.endSession();
|
||||
}
|
||||
}
|
||||
static cancelOrder(id: string | string[] | undefined) {
|
||||
throw new Error("Method not implemented.");
|
||||
static async cancelOrder(id: string | string[] | undefined) {
|
||||
if (!id || Array.isArray(id)) {
|
||||
throw { statusCode: 400, message: "Invalid order id" };
|
||||
}
|
||||
|
||||
const session = await mongoose.startSession();
|
||||
session.startTransaction();
|
||||
|
||||
try {
|
||||
const order = await OrderRepository.findById(id, session);
|
||||
|
||||
if (!order) {
|
||||
throw { statusCode: 404, message: "Order not found" };
|
||||
}
|
||||
|
||||
if (order.status === "cancelled") {
|
||||
throw { statusCode: 409, message: "Order is already cancelled" };
|
||||
}
|
||||
|
||||
// restore stock for each item
|
||||
for (const item of order.items) {
|
||||
await ProductRepository.incrementStock(
|
||||
item.productId,
|
||||
item.quantity,
|
||||
session,
|
||||
);
|
||||
}
|
||||
|
||||
order.status = "cancelled";
|
||||
await OrderRepository.save(order, session);
|
||||
|
||||
await session.commitTransaction();
|
||||
return order;
|
||||
} catch (err) {
|
||||
await session.abortTransaction();
|
||||
throw err;
|
||||
} finally {
|
||||
session.endSession();
|
||||
}
|
||||
}
|
||||
static async createOrder(
|
||||
userId: string,
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { JwtPayload } from "../utils/jwt.js";
|
||||
import { JwtPayload } from "../utils/jwt.ts";
|
||||
|
||||
declare global {
|
||||
namespace Express {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
"compilerOptions": {
|
||||
// File Layout
|
||||
"rootDir": "./src",
|
||||
// "outDir": "./dist",
|
||||
"outDir": "./dist",
|
||||
|
||||
// Environment Settings
|
||||
// See also https://aka.ms/tsconfig/module
|
||||
|
||||
Reference in New Issue
Block a user