feat(wallets): implement wallet movements feature with filtering and pagination
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
import type { Context } from "hono";
|
||||
import { listAllMovements } from "../wallets.service";
|
||||
|
||||
export async function listAllMovementsHandler(c: Context) {
|
||||
const walletId = c.req.query("walletId")
|
||||
? Number(c.req.query("walletId"))
|
||||
: undefined;
|
||||
const startDate = c.req.query("startDate") || undefined;
|
||||
const endDate = c.req.query("endDate") || undefined;
|
||||
const page = parseInt(c.req.query("page") ?? "1", 10);
|
||||
const pageSize = parseInt(c.req.query("pageSize") ?? "20", 10);
|
||||
|
||||
const result = await listAllMovements({
|
||||
walletId,
|
||||
startDate,
|
||||
endDate,
|
||||
page,
|
||||
pageSize,
|
||||
});
|
||||
return c.json(result);
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import { adjustBalanceHandler } from "./handlers/adjustBalance";
|
||||
import { createWalletHandler } from "./handlers/createWallet";
|
||||
import { deleteWalletHandler } from "./handlers/deleteWallet";
|
||||
import { depositWalletHandler } from "./handlers/depositWallet";
|
||||
import { listAllMovementsHandler } from "./handlers/listAllMovements";
|
||||
import { listMovementsHandler } from "./handlers/listMovements";
|
||||
import { listWalletsHandler } from "./handlers/listWallets";
|
||||
import { transferWalletHandler } from "./handlers/transferWallet";
|
||||
@@ -11,6 +12,7 @@ import { setDefaultWalletHandler } from "./handlers/setDefaultWallet";
|
||||
|
||||
const app = new Hono();
|
||||
|
||||
app.get("/movements", listAllMovementsHandler);
|
||||
app.get("/", listWalletsHandler);
|
||||
app.post("/", createWalletHandler);
|
||||
app.put("/:id", updateWalletHandler);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { z } from "zod";
|
||||
import { Prisma } from "../../generated/prisma/client";
|
||||
import { prisma } from "../../lib/prisma";
|
||||
import { cache } from "../../lib/cache";
|
||||
|
||||
export const createWalletSchema = z.object({
|
||||
name: z.string().min(1).max(100),
|
||||
@@ -192,3 +193,51 @@ export async function listMovements(walletId: number) {
|
||||
});
|
||||
return movements.map((m) => ({ ...m, amount: Number(m.amount) }));
|
||||
}
|
||||
|
||||
export async function listAllMovements(params: {
|
||||
walletId?: number;
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
}) {
|
||||
const { walletId, startDate, endDate, page = 1, pageSize = 20 } = params;
|
||||
|
||||
const cacheKey = `movements:all:${walletId ?? "all"}:${startDate ?? ""}:${endDate ?? ""}:${page}:${pageSize}`;
|
||||
const cached = cache.get(cacheKey);
|
||||
if (cached) return cached;
|
||||
|
||||
const where: Record<string, unknown> = {};
|
||||
if (walletId !== undefined) {
|
||||
where.walletId = walletId;
|
||||
}
|
||||
if (startDate || endDate) {
|
||||
const createdAt: Record<string, Date> = {};
|
||||
if (startDate) createdAt.gte = new Date(startDate);
|
||||
if (endDate) {
|
||||
const end = new Date(endDate);
|
||||
end.setHours(23, 59, 59, 999);
|
||||
createdAt.lte = end;
|
||||
}
|
||||
where.createdAt = createdAt;
|
||||
}
|
||||
|
||||
const [data, total] = await Promise.all([
|
||||
prisma.walletMovement.findMany({
|
||||
where,
|
||||
orderBy: { createdAt: "desc" },
|
||||
skip: (page - 1) * pageSize,
|
||||
take: pageSize,
|
||||
}),
|
||||
prisma.walletMovement.count({ where }),
|
||||
]);
|
||||
|
||||
const result = {
|
||||
data: data.map((m) => ({ ...m, amount: Number(m.amount) })),
|
||||
total,
|
||||
page,
|
||||
pageSize,
|
||||
};
|
||||
cache.set(cacheKey, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user