Skip to content

Commit 3ae414a

Browse files
authored
fix(cards): improve typing, transaction safety, and resolve lint issues (#327)
1 parent f4213b6 commit 3ae414a

1 file changed

Lines changed: 46 additions & 13 deletions

File tree

apps/backend/src/routes/cards.ts

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
2-
import type { Card } from '@devcard/shared';
3-
import { createCardSchema, updateCardSchema } from '../utils/validators.js';
41
import { handleDbError } from '../utils/error.util.js';
2+
import { createCardSchema, updateCardSchema } from '../utils/validators.js';
3+
4+
import type { Card } from '@devcard/shared';
5+
import type { Prisma } from '@prisma/client';
6+
import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
7+
58

69
interface CreateCardBody {
710
title: string;
@@ -17,8 +20,36 @@ interface CardParams {
1720
id: string;
1821
}
1922

23+
interface PlatformLink {
24+
id: string;
25+
userId: string;
26+
platform: string;
27+
username: string;
28+
url: string;
29+
displayOrder: number;
30+
createdAt: Date;
31+
}
32+
33+
interface CardLinkWithPlatform {
34+
id: string;
35+
cardId: string;
36+
platformLinkId: string;
37+
displayOrder: number;
38+
platformLink: PlatformLink;
39+
}
40+
41+
interface CardWithLinks {
42+
id: string;
43+
userId: string;
44+
title: string;
45+
isDefault: boolean;
46+
createdAt: Date;
47+
updatedAt: Date;
48+
cardLinks: CardLinkWithPlatform[];
49+
}
50+
2051
export async function cardRoutes(app: FastifyInstance): Promise<void> {
21-
app.addHook('preHandler', app.authenticate);
52+
app.addHook('preHandler', app.authenticate.bind(app));
2253

2354
// ─── List Cards ───
2455

@@ -38,11 +69,11 @@ export async function cardRoutes(app: FastifyInstance): Promise<void> {
3869
orderBy: { createdAt: 'asc' },
3970
});
4071

41-
return cards.map((card) => ({
72+
return cards.map((card:CardWithLinks) => ({
4273
id: card.id,
4374
title: card.title,
4475
isDefault: card.isDefault,
45-
links: card.cardLinks.map((cl) => cl.platformLink) as any,
76+
links: card.cardLinks.map((cl) => cl.platformLink),
4677
}));
4778
} catch (error) {
4879
return handleDbError(error, request, reply);
@@ -98,12 +129,14 @@ export async function cardRoutes(app: FastifyInstance): Promise<void> {
98129
},
99130
});
100131

101-
return reply.status(201).send({
102-
id: card.id,
132+
const response = {
133+
id: card.id,
103134
title: card.title,
104135
isDefault: card.isDefault,
105-
links: card.cardLinks.map((cl) => cl.platformLink) as any,
106-
});
136+
links: card.cardLinks.map((cl: CardLinkWithPlatform) => cl.platformLink),
137+
}
138+
139+
return reply.status(201).send(response);
107140
} catch (error) {
108141
return handleDbError(error, request, reply);
109142
}
@@ -153,7 +186,7 @@ export async function cardRoutes(app: FastifyInstance): Promise<void> {
153186
// Replace links inside a transaction so the card is never left linkless
154187
// when deleteMany succeeds but createMany subsequently fails.
155188
const linkIds = parsed.data.linkIds;
156-
await app.prisma.$transaction(async (tx) => {
189+
await app.prisma.$transaction(async (tx:Prisma.TransactionClient) => {
157190
await tx.cardLink.deleteMany({ where: { cardId: id } });
158191
if (linkIds.length > 0) {
159192
await tx.cardLink.createMany({
@@ -181,7 +214,7 @@ export async function cardRoutes(app: FastifyInstance): Promise<void> {
181214
id: updated!.id,
182215
title: updated!.title,
183216
isDefault: updated!.isDefault,
184-
links: updated!.cardLinks.map((cl) => cl.platformLink) as any,
217+
links: updated!.cardLinks.map((cl:CardLinkWithPlatform) => cl.platformLink) as any,
185218
};
186219

187220
return response;
@@ -253,7 +286,7 @@ export async function cardRoutes(app: FastifyInstance): Promise<void> {
253286

254287
// Clear then set in a single transaction so there is never a window where
255288
// the user has zero default cards if the second write fails.
256-
await app.prisma.$transaction(async (tx) => {
289+
await app.prisma.$transaction(async (tx:Prisma.TransactionClient) => {
257290
await tx.card.updateMany({ where: { userId }, data: { isDefault: false } });
258291
await tx.card.update({ where: { id }, data: { isDefault: true } });
259292
});

0 commit comments

Comments
 (0)