Skip to content

Commit 378c533

Browse files
authored
backend: add typed response models for public profile routes (#69)
1 parent f477807 commit 378c533

1 file changed

Lines changed: 85 additions & 8 deletions

File tree

apps/backend/src/routes/public.ts

Lines changed: 85 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,69 @@
11
import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
22
import { generateQRBuffer, generateQRSvg } from '../utils/qr.js';
33

4+
type PublicProfileLink = {
5+
id: string;
6+
platform: string;
7+
username: string;
8+
url: string;
9+
displayOrder: number;
10+
}
11+
12+
type UsernamePublicProfileResponse = {
13+
username: string;
14+
displayName: string;
15+
bio: string | null;
16+
pronouns: string | null;
17+
role: string | null;
18+
company: string | null;
19+
avatarUrl: string | null;
20+
accentColor: string;
21+
links: PublicProfileLink[]
22+
}
23+
24+
type PublicProfileCardLink = {
25+
id: string;
26+
platform: string;
27+
username: string;
28+
url: string;
29+
}
30+
31+
type CardPublicProfileResponse = {
32+
id: string;
33+
title: string;
34+
owner: {
35+
username: string;
36+
displayName: string;
37+
bio: string | null;
38+
avatarUrl: string | null;
39+
accentColor: string;
40+
};
41+
links: PublicProfileCardLink[]
42+
}
43+
44+
type UsernameCardPublicProfileResponse = {
45+
title: string;
46+
owner: {
47+
username: string;
48+
displayName: string;
49+
bio: string | null;
50+
pronouns: string | null;
51+
role: string | null;
52+
company: string | null;
53+
avatarUrl: string | null;
54+
accentColor: string;
55+
};
56+
links: PublicProfileCardLink[]
57+
}
58+
59+
60+
461
export async function publicRoutes(app: FastifyInstance) {
562
// ─── Public Profile ───
6-
63+
/**
64+
* GET /api/public/:username
65+
* Returns the public profile information for a user.
66+
*/
767
app.get('/:username', async (request: FastifyRequest<{ Params: { username: string } }>, reply: FastifyReply) => {
868
const { username } = request.params;
969

@@ -50,7 +110,7 @@ export async function publicRoutes(app: FastifyInstance) {
50110
}).catch(err => app.log.error('Failed to log view:', err));
51111
}
52112

53-
return {
113+
const response: UsernamePublicProfileResponse = {
54114
username: user.username,
55115
displayName: user.displayName,
56116
bio: user.bio,
@@ -66,9 +126,17 @@ export async function publicRoutes(app: FastifyInstance) {
66126
url: link.url,
67127
displayOrder: link.displayOrder,
68128
})),
69-
};
129+
}
130+
131+
return response;
132+
70133
});
71134

135+
/**
136+
* GET /api/public/card/:cardId
137+
* Returns public data for a shared card via its direct link.
138+
* Used for standalone card sharing (minimal owner info).
139+
*/
72140
// ─── Shared Card View (Direct) ───
73141

74142
app.get('/card/:cardId', async (request: FastifyRequest<{ Params: { cardId: string } }>, reply: FastifyReply) => {
@@ -89,7 +157,7 @@ export async function publicRoutes(app: FastifyInstance) {
89157
return reply.status(404).send({ error: 'Card not found' });
90158
}
91159

92-
return {
160+
const response: CardPublicProfileResponse = {
93161
id: card.id,
94162
title: card.title,
95163
owner: {
@@ -105,11 +173,18 @@ export async function publicRoutes(app: FastifyInstance) {
105173
username: cl.platformLink.username,
106174
url: cl.platformLink.url,
107175
})),
108-
};
176+
}
177+
178+
return response;
179+
109180
});
110181

111182
// ─── Public Card View ───
112-
183+
/**
184+
* GET /api/public/:username/card/:cardId
185+
* Returns full owner profile + specific card data.
186+
* Used when viewing a card through username + cardId (e.g. QR code scans).
187+
*/
113188
app.get('/:username/card/:cardId', async (request: FastifyRequest<{ Params: { username: string; cardId: string } }>, reply: FastifyReply) => {
114189
const { username, cardId } = request.params;
115190

@@ -158,7 +233,8 @@ export async function publicRoutes(app: FastifyInstance) {
158233
}).catch(err => app.log.error('Failed to log card view:', err));
159234
}
160235

161-
return {
236+
237+
const response: UsernameCardPublicProfileResponse = {
162238
title: card.title,
163239
owner: {
164240
username: user.username,
@@ -177,7 +253,8 @@ export async function publicRoutes(app: FastifyInstance) {
177253
url: cl.platformLink.url,
178254
displayOrder: cl.displayOrder,
179255
})),
180-
};
256+
}
257+
return response;
181258
});
182259

183260
// ─── QR Code Generation ───

0 commit comments

Comments
 (0)