100 lines
3.0 KiB
TypeScript
100 lines
3.0 KiB
TypeScript
import { Elysia, t } from "elysia";
|
|
import prisma from "../lib/prisma";
|
|
|
|
export const customersRoute = new Elysia({ prefix: "/customers" })
|
|
.get("/", async ({ query }) => {
|
|
const search = query.search as string | undefined;
|
|
|
|
const whereClause = search ? {
|
|
OR: [
|
|
{ displayName: { contains: search, mode: "insensitive" as any } },
|
|
{ email: { contains: search, mode: "insensitive" as any } },
|
|
{ phone: { contains: search, mode: "insensitive" as any } },
|
|
{ lineUserId: { contains: search, mode: "insensitive" as any } }
|
|
]
|
|
} : {};
|
|
|
|
return await prisma.customer.findMany({
|
|
where: whereClause,
|
|
orderBy: { createdAt: 'desc' },
|
|
include: {
|
|
_count: {
|
|
select: { orders: true }
|
|
}
|
|
}
|
|
});
|
|
})
|
|
.get("/:id", async ({ params: { id }, set }) => {
|
|
const customer = await prisma.customer.findUnique({
|
|
where: { id: Number(id) },
|
|
include: { orders: { orderBy: { createdAt: 'desc' } } }
|
|
});
|
|
if (!customer) {
|
|
set.status = 404;
|
|
return { error: "Customer not found" };
|
|
}
|
|
return customer;
|
|
})
|
|
.patch("/:id/points", async ({ params: { id }, body, set }) => {
|
|
try {
|
|
const { pointsDelta, reason } = body as { pointsDelta: number, reason?: string };
|
|
|
|
const customer = await prisma.customer.findUnique({
|
|
where: { id: Number(id) }
|
|
});
|
|
|
|
if (!customer) {
|
|
set.status = 404;
|
|
return { error: "Customer not found" };
|
|
}
|
|
|
|
const newPoints = Math.max(0, customer.points + pointsDelta);
|
|
|
|
const updatedCustomer = await prisma.customer.update({
|
|
where: { id: Number(id) },
|
|
data: { points: newPoints }
|
|
});
|
|
|
|
return updatedCustomer;
|
|
} catch (err) {
|
|
console.error("[Customers] Adjust Points Error:", err);
|
|
set.status = 500;
|
|
return { error: "Failed to adjust points" };
|
|
}
|
|
}, {
|
|
body: t.Object({
|
|
pointsDelta: t.Number(),
|
|
reason: t.Optional(t.String())
|
|
})
|
|
})
|
|
.post("/", async ({ body, set }) => {
|
|
try {
|
|
const { displayName, phone, email } = body as { displayName?: string, phone?: string, email?: string };
|
|
|
|
// Auto-generate a unique lineUserId placeholder for in-store/POS customers
|
|
const lineUserId = `POS_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
|
|
|
|
const newCustomer = await prisma.customer.create({
|
|
data: {
|
|
lineUserId,
|
|
displayName: displayName || "ลูกค้าหน้าร้าน",
|
|
phone: phone || null,
|
|
email: email || null,
|
|
points: 0
|
|
}
|
|
});
|
|
return newCustomer;
|
|
} catch (err: any) {
|
|
console.error("[Customers] Create error:", err);
|
|
set.status = 400;
|
|
return { error: err.message || "Failed to create customer" };
|
|
}
|
|
}, {
|
|
body: t.Object({
|
|
displayName: t.Optional(t.String()),
|
|
phone: t.Optional(t.String()),
|
|
email: t.Optional(t.String())
|
|
})
|
|
});
|
|
|