Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | 6x 6x 8x 8x 8x 8x 5x 5x 8x 8x 8x 16x 6x 7x 7x 8x 6x | import { z } from "zod";
import {
debtsFiltersSchema,
limitSchema,
offsetSchema,
} from "~app/utils/validation";
import type { PeerId } from "~db/ids";
import { queueCallFactory } from "~web/handlers/batch";
import type { AuthorizedContext } from "~web/handlers/context";
import { authProcedure } from "~web/handlers/trpc";
import type { GeneralOutput } from "~web/utils/batch";
import { queueList } from "~web/utils/batch";
const inputSchema = z.strictObject({
cursor: offsetSchema,
limit: limitSchema,
filters: debtsFiltersSchema.optional(),
});
type Input = z.infer<typeof inputSchema>;
type Output = GeneralOutput<PeerId> & { count: number };
const fetchPage = async (
{ database, auth }: AuthorizedContext,
input: Input,
) => {
const debtSummaries = database
.with("debtSummaries", () =>
database
.selectFrom("debts")
.where("debts.ownerUserId", "=", auth.userId)
.innerJoin("peers", (qb) => qb.onRef("peers.id", "=", "debts.peerId"))
.select([
"debts.peerId",
"peers.name",
"debts.currencyCode",
database.fn.sum<string>("debts.amount").as("sum"),
])
.groupBy(["debts.peerId", "peers.name", "debts.currencyCode"]),
)
.selectFrom("debtSummaries");
const peers = debtSummaries.$if(!input.filters?.showResolved, (qb) =>
qb.where(
"peerId",
"not in",
debtSummaries
.select("peerId")
.groupBy("peerId")
.having(
(eb) => eb.fn.count(eb.case().when("sum", "<>", "0").then(1).end()),
"=",
0,
),
),
);
const [paginatedPeers, totalCount] = await Promise.all([
peers
.select("peerId")
.groupBy(["name", "peerId"])
.orderBy("name")
.orderBy("peerId")
.offset(input.cursor)
.limit(input.limit)
.execute(),
database
.selectFrom(peers.select("peerId").groupBy("peerId").as("groupedPeers"))
.select((eb) => eb.fn.count<number>("peerId").as("count"))
.executeTakeFirstOrThrow(),
]);
return {
count: totalCount.count,
cursor: input.cursor,
items: paginatedPeers.map(({ peerId }) => peerId),
};
};
const queuePeerList = queueCallFactory<AuthorizedContext, Input, Output>(
(ctx) => async (inputs) =>
queueList<Input, PeerId, Output>(inputs, (values) =>
fetchPage(ctx, values),
),
);
export const procedure = authProcedure
.meta({
title: "Get peers with debts, paged",
description:
"Returns a page of peerIds the current user has debts with, optionally excluding peers whose debts are fully resolved.",
})
.input(inputSchema)
.query(queuePeerList);
|