Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
69 changes: 69 additions & 0 deletions __tests__/schema/opportunity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,75 @@ describe('query opportunityMatches', () => {
});
});

it('should include previewUser with additional information', async () => {
loggedUser = '1';

const GET_OPPORTUNITY_MATCHES_WITH_PREVIEW_USER_QUERY = /* GraphQL */ `
query GetOpportunityMatchesWithPreviewUser(
$opportunityId: ID!
$first: Int
) {
opportunityMatches(opportunityId: $opportunityId, first: $first) {
edges {
node {
userId
status
previewUser {
id
profileImage
anonId
description
openToWork
seniority
location
topTags
activeSquads {
id
name
handle
}
}
}
}
}
}
`;

const res = await client.query(
GET_OPPORTUNITY_MATCHES_WITH_PREVIEW_USER_QUERY,
{
variables: {
opportunityId: '550e8400-e29b-41d4-a716-446655440001',
first: 10,
},
},
);

expect(res.errors).toBeFalsy();

const acceptedMatch = res.data.opportunityMatches.edges.find(
(e: { node: { status: string } }) =>
e.node.status === 'candidate_accepted',
);

expect(acceptedMatch.node.previewUser).toBeDefined();
expect(acceptedMatch.node.previewUser.id).toBe('2');
expect(acceptedMatch.node.previewUser.anonId).toBeTruthy();
expect(Array.isArray(acceptedMatch.node.previewUser.topTags)).toBe(true);
expect(Array.isArray(acceptedMatch.node.previewUser.activeSquads)).toBe(
true,
);
// Verify activeSquads contains Source objects with expected fields
if (acceptedMatch.node.previewUser.activeSquads.length > 0) {
expect(acceptedMatch.node.previewUser.activeSquads[0]).toHaveProperty(
'id',
);
expect(acceptedMatch.node.previewUser.activeSquads[0]).toHaveProperty(
'name',
);
}
});

it('should include screening, feedback, and application rank', async () => {
loggedUser = '1';

Expand Down
36 changes: 24 additions & 12 deletions src/graphorm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1643,6 +1643,13 @@ const obj = new GraphORM({
parentColumn: 'userId',
},
},
previewUser: {
relation: {
isMany: false,
childColumn: 'id',
parentColumn: 'userId',
},
},
},
},
UserCandidatePreference: {
Expand Down Expand Up @@ -1891,18 +1898,23 @@ const obj = new GraphORM({
},
},
activeSquads: {
select: (_, alias) => `
ARRAY(
SELECT sm."sourceId"
FROM source_member sm
INNER JOIN source s ON s.id = sm."sourceId"
WHERE sm."userId" = ${alias}.id
AND s.type = '${SourceType.Squad}'
AND s.active = true
ORDER BY sm."createdAt" DESC
LIMIT 5
)
`,
relation: {
isMany: true,
customRelation: (_, parentAlias, childAlias, qb): QueryBuilder =>
qb
.innerJoin(
SourceMember,
'sm',
`sm."sourceId" = "${childAlias}".id`,
)
.where(`sm."userId" = ${parentAlias}.id`)
.andWhere(`"${childAlias}".type = :squadType`, {
squadType: SourceType.Squad,
})
.andWhere(`"${childAlias}".active = true`)
.orderBy('sm."createdAt"', 'DESC')
.limit(5),
},
},
},
},
Expand Down
12 changes: 8 additions & 4 deletions src/schema/opportunity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ import { addOpportunityDefaultQuestionFeedback } from '../common/opportunity/que
import { cursorToOffset, offsetToCursor } from 'graphql-relay/index';
import { getShowcaseCompanies } from '../common/opportunity/companies';
import { Opportunity } from '../entity/opportunities/Opportunity';
import type { GQLSource } from './sources';

export interface GQLOpportunity
extends Pick<
Expand Down Expand Up @@ -153,7 +154,7 @@ export interface GQLOpportunityPreviewUser extends Pick<User, 'id'> {
lastActivity: Date | null;
topTags: string[] | null;
recentlyRead: GQLTopReaderBadge[] | null;
activeSquads: string[] | null;
activeSquads: GQLSource[] | null;
}

export interface GQLOpportunityPreviewEdge {
Expand Down Expand Up @@ -309,6 +310,7 @@ export const typeDefs = /* GraphQL */ `
feedback: [ScreeningAnswer!]!
applicationRank: ApplicationRank!
engagementProfile: EngagementProfile
previewUser: OpportunityPreviewUser
}

type OpportunityMatchEdge {
Expand Down Expand Up @@ -441,9 +443,9 @@ export const typeDefs = /* GraphQL */ `
recentlyRead: [UserTopReader!]

"""
Active squad IDs
Active squads
"""
activeSquads: [String!]!
activeSquads: [Source!]!
}

type OpportunityPreviewEdge {
Expand Down Expand Up @@ -1281,7 +1283,9 @@ export const resolvers: IResolvers<unknown, BaseContext> = traceResolvers<
const companies = getShowcaseCompanies();

const squads = uniqueifyArray(
connection.edges.flatMap(({ node }) => node.activeSquads || []),
connection.edges.flatMap(({ node }) =>
(node.activeSquads || []).map((squad) => squad.id),
),
);

return {
Expand Down
Loading