Skip to content

Commit 44bbb26

Browse files
committed
feat(backend): add username-based public profile lookup endpoint
Closes #283
1 parent 9c0b1b7 commit 44bbb26

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

backend/src/users/users.controller.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,21 @@ export class UsersController {
9191
return this.userService.getMyStats(req.user.id as string);
9292
}
9393

94+
@Get('by-username/:username')
95+
async getPublicProfileByUsername(
96+
@Param('username') username: string,
97+
): Promise<{
98+
id: string;
99+
username: string | null;
100+
xp: number;
101+
badgesCount: number;
102+
coursesCompleted: number;
103+
avatarUrl: string | null;
104+
bio: string | null;
105+
}> {
106+
return this.userService.findByUsername(username);
107+
}
108+
94109
@Get(':id/public')
95110
async getPublicProfile(@Param('id') id: string): Promise<{
96111
id: string;

backend/src/users/users.service.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
BadRequestException,
77
} from '@nestjs/common';
88
import { InjectRepository } from '@nestjs/typeorm';
9-
import { Repository, MoreThan } from 'typeorm';
9+
import { ILike, Repository, MoreThan } from 'typeorm';
1010
import * as crypto from 'crypto';
1111
import * as bcrypt from 'bcrypt';
1212
import { RegisterDto } from 'src/auth/dto/register.dto';
@@ -302,4 +302,36 @@ export class UserService {
302302
bio: user.bio ?? null,
303303
};
304304
}
305+
306+
async findByUsername(username: string): Promise<{
307+
id: string;
308+
username: string | null;
309+
xp: number;
310+
badgesCount: number;
311+
coursesCompleted: number;
312+
avatarUrl: string | null;
313+
bio: string | null;
314+
}> {
315+
const user = await this.userRepository.findOne({
316+
where: { username: ILike(username) },
317+
});
318+
319+
if (!user) {
320+
throw new NotFoundException('User not found');
321+
}
322+
323+
const badgesCount = await this.userBadgeRepository.count({
324+
where: { userId: user.id },
325+
});
326+
327+
return {
328+
id: user.id,
329+
username: user.username ?? user.name ?? null,
330+
xp: this.resolveXp(user),
331+
badgesCount,
332+
coursesCompleted: user.coursesCompleted ?? 0,
333+
avatarUrl: user.avatarUrl ?? null,
334+
bio: user.bio ?? null,
335+
};
336+
}
305337
}

0 commit comments

Comments
 (0)