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 { db } from "@/storage/db";
|
||||
import { RelationshipStatus } from "@prisma/client";
|
||||
import { getPublicUrl } from "@/storage/files";
|
||||
import { friendAdd } from "@/app/social/friendAdd";
|
||||
import { Context } from "@/context";
|
||||
import { friendRemove } from "@/app/social/friendRemove";
|
||||
import { friendList } from "@/app/social/friendList";
|
||||
import { buildUserProfile } from "@/app/social/type";
|
||||
|
||||
export async function userRoutes(app: Fastify) {
|
||||
|
||||
@ -54,24 +54,11 @@ export async function userRoutes(app: Fastify) {
|
||||
|
||||
// Build user profile
|
||||
return reply.send({
|
||||
user: {
|
||||
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
|
||||
}
|
||||
user: buildUserProfile(user, status)
|
||||
});
|
||||
});
|
||||
|
||||
// Search for user
|
||||
// Search for users
|
||||
app.get('/v1/user/search', {
|
||||
schema: {
|
||||
querystring: z.object({
|
||||
@ -79,10 +66,7 @@ export async function userRoutes(app: Fastify) {
|
||||
}),
|
||||
response: {
|
||||
200: z.object({
|
||||
user: UserProfileSchema
|
||||
}),
|
||||
404: z.object({
|
||||
error: z.literal('User not found')
|
||||
users: z.array(UserProfileSchema)
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -90,8 +74,8 @@ export async function userRoutes(app: Fastify) {
|
||||
}, async (request, reply) => {
|
||||
const { query } = request.query;
|
||||
|
||||
// Search for user by username or GitHub login
|
||||
const user = await db.account.findFirst({
|
||||
// Search for users by username, first 10 matches
|
||||
const users = await db.account.findMany({
|
||||
where: {
|
||||
username: {
|
||||
startsWith: query,
|
||||
@ -100,14 +84,15 @@ export async function userRoutes(app: Fastify) {
|
||||
},
|
||||
include: {
|
||||
githubUser: true
|
||||
},
|
||||
take: 10,
|
||||
orderBy: {
|
||||
username: 'asc'
|
||||
}
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return reply.code(404).send({ error: 'User not found' });
|
||||
}
|
||||
|
||||
// Resolve relationship status
|
||||
// Resolve relationship status for each user
|
||||
const userProfiles = await Promise.all(users.map(async (user) => {
|
||||
const relationship = await db.userRelationship.findFirst({
|
||||
where: {
|
||||
fromUserId: request.userId,
|
||||
@ -115,22 +100,11 @@ export async function userRoutes(app: Fastify) {
|
||||
}
|
||||
});
|
||||
const status: RelationshipStatus = relationship?.status || RelationshipStatus.none;
|
||||
return buildUserProfile(user, status);
|
||||
}));
|
||||
|
||||
return reply.send({
|
||||
user: {
|
||||
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
|
||||
}
|
||||
users: userProfiles
|
||||
});
|
||||
});
|
||||
|
||||
@ -204,5 +178,6 @@ const UserProfileSchema = z.object({
|
||||
thumbhash: z.string().optional()
|
||||
}).nullable(),
|
||||
username: z.string(),
|
||||
bio: z.string().nullable(),
|
||||
status: RelationshipStatusSchema
|
||||
});
|
@ -4,14 +4,13 @@ import { log } from "@/utils/log";
|
||||
import { allocateUserSeq } from "@/storage/seq";
|
||||
import { buildUpdateAccountUpdate, eventRouter } from "@/app/events/eventRouter";
|
||||
import { randomKeyNaked } from "@/utils/randomKeyNaked";
|
||||
import { Prisma } from "@prisma/client";
|
||||
|
||||
/**
|
||||
* Disconnects a GitHub account from a user profile.
|
||||
*
|
||||
* Flow:
|
||||
* 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
|
||||
*
|
||||
* @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
|
||||
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({
|
||||
where: { id: userId },
|
||||
data: {
|
||||
githubUserId: null,
|
||||
username: null,
|
||||
avatar: Prisma.JsonNull
|
||||
username: null
|
||||
}
|
||||
});
|
||||
|
||||
@ -56,8 +54,7 @@ export async function githubDisconnect(ctx: Context): Promise<void> {
|
||||
const updSeq = await allocateUserSeq(userId);
|
||||
const updatePayload = buildUpdateAccountUpdate(userId, {
|
||||
github: null,
|
||||
username: null,
|
||||
avatar: null
|
||||
username: null
|
||||
}, updSeq, randomKeyNaked(12));
|
||||
|
||||
eventRouter.emitUpdate({
|
||||
|
@ -14,6 +14,7 @@ export type UserProfile = {
|
||||
thumbhash?: string;
|
||||
} | null;
|
||||
username: string;
|
||||
bio: string | null;
|
||||
status: RelationshipStatus;
|
||||
}
|
||||
|
||||
@ -49,6 +50,7 @@ export function buildUserProfile(
|
||||
lastName: account.lastName,
|
||||
avatar,
|
||||
username: account.username || githubProfile?.login || '',
|
||||
bio: githubProfile?.bio || null,
|
||||
status
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user