Skip to content

Commit bc1cc06

Browse files
committed
fix(cards): address review feedback
1 parent 02beb8e commit bc1cc06

2 files changed

Lines changed: 29 additions & 16 deletions

File tree

apps/backend/src/__tests__/cards.test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { describe, it, expect, beforeEach, vi } from 'vitest';
2-
import Fastify from 'fastify';
2+
import Fastify, { FastifyRequest } from 'fastify';
3+
import { Prisma } from '@prisma/client';
34
import { cardRoutes } from '../routes/cards.js';
45

56
const USER_ID = 'user-123';
@@ -45,14 +46,14 @@ const mockPrisma = {
4546
// against the same mock client, preserving existing per-operation mocks.
4647
function wireTransaction() {
4748
mockPrisma.$transaction.mockImplementation(
48-
async (callback: (tx: typeof mockPrisma) => Promise<unknown>, options?: any) => callback(mockPrisma),
49+
async (callback: (tx: typeof mockPrisma) => Promise<unknown>, options?: unknown) => callback(mockPrisma),
4950
);
5051
}
5152

5253
async function buildApp() {
5354
const app = Fastify({ logger: false });
5455
app.decorate('prisma', mockPrisma);
55-
app.decorate('authenticate', async (request: any) => {
56+
app.decorate('authenticate', async (request: FastifyRequest & { user?: { id: string } }) => {
5657
request.user = { id: USER_ID };
5758
});
5859
app.register(cardRoutes, { prefix: '/api/cards' });
@@ -204,8 +205,8 @@ describe('POST /api/cards — link ownership validation', () => {
204205

205206
// First attempt fails with P2034 (serialization conflict)
206207
// Second attempt succeeds
207-
const error = new Error('Serialization failure');
208-
(error as any).code = 'P2034';
208+
const error = new Error('Serialization failure') as Error & { code: string };
209+
error.code = 'P2034';
209210

210211
// We mock $transaction to fail once, then succeed
211212
mockPrisma.$transaction

apps/backend/src/services/cardService.ts

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
import type { FastifyInstance } from 'fastify'
2-
import type { Prisma } from '@prisma/client'
2+
3+
4+
type RawCard = { id: string, title: string, isDefault: boolean, cardLinks: { platformLink: unknown }[] };
35

46
export async function listCards(app: FastifyInstance, userId: string) {
57
const cards = await app.prisma.card.findMany({
68
where: { userId },
79
take: 50,
810
include: { cardLinks: { include: { platformLink: true }, orderBy: { displayOrder: 'asc' } } },
911
orderBy: { createdAt: 'asc' },
10-
})
12+
}) as unknown as RawCard[];
1113

12-
return cards.map((card: any) => ({ id: card.id, title: card.title, isDefault: card.isDefault, links: card.cardLinks.map((cl: any) => cl.platformLink) }))
14+
return cards.map((card) => ({ id: card.id, title: card.title, isDefault: card.isDefault, links: card.cardLinks.map((cl) => cl.platformLink) }))
1315
}
1416

1517
export async function createCard(app: FastifyInstance, userId: string, body: { title: string; linkIds: string[] }) {
@@ -34,12 +36,21 @@ export async function createCard(app: FastifyInstance, userId: string, body: { t
3436
include: { cardLinks: { include: { platformLink: true }, orderBy: { displayOrder: 'asc' } } },
3537
})
3638
}, {
37-
isolationLevel: 'Serializable' as Prisma.TransactionIsolationLevel
38-
})
39-
40-
return { id: card.id, title: card.title, isDefault: card.isDefault, links: card.cardLinks.map((cl: any) => cl.platformLink) }
41-
} catch (error: any) {
42-
if (error.code === 'P2034' && attempt < MAX_RETRIES) continue;
39+
isolationLevel: 'Serializable'
40+
}) as unknown as RawCard;
41+
42+
return { id: card.id, title: card.title, isDefault: card.isDefault, links: card.cardLinks.map((cl) => cl.platformLink) }
43+
} catch (error: unknown) {
44+
if (
45+
typeof error === 'object' &&
46+
error !== null &&
47+
'code' in error &&
48+
(error as { code: string }).code === 'P2034' &&
49+
attempt < MAX_RETRIES
50+
) {
51+
continue;
52+
}
53+
app.log.error(error);
4354
throw error;
4455
}
4556
}
@@ -68,8 +79,9 @@ export async function updateCard(app: FastifyInstance, userId: string, id: strin
6879
})
6980
}
7081

71-
const updated = await app.prisma.card.findUnique({ where: { id }, include: { cardLinks: { include: { platformLink: true }, orderBy: { displayOrder: 'asc' } } } })
72-
return { id: updated!.id, title: updated!.title, isDefault: updated!.isDefault, links: updated!.cardLinks.map((cl: any) => cl.platformLink) }
82+
const updated = (await app.prisma.card.findUnique({ where: { id }, include: { cardLinks: { include: { platformLink: true }, orderBy: { displayOrder: 'asc' } } } })) as unknown as RawCard | null;
83+
if (!updated) return null;
84+
return { id: updated.id, title: updated.title, isDefault: updated.isDefault, links: updated.cardLinks.map((cl) => cl.platformLink) }
7385
}
7486

7587
export async function deleteCard(app: FastifyInstance, userId: string, id: string) {

0 commit comments

Comments
 (0)