Skip to content

feat(backend): add username-based public profile lookup endpoint#342

Open
Spagero763 wants to merge 2 commits into
WeAcademy:mainfrom
Spagero763:feat/username-profile-lookup
Open

feat(backend): add username-based public profile lookup endpoint#342
Spagero763 wants to merge 2 commits into
WeAcademy:mainfrom
Spagero763:feat/username-profile-lookup

Conversation

@Spagero763
Copy link
Copy Markdown
Contributor

Closes #283

Changes

  • Added findByUsername(username: string) to UsersService — case-insensitive lookup via TypeORM ILike, throws NotFoundException if not found
  • Added GET /users/by-username/:username public endpoint to UsersController — placed before GET /users/:id to avoid route collision
  • Returns same public profile shape as existing UUID-based endpoint

Backend only. Frontend public profile page is a follow-up.

— EduAgent (Lunar Wasp) via AIBTC autonomous loop

Copilot AI review requested due to automatic review settings May 5, 2026 13:12
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a backend endpoint for looking up a user's public profile by username so the frontend can resolve learner profile pages without requiring a UUID. The PR extends the users module with a username-based lookup and returns the same public-profile fields as the existing UUID-based flow.

Changes:

  • Added UserService.findByUsername() with case-insensitive username lookup.
  • Added GET /users/by-username/:username in UsersController.
  • Reused the existing public profile payload shape for the new route.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
backend/src/users/users.service.ts Adds the username lookup logic and maps the matched user into a public profile response.
backend/src/users/users.controller.ts Exposes the new username-based public profile endpoint.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +94 to +96
@Get('by-username/:username')
async getPublicProfileByUsername(
@Param('username') username: string,
Comment on lines +315 to +317
const user = await this.userRepository.findOne({
where: { username: ILike(username) },
});
Comment on lines +315 to +322
const user = await this.userRepository.findOne({
where: { username: ILike(username) },
});

if (!user) {
throw new NotFoundException('User not found');
}

Comment thread backend/src/users/users.service.ts Outdated
Comment on lines +306 to +317
async findByUsername(username: string): Promise<{
id: string;
username: string | null;
xp: number;
badgesCount: number;
coursesCompleted: number;
avatarUrl: string | null;
bio: string | null;
}> {
const user = await this.userRepository.findOne({
where: { username: ILike(username) },
});
Comment on lines +94 to +95
@Get('by-username/:username')
async getPublicProfileByUsername(
Comment on lines +323 to +327
const badgesCount = await this.userBadgeRepository.count({
where: { userId: user.id },
});

return {
Resolves merge conflict in users.service.ts.
Moves JwtAuthGuard off controller level — public endpoints
(by-username/:username and :id/public) are now unauthenticated
as the issue requires. Protected routes retain per-route guards.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Spagero763
Copy link
Copy Markdown
Contributor Author

Addressed Copilot review feedback:

  • Removed controller-level @UseGuards(JwtAuthGuard) and @ApiBearerAuth — public endpoints (GET /users/by-username/:username and GET /users/:id/public) are now fully unauthenticated as required by issue feat(backend+frontend): add username-based public profile lookup endpoint and public learner profile page #283.
  • All other routes (/me, /me/avatar, /me/wallet, etc.) retain per-route @UseGuards(JwtAuthGuard) and @ApiBearerAuth decorators.
  • Resolved merge conflict with upstream/main.
  • Centralised public profile mapping via toPublicProfile() helper to keep getPublicProfile() and findByUsername() in sync.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(backend+frontend): add username-based public profile lookup endpoint and public learner profile page

2 participants