Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix/missing user #4472

Merged
merged 4 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 11 additions & 126 deletions @connect-shared/lib/projects/createProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { OptionalPrismaTransaction, Prisma, Project, ProjectSource } from '
import { prisma } from '@charmverse/core/prisma-client';
import type { StatusAPIResponse } from '@farcaster/auth-client';
import { resolveENSName } from '@root/lib/blockchain';
import { ensureFarcasterUserExists } from '@root/lib/farcaster/ensureFarcasterUserExists';
import { getFarcasterUsers } from '@root/lib/farcaster/getFarcasterUsers';
import { generatePagePathFromPathAndTitle } from '@root/lib/pages/utils';
import { stringToValidPath, uid } from '@root/lib/utils/strings';
Expand Down Expand Up @@ -43,131 +44,15 @@ export async function createProject({
}
}

const farcasterAccounts = await tx.farcasterUser.findMany({
where: {
fid: {
in: input.projectMembers.map(({ farcasterId }) => farcasterId)
}
},
select: {
userId: true,
fid: true,
account: true
}
});

const teamLeadFarcasterAccount = farcasterAccounts.find(
(account) => account.userId === userId
) as (typeof farcasterAccounts)[0];

const farcasterAccountsRecord: Record<
number,
{
userId: string;
account: StatusAPIResponse;
}
> = farcasterAccounts.reduce<
Record<
number,
{
userId: string;
account: StatusAPIResponse;
}
>
>((acc, { fid, userId: _userId, account }) => {
acc[fid] = {
userId: _userId,
account: account as unknown as StatusAPIResponse
};
return acc;
}, {});

const projectMembers = (
await Promise.all(
input.projectMembers.map(async (member) => {
if (farcasterAccountsRecord[member.farcasterId]) {
return {
userId: farcasterAccountsRecord[member.farcasterId].userId,
name: farcasterAccountsRecord[member.farcasterId].account.displayName as string,
farcasterId: member.farcasterId
};
}
try {
const [farcasterProfile] = await getFarcasterUsers({
fids: [member.farcasterId]
});
if (!farcasterProfile) {
return null;
}

const farcasterWalletUser = await tx.user.findFirst({
where: {
wallets: {
some: {
address: {
in: [
farcasterProfile.custody_address,
...(farcasterProfile.verified_addresses ? farcasterProfile.verified_addresses.eth_addresses : [])
].map((address) => address.toLowerCase())
}
}
}
},
select: {
id: true
}
});

if (farcasterWalletUser) {
return {
userId: farcasterWalletUser.id,
name: farcasterProfile.display_name,
farcasterId: member.farcasterId
};
}
const username = farcasterProfile.username;
const displayName = farcasterProfile.display_name;
const bio = farcasterProfile.profile.bio.text;
const pfpUrl = farcasterProfile.pfp_url;
const fid = member.farcasterId;

const newUser = await tx.user.create({
data: {
id: v4(),
username,
identityType: 'Farcaster',
claimed: false,
avatar: farcasterProfile.pfp_url,
farcasterUser: {
create: {
account: { username, displayName, bio, pfpUrl },
fid
}
},
path: uid(),
profile: {
create: {
...(bio && { description: bio || '' })
}
}
}
});

return {
userId: newUser.id,
name: displayName,
farcasterId: member.farcasterId
};
} catch (err) {
log.error('Error creating user', {
fid: member.farcasterId,
err
});
return null;
}
const projectMembers = await Promise.all(
input.projectMembers.map((member) =>
ensureFarcasterUserExists({
fid: member.farcasterId
})
)
).filter(isTruthy);
);

const teamLeadFarcasterAccount = projectMembers.find((member) => member.userId === userId);

let path = stringToValidPath({ input: input.name ?? '', wordSeparator: '-', autoReplaceEmpty: false });

Expand All @@ -189,12 +74,12 @@ export async function createProject({

const projectMembersToCreate: Omit<Prisma.ProjectMemberCreateManyInput, 'projectId'>[] = [
...projectMembers.map((member) => ({
teamLead: member.farcasterId === teamLeadFarcasterAccount.fid,
teamLead: member.fid === teamLeadFarcasterAccount?.fid,
updatedBy: userId,
userId: member.userId,
// This is necessary because some test data fids do not have a corresponding farcaster profile
name: member.name || '',
farcasterId: member.farcasterId
name: member.account.displayName || member.account.username,
Copy link
Member

@mattcasey mattcasey Aug 21, 2024

Choose a reason for hiding this comment

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

@motechFR please trim these values, this wouldn't fix the name which we got, which was was " "

farcasterId: member.fid
}))
];

Expand Down
113 changes: 6 additions & 107 deletions @connect-shared/lib/projects/editProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import type { Project } from '@charmverse/core/prisma-client';
import { prisma } from '@charmverse/core/prisma-client';
import type { StatusAPIResponse } from '@farcaster/auth-kit';
import { resolveENSName } from '@root/lib/blockchain';
import { ensureFarcasterUserExists } from '@root/lib/farcaster/ensureFarcasterUserExists';
import { getFarcasterUsers } from '@root/lib/farcaster/getFarcasterUsers';
import { uid } from '@root/lib/utils/strings';
import { isTruthy } from '@root/lib/utils/types';
import { meanBy } from 'lodash';
Copy link
Member

Choose a reason for hiding this comment

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

accidental import?

import { v4 } from 'uuid';

import type { FormValues } from './projectSchema';
Expand Down Expand Up @@ -70,112 +72,9 @@ export async function editProject({ userId, input }: { input: EditProjectValues;
!currentProjectMembers.some((projectMember) => member.farcasterId === projectMember.user?.farcasterUser?.fid)
);

const farcasterAccountsRecord: Record<
number,
{
userId: string;
account: StatusAPIResponse;
}
> = inputProjectMembers.reduce<
Record<
number,
{
userId: string;
account: StatusAPIResponse;
}
>
>((acc, { fid, userId: _userId, account }) => {
acc[fid] = {
userId: _userId,
account: account as unknown as StatusAPIResponse
};
return acc;
}, {});

const projectMembers = (
await Promise.all(
newProjectMembers.map(async (member) => {
if (farcasterAccountsRecord[member.farcasterId]) {
return {
userId: farcasterAccountsRecord[member.farcasterId].userId,
name: farcasterAccountsRecord[member.farcasterId].account.displayName as string,
farcasterId: member.farcasterId
};
}
try {
const [farcasterProfile] = await getFarcasterUsers({
fids: [member.farcasterId]
});

if (!farcasterProfile) {
return null;
}

const farcasterWalletUser = await prisma.user.findFirst({
where: {
wallets: {
some: {
address: {
in: [
farcasterProfile.custody_address,
...(farcasterProfile.verified_addresses ? farcasterProfile.verified_addresses.eth_addresses : [])
].map((address) => address.toLowerCase())
}
}
}
}
});

if (farcasterWalletUser) {
return {
userId: farcasterWalletUser.id,
name: farcasterProfile.display_name,
farcasterId: member.farcasterId
};
}
const username = farcasterProfile.username;
const displayName = farcasterProfile.display_name;
const bio = farcasterProfile.profile.bio.text;
const pfpUrl = farcasterProfile.pfp_url;
const fid = member.farcasterId;

const newUser = await prisma.user.create({
data: {
id: v4(),
username,
identityType: 'Farcaster',
claimed: false,
avatar: farcasterProfile.pfp_url,
farcasterUser: {
create: {
account: { username, displayName, bio, pfpUrl },
fid
}
},
path: uid(),
profile: {
create: {
...(bio && { description: bio || '' })
}
}
}
});

return {
userId: newUser.id,
name: displayName,
farcasterId: member.farcasterId
};
} catch (err) {
log.error('Error creating user', {
fid: member.farcasterId,
err
});
return null;
}
})
)
).filter(isTruthy);
const projectMembers = await Promise.all(
newProjectMembers.map(async (member) => ensureFarcasterUserExists({ fid: member.farcasterId }))
Copy link
Member

@mattcasey mattcasey Aug 21, 2024

Choose a reason for hiding this comment

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

async is uneccessary

);

const [editedProject] = await prisma.$transaction([
prisma.project.update({
Expand Down Expand Up @@ -206,7 +105,7 @@ export async function editProject({ userId, input }: { input: EditProjectValues;
data: projectMembers.map((member) => ({
teamLead: false,
updatedBy: userId,
name: member.name,
name: member.account.displayName || member.account.username,
userId: member.userId,
projectId: input.projectId
}))
Expand Down
2 changes: 1 addition & 1 deletion @connect-shared/lib/projects/findProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export async function findProject({ id, path }: { id?: string; path?: string }):
...member.user,
userId: member.userId,
teamLead: member.teamLead,
name: farcasterUser?.displayName || '',
name: farcasterUser?.displayName || farcasterUser?.username || '',
farcasterId: member.user?.farcasterUser?.fid as number,
farcasterUser: {
fid: member.user?.farcasterUser?.fid,
Expand Down
2 changes: 1 addition & 1 deletion apps/connect/components/profile/ProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export async function ProfilePage({ user }: { user: LoggedInUser }) {
<Box gap={3} display='flex' flexDirection='column' mt={{ md: 2 }}>
<FarcasterCard
fid={user.farcasterUser?.fid}
name={farcasterDetails?.displayName}
name={farcasterDetails?.displayName || farcasterDetails?.username}
username={farcasterDetails?.username}
avatar={farcasterDetails?.pfpUrl}
bio={farcasterDetails?.bio}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export async function ProfileDetailsPage({ user }: { user: Pick<LoggedInUser, 'f
<Box gap={2} display='flex' flexDirection='column'>
<FarcasterCard
fid={user.farcasterUser?.fid}
name={farcasterDetails?.displayName}
name={farcasterDetails?.displayName || farcasterDetails?.username}
username={farcasterDetails?.username}
avatar={farcasterDetails?.pfpUrl}
bio={farcasterDetails?.bio}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export function AddProjectMembersForm({
<Typography variant='h6'>Team</Typography>
<FarcasterCard
fid={user.farcasterUser?.fid}
name={farcasterDetails?.displayName}
name={farcasterDetails?.displayName || farcasterDetails?.username}
username={farcasterDetails?.username}
avatar={farcasterDetails?.pfpUrl}
avatarSize='large'
Expand Down
2 changes: 1 addition & 1 deletion apps/sunnyawards/components/profile/ProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export async function ProfilePage({ user }: { user: LoggedInUser }) {
<Box gap={3} display='flex' flexDirection='column' mt={{ md: 2 }}>
<FarcasterCard
fid={user.farcasterUser?.fid}
name={farcasterDetails?.displayName}
name={farcasterDetails?.displayName || farcasterDetails?.username}
username={farcasterDetails?.username}
avatar={farcasterDetails?.pfpUrl}
bio={farcasterDetails?.bio}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export async function ProfileDetailsPage({ user }: { user: Pick<LoggedInUser, 'f
<Box gap={2} display='flex' flexDirection='column'>
<FarcasterCard
fid={user.farcasterUser?.fid}
name={farcasterDetails?.displayName}
name={farcasterDetails?.displayName || farcasterDetails?.username}
username={farcasterDetails?.username}
avatar={farcasterDetails?.pfpUrl}
bio={farcasterDetails?.bio}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function AddProjectMembersForm({
<FormLabel id='search-farcaster-user'>Team</FormLabel>
<FarcasterCard
fid={user.farcasterUser?.fid}
name={farcasterDetails?.displayName}
name={farcasterDetails?.displayName || farcasterDetails?.username}
username={farcasterDetails?.username}
avatar={farcasterDetails?.pfpUrl}
avatarSize='large'
Expand Down
Loading
Loading