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
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ workflows:
branches:
only:
- develop
- PM-4961
- PM-4931

# Production builds are exectuted only on tagged commits to the
# master branch.
Expand Down
2 changes: 1 addition & 1 deletion src/reports/member/dto/member-search-response.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class MatchedSkillDto {

@ApiProperty({
description:
"True when the member has at least one challenge-win event for this skill.",
"True for platform-backed skill activity (wins and/or skill events). Matched skills only include these, not self-attested-only skills.",
})
isVerified!: boolean;

Expand Down
5 changes: 4 additions & 1 deletion src/reports/member/member-search.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ describe("MemberSearchService", () => {
expect(dataSql).not.toContain(
'EXISTS (SELECT 1 FROM recently_active ra WHERE ra.user_id = m."userId")',
);
expect(dataSql).not.toContain("COALESCE(m.verified, false) = true");
});

it("adds profileComplete CTE/join only when enabled and keeps count params free of pagination", async () => {
Expand Down Expand Up @@ -226,7 +225,11 @@ describe("MemberSearchService", () => {
expect(validationParams).toEqual([[skillA, skillB]]);

expect(dataSql).toContain("requested_skills AS");
expect(dataSql).toContain("FILTER (WHERE usd.wins > 0 OR usd.submitted > 0)");
expect(dataSql).toContain("INNER JOIN user_match_data umd");
expect(dataSql).toContain("THEN COUNT(DISTINCT CASE");
expect(dataSql).toContain("ELSE COUNT(DISTINCT CASE");
expect(dataSql).toContain("(usd.wins >= rs.min_wins OR usd.submitted > 0)");
expect(dataParams).toContainEqual([skillA, skillB]);
expect(dataParams).toContainEqual([5, 0]);
expect(dataParams).toContain("AND");
Expand Down
46 changes: 28 additions & 18 deletions src/reports/member/member-search.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,31 +141,41 @@ qualifying_users AS (
GROUP BY usd.user_id
HAVING
CASE WHEN ${pSearchType} = 'AND'
THEN COUNT(DISTINCT CASE WHEN usd.wins >= rs.min_wins THEN usd.skill_id END)
THEN COUNT(DISTINCT CASE
WHEN (usd.wins >= rs.min_wins OR usd.submitted > 0)
THEN usd.skill_id END)
= ${pNumSkills}::integer
ELSE COUNT(DISTINCT CASE WHEN usd.wins >= rs.min_wins THEN usd.skill_id END) >= 1
ELSE COUNT(DISTINCT CASE
WHEN (usd.wins >= rs.min_wins OR usd.submitted > 0)
THEN usd.skill_id END) >= 1
END
),
user_match_data AS (
SELECT
usd.user_id,
SUM(
1.0
+ LEAST(usd.wins::float / 100.0, 0.5)
+ CASE WHEN usd.submitted > 0
THEN (usd.wins::float / usd.submitted::float) * 0.5
ELSE 0.0
END
COALESCE(
SUM(
1.0
+ LEAST(usd.wins::float / 100.0, 0.5)
+ CASE WHEN usd.submitted > 0
THEN (usd.wins::float / usd.submitted::float) * 0.5
ELSE 0.0
END
) FILTER (WHERE usd.wins > 0 OR usd.submitted > 0),
0.0
) AS total_skill_points,
jsonb_agg(
jsonb_build_object(
'id', usd.skill_id::text,
'name', usd.skill_name,
'isVerified', usd.wins > 0,
'wins', usd.wins,
'submitted', usd.submitted
)
ORDER BY usd.skill_name
COALESCE(
jsonb_agg(
jsonb_build_object(
'id', usd.skill_id::text,
'name', usd.skill_name,
'isVerified', (usd.wins > 0 OR usd.submitted > 0),
'wins', usd.wins,
'submitted', usd.submitted
)
ORDER BY usd.skill_name
) FILTER (WHERE usd.wins > 0 OR usd.submitted > 0),
'[]'::jsonb
) AS matched_skills
FROM user_skill_data usd
WHERE usd.user_id IN (SELECT user_id FROM qualifying_users)
Expand Down
Loading