feat: add bio, return multiple results from search
This commit is contained in:
parent
0d46e6fee3
commit
595e23967a
@ -2,11 +2,11 @@ import { z } from "zod";
|
|||||||
import { Fastify } from "../types";
|
import { Fastify } from "../types";
|
||||||
import { db } from "@/storage/db";
|
import { db } from "@/storage/db";
|
||||||
import { RelationshipStatus } from "@prisma/client";
|
import { RelationshipStatus } from "@prisma/client";
|
||||||
import { getPublicUrl } from "@/storage/files";
|
|
||||||
import { friendAdd } from "@/app/social/friendAdd";
|
import { friendAdd } from "@/app/social/friendAdd";
|
||||||
import { Context } from "@/context";
|
import { Context } from "@/context";
|
||||||
import { friendRemove } from "@/app/social/friendRemove";
|
import { friendRemove } from "@/app/social/friendRemove";
|
||||||
import { friendList } from "@/app/social/friendList";
|
import { friendList } from "@/app/social/friendList";
|
||||||
|
import { buildUserProfile } from "@/app/social/type";
|
||||||
|
|
||||||
export async function userRoutes(app: Fastify) {
|
export async function userRoutes(app: Fastify) {
|
||||||
|
|
||||||
@ -54,24 +54,11 @@ export async function userRoutes(app: Fastify) {
|
|||||||
|
|
||||||
// Build user profile
|
// Build user profile
|
||||||
return reply.send({
|
return reply.send({
|
||||||
user: {
|
user: buildUserProfile(user, status)
|
||||||
id: user.id,
|
|
||||||
firstName: user.firstName || '',
|
|
||||||
lastName: user.lastName,
|
|
||||||
avatar: user.avatar ? {
|
|
||||||
path: user.avatar.path,
|
|
||||||
url: getPublicUrl(user.avatar.path),
|
|
||||||
width: user.avatar.width,
|
|
||||||
height: user.avatar.height,
|
|
||||||
thumbhash: user.avatar.thumbhash
|
|
||||||
} : null,
|
|
||||||
username: user.username || (user.githubUser?.profile?.login || ''),
|
|
||||||
status: status
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Search for user
|
// Search for users
|
||||||
app.get('/v1/user/search', {
|
app.get('/v1/user/search', {
|
||||||
schema: {
|
schema: {
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
@ -79,10 +66,7 @@ export async function userRoutes(app: Fastify) {
|
|||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
user: UserProfileSchema
|
users: z.array(UserProfileSchema)
|
||||||
}),
|
|
||||||
404: z.object({
|
|
||||||
error: z.literal('User not found')
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -90,8 +74,8 @@ export async function userRoutes(app: Fastify) {
|
|||||||
}, async (request, reply) => {
|
}, async (request, reply) => {
|
||||||
const { query } = request.query;
|
const { query } = request.query;
|
||||||
|
|
||||||
// Search for user by username or GitHub login
|
// Search for users by username, first 10 matches
|
||||||
const user = await db.account.findFirst({
|
const users = await db.account.findMany({
|
||||||
where: {
|
where: {
|
||||||
username: {
|
username: {
|
||||||
startsWith: query,
|
startsWith: query,
|
||||||
@ -100,37 +84,27 @@ export async function userRoutes(app: Fastify) {
|
|||||||
},
|
},
|
||||||
include: {
|
include: {
|
||||||
githubUser: true
|
githubUser: true
|
||||||
|
},
|
||||||
|
take: 10,
|
||||||
|
orderBy: {
|
||||||
|
username: 'asc'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!user) {
|
// Resolve relationship status for each user
|
||||||
return reply.code(404).send({ error: 'User not found' });
|
const userProfiles = await Promise.all(users.map(async (user) => {
|
||||||
}
|
const relationship = await db.userRelationship.findFirst({
|
||||||
|
where: {
|
||||||
// Resolve relationship status
|
fromUserId: request.userId,
|
||||||
const relationship = await db.userRelationship.findFirst({
|
toUserId: user.id
|
||||||
where: {
|
}
|
||||||
fromUserId: request.userId,
|
});
|
||||||
toUserId: user.id
|
const status: RelationshipStatus = relationship?.status || RelationshipStatus.none;
|
||||||
}
|
return buildUserProfile(user, status);
|
||||||
});
|
}));
|
||||||
const status: RelationshipStatus = relationship?.status || RelationshipStatus.none;
|
|
||||||
|
|
||||||
return reply.send({
|
return reply.send({
|
||||||
user: {
|
users: userProfiles
|
||||||
id: user.id,
|
|
||||||
firstName: user.firstName || '',
|
|
||||||
lastName: user.lastName,
|
|
||||||
avatar: user.avatar ? {
|
|
||||||
path: user.avatar.path,
|
|
||||||
url: getPublicUrl(user.avatar.path),
|
|
||||||
width: user.avatar.width,
|
|
||||||
height: user.avatar.height,
|
|
||||||
thumbhash: user.avatar.thumbhash
|
|
||||||
} : null,
|
|
||||||
username: user.username || (user.githubUser?.profile?.login || ''),
|
|
||||||
status: status
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -204,5 +178,6 @@ const UserProfileSchema = z.object({
|
|||||||
thumbhash: z.string().optional()
|
thumbhash: z.string().optional()
|
||||||
}).nullable(),
|
}).nullable(),
|
||||||
username: z.string(),
|
username: z.string(),
|
||||||
|
bio: z.string().nullable(),
|
||||||
status: RelationshipStatusSchema
|
status: RelationshipStatusSchema
|
||||||
});
|
});
|
@ -4,14 +4,13 @@ import { log } from "@/utils/log";
|
|||||||
import { allocateUserSeq } from "@/storage/seq";
|
import { allocateUserSeq } from "@/storage/seq";
|
||||||
import { buildUpdateAccountUpdate, eventRouter } from "@/app/events/eventRouter";
|
import { buildUpdateAccountUpdate, eventRouter } from "@/app/events/eventRouter";
|
||||||
import { randomKeyNaked } from "@/utils/randomKeyNaked";
|
import { randomKeyNaked } from "@/utils/randomKeyNaked";
|
||||||
import { Prisma } from "@prisma/client";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disconnects a GitHub account from a user profile.
|
* Disconnects a GitHub account from a user profile.
|
||||||
*
|
*
|
||||||
* Flow:
|
* Flow:
|
||||||
* 1. Check if user has GitHub connected - early exit if not
|
* 1. Check if user has GitHub connected - early exit if not
|
||||||
* 2. In transaction: clear GitHub link, username, avatar from account and delete GitHub user record
|
* 2. In transaction: clear GitHub link and username from account (keeps avatar) and delete GitHub user record
|
||||||
* 3. Send socket update after transaction completes
|
* 3. Send socket update after transaction completes
|
||||||
*
|
*
|
||||||
* @param ctx - Request context containing user ID
|
* @param ctx - Request context containing user ID
|
||||||
@ -36,13 +35,12 @@ export async function githubDisconnect(ctx: Context): Promise<void> {
|
|||||||
|
|
||||||
// Step 2: Transaction for atomic database operations
|
// Step 2: Transaction for atomic database operations
|
||||||
await db.$transaction(async (tx) => {
|
await db.$transaction(async (tx) => {
|
||||||
// Clear GitHub connection, username, and avatar from account
|
// Clear GitHub connection and username from account (keep avatar)
|
||||||
await tx.account.update({
|
await tx.account.update({
|
||||||
where: { id: userId },
|
where: { id: userId },
|
||||||
data: {
|
data: {
|
||||||
githubUserId: null,
|
githubUserId: null,
|
||||||
username: null,
|
username: null
|
||||||
avatar: Prisma.JsonNull
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -56,8 +54,7 @@ export async function githubDisconnect(ctx: Context): Promise<void> {
|
|||||||
const updSeq = await allocateUserSeq(userId);
|
const updSeq = await allocateUserSeq(userId);
|
||||||
const updatePayload = buildUpdateAccountUpdate(userId, {
|
const updatePayload = buildUpdateAccountUpdate(userId, {
|
||||||
github: null,
|
github: null,
|
||||||
username: null,
|
username: null
|
||||||
avatar: null
|
|
||||||
}, updSeq, randomKeyNaked(12));
|
}, updSeq, randomKeyNaked(12));
|
||||||
|
|
||||||
eventRouter.emitUpdate({
|
eventRouter.emitUpdate({
|
||||||
|
@ -14,6 +14,7 @@ export type UserProfile = {
|
|||||||
thumbhash?: string;
|
thumbhash?: string;
|
||||||
} | null;
|
} | null;
|
||||||
username: string;
|
username: string;
|
||||||
|
bio: string | null;
|
||||||
status: RelationshipStatus;
|
status: RelationshipStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +50,7 @@ export function buildUserProfile(
|
|||||||
lastName: account.lastName,
|
lastName: account.lastName,
|
||||||
avatar,
|
avatar,
|
||||||
username: account.username || githubProfile?.login || '',
|
username: account.username || githubProfile?.login || '',
|
||||||
|
bio: githubProfile?.bio || null,
|
||||||
status
|
status
|
||||||
};
|
};
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user