Skip to content

Commit 1276bbe

Browse files
committed
Merge remote-tracking branch 'origin/main' into chore/add-intercom
Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
2 parents b0e6cb1 + 44c6b90 commit 1276bbe

38 files changed

Lines changed: 3257 additions & 382 deletions

backend/src/api/public/v1/members/project-affiliations/patchProjectAffiliation.ts

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ const paramsSchema = z.object({
2626
projectId: z.uuid(),
2727
})
2828

29-
const bodySchema = z.object({
30-
affiliations: z
31-
.array(
29+
const bodySchema = z
30+
.object({
31+
affiliations: z.array(
3232
z
3333
.object({
3434
organizationId: z.uuid(),
@@ -38,10 +38,13 @@ const bodySchema = z.object({
3838
.refine((a) => a.dateEnd == null || a.dateEnd >= a.dateStart, {
3939
message: 'dateEnd must be greater than or equal to dateStart',
4040
}),
41-
)
42-
.min(1),
43-
verifiedBy: z.string().max(255),
44-
})
41+
),
42+
verifiedBy: z.string().max(255).optional(),
43+
})
44+
.refine((b) => b.affiliations.length === 0 || b.verifiedBy != null, {
45+
message: 'verifiedBy is required when affiliations is non-empty',
46+
path: ['verifiedBy'],
47+
})
4548

4649
export async function patchProjectAffiliation(req: Request, res: Response): Promise<void> {
4750
const { memberId, projectId } = validateOrThrow(paramsSchema, req.params)
@@ -75,17 +78,19 @@ export async function patchProjectAffiliation(req: Request, res: Response): Prom
7578
await qx.tx(async (tx) => {
7679
await deleteAllMemberSegmentAffiliationsForProject(tx, memberId, projectId)
7780

78-
await insertMemberSegmentAffiliations(
79-
tx,
80-
memberId,
81-
projectId,
82-
affiliations.map((a) => ({
83-
organizationId: a.organizationId,
84-
dateStart: a.dateStart.toISOString(),
85-
dateEnd: a.dateEnd?.toISOString() ?? null,
86-
verifiedBy,
87-
})),
88-
)
81+
if (affiliations.length > 0) {
82+
await insertMemberSegmentAffiliations(
83+
tx,
84+
memberId,
85+
projectId,
86+
affiliations.map((a) => ({
87+
organizationId: a.organizationId,
88+
dateStart: a.dateStart.toISOString(),
89+
dateEnd: a.dateEnd?.toISOString() ?? null,
90+
verifiedBy: verifiedBy!,
91+
})),
92+
)
93+
}
8994

9095
const oldOrgIds = existingAffiliations.map((a) => a.organizationId)
9196
const newOrgIds = affiliations.map((a) => a.organizationId)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DROP INDEX CONCURRENTLY IF EXISTS "idx_memberIdentities_verified_email_lower_value";
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
INSERT INTO "activityTypes" ("activityType", platform, "isCodeContribution", "isCollaboration", description, "label") VALUES
2+
('enrolled-certification', 'tnc', false, false, 'Successful payment purchase of certification enrollment', 'Enrolled in certification'),
3+
('enrolled-training', 'tnc', false, false, 'Successful payment purchase of training enrollment', 'Enrolled in training'),
4+
('issued-certification', 'tnc', false, false, 'User is granted a certification', 'Issued certification'),
5+
('attempted-course', 'tnc', false, false, 'Certification course is completed', 'Attempted course'),
6+
('attempted-exam', 'tnc', false, false, 'Certification exam is completed', 'Attempted exam');
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- The existing idx_memberIdentities_email_verified_trgm covers the right partial
2+
-- conditions (verified = true, type = 'email', deletedAt IS NULL) but is a GIN
3+
-- trigram index -- PostgreSQL will not use it for equality joins on
4+
-- lower(mi.value) against input emails, for example:
5+
--
6+
-- JOIN ON lower(mi.value) = input_email
7+
-- WHERE mi.verified = true AND mi.type = 'email' AND mi."deletedAt" IS NULL
8+
--
9+
-- The only usable B-tree index (idx_memberIdentities_lower_value) only carries
10+
-- the partial condition deletedAt IS NULL, so PG must heap-fetch every matched
11+
-- row to re-check verified and type, which degrades as the table grows.
12+
--
13+
-- This B-tree partial index lets the planner do a direct nested-loop index scan
14+
-- (one lookup per input email) with no extra heap fetches for verified/type.
15+
16+
CREATE INDEX CONCURRENTLY IF NOT EXISTS "idx_memberIdentities_verified_email_lower_value"
17+
ON "memberIdentities" (lower(value))
18+
WHERE verified = true
19+
AND type = 'email'
20+
AND "deletedAt" IS NULL;

frontend/package-lock.json

Lines changed: 23 additions & 177 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)