diff --git a/app/server/routers/learn.ts b/app/server/routers/learn.ts index c98bbab..8492a75 100644 --- a/app/server/routers/learn.ts +++ b/app/server/routers/learn.ts @@ -44,12 +44,14 @@ export const learnRouting = { .input( z.object({ name: z.string().min(1).max(100), - list: z.array( - z.object({ - vraag: z.string().min(1).max(100), - antwoord: z.string().min(1).max(100), - }), - ), + list: z + .array( + z.object({ + vraag: z.string().min(1).max(100), + antwoord: z.string().min(1).max(100), + }), + ) + .max(1500), id: z.uuid().optional(), language: z.enum(taalSlugsList), fromLanguage: z.enum(taalSlugsList), @@ -57,6 +59,15 @@ export const learnRouting = { }), ) .mutation(async ({ input, ctx }) => { + const dag = 24 * 60 * 60 * 1000; + const limit = + Date.now() - ctx.user.createdAt.getTime() < 30 * dag ? 750 : 1500; + if (input.list.length > limit) { + throw new TRPCError({ + code: "BAD_REQUEST", + message: `Een lijst mag maximaal ${limit} vragen hebben`, + }); + } if (!input.id) { const list = await ctx.prisma.list.create({ data: { diff --git a/app/server/trpc.ts b/app/server/trpc.ts index 038f7be..df371f3 100644 --- a/app/server/trpc.ts +++ b/app/server/trpc.ts @@ -55,6 +55,7 @@ const withResolvedUser = t.middleware(async ({ ctx, next, path }) => { banned: true, forumBanned: true, theme: true, + createdAt: true, }, }); diff --git a/tests/trpc.endpoints.test.ts b/tests/trpc.endpoints.test.ts index a476a80..5f8b4e8 100644 --- a/tests/trpc.endpoints.test.ts +++ b/tests/trpc.endpoints.test.ts @@ -261,6 +261,53 @@ describe("tRPC endpoints (integration)", () => { expect(updated.listItems[0].vraag).toBe("vraag2"); expect(updated.listItems[0].antwoord).toBe("antwoord2"); }); + + describe("item cap", () => { + const items = (n: number) => + Array.from({ length: n }, (_, i) => ({ + vraag: `v${i}`, + antwoord: `a${i}`, + })); + const save = ( + caller: ReturnType["caller"], + n: number, + ) => + caller.learn.upsertList({ + name: `cap-${Date.now()}`, + list: items(n), + language: TaalSlugEnum.NL, + fromLanguage: TaalSlugEnum.EN, + toLanguage: TaalSlugEnum.NL, + }); + + it("new accounts 750 words max", async () => { + const user = await createTestUser(); + const { caller } = makeCaller({ id: user.id }); + + const created = await save(caller, 750); + createdListIds.add(created.id); + expect(created.listItems.length).toBe(750); + + await expect(save(caller, 751)).rejects.toThrow("maximaal 750"); + }); + + it("old accounts 1.5K words max", async () => { + const user = await createTestUser(); + await prisma.user.update({ + where: { id: user.id }, + data: { + createdAt: new Date(Date.now() - 31 * 24 * 60 * 60 * 1000), + }, + }); + const { caller } = makeCaller({ id: user.id }); + + const created = await save(caller, 1500); + createdListIds.add(created.id); + expect(created.listItems.length).toBe(1500); + + await expect(save(caller, 1501)).rejects.toThrow(); + }); + }); }); it("get the users lists", async () => {