Skip to content

Commit 43395bb

Browse files
authored
fix: adding steward details (#4254)
Signed-off-by: Umberto Sgueglia <usgueglia@contractor.linuxfoundation.org>
1 parent 14c7dc4 commit 43395bb

6 files changed

Lines changed: 91 additions & 35 deletions

File tree

backend/src/api/public/v1/packages/listPackages.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,15 @@ export async function listPackages(req: Request, res: Response): Promise<void> {
6868

6969
const qx = await getPackagesQx()
7070
const [{ rows, total }, statusCounts] = await Promise.all([
71-
listPackagesForApi(qx, { page, pageSize, status, sortBy, sortDir, ...filterOpts }),
71+
listPackagesForApi(qx, {
72+
page,
73+
pageSize,
74+
status,
75+
sortBy,
76+
sortDir,
77+
...filterOpts,
78+
includeStewards: true,
79+
}),
7280
getPackageStatusCounts(qx, filterOpts),
7381
])
7482

@@ -83,7 +91,7 @@ export async function listPackages(req: Request, res: Response): Promise<void> {
8391
openVulns: r.openVulns,
8492
stewardshipId: r.stewardshipId ?? null,
8593
stewardship: (r.stewardshipStatus ?? 'unassigned') as StewardshipStatus,
86-
stewards: null,
94+
stewards: r.stewards ?? [],
8795
}))
8896

8997
ok(res, {

backend/src/api/public/v1/packages/openapi.yaml

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,13 @@ components:
9191
type: string
9292
description: Auth0 sub of the assigned steward.
9393
example: abc123
94-
name:
94+
username:
95+
type:
96+
- string
97+
- 'null'
98+
description: Username of the steward. Null if not available.
99+
example: jrodriguez
100+
displayName:
95101
type:
96102
- string
97103
- 'null'
@@ -206,12 +212,10 @@ components:
206212
stewardship:
207213
$ref: '#/components/schemas/StewardshipStatus'
208214
stewards:
209-
description: Assigned stewards or null.
210-
oneOf:
211-
- type: array
212-
items:
213-
$ref: '#/components/schemas/Steward'
214-
- type: 'null'
215+
description: Assigned stewards. Empty array if none.
216+
type: array
217+
items:
218+
$ref: '#/components/schemas/Steward'
215219

216220
# ── Package detail ───────────────────────────────────────────────────────────
217221

services/libs/data-access-layer/src/osspckgs/api.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
import { QueryExecutor } from '../queryExecutor'
22

3+
import {
4+
SEVERITY_RANK_EXPR,
5+
STEWARD_DISPLAY_NAME_METADATA,
6+
STEWARD_MENTIONED_JOIN,
7+
} from './sqlFragments'
8+
39
export interface PackageMetrics {
410
totalPackages: number
511
criticalPackages: number
@@ -167,16 +173,9 @@ export interface ListPackagesOptions {
167173
sortDir: 'asc' | 'desc'
168174
}
169175

170-
const STALE_MONTHS = 18
176+
export { SEVERITY_RANK_EXPR } from './sqlFragments'
171177

172-
// Severity stored as uppercase in advisories table.
173-
// Ranks: CRITICAL=4, HIGH=3, MEDIUM=2, LOW=1
174-
export const SEVERITY_RANK_EXPR = `MAX(CASE a.severity
175-
WHEN 'CRITICAL' THEN 4
176-
WHEN 'HIGH' THEN 3
177-
WHEN 'MEDIUM' THEN 2
178-
WHEN 'LOW' THEN 1
179-
ELSE 0 END)::int`
178+
const STALE_MONTHS = 18
180179

181180
export interface PackageStatusCounts {
182181
all: number
@@ -512,8 +511,10 @@ export async function listPackagesForApi(
512511
opts.includeLastActivity === true
513512
? `
514513
LEFT JOIN LATERAL (
515-
SELECT sa.activity_type, sa.content, sa.metadata, sa.created_at
514+
SELECT sa.activity_type, sa.content, sa.created_at,
515+
${STEWARD_DISPLAY_NAME_METADATA} AS metadata
516516
FROM stewardship_activity sa
517+
${STEWARD_MENTIONED_JOIN}
517518
WHERE sa.stewardship_id = s.id
518519
ORDER BY sa.created_at DESC
519520
LIMIT 1
@@ -545,7 +546,7 @@ export async function listPackagesForApi(
545546
r_sc.scorecard_score AS "scorecardScore",
546547
p.latest_release_at AS "latestReleaseAt",
547548
${opts.includeLastActivity === true ? `last_act.activity_type AS "lastActivityType", last_act.content AS "lastActivityContent", last_act.metadata AS "lastActivityMetadata", last_act.created_at AS "lastActivityAt",` : ''}
548-
${opts.includeStewards === true ? "COALESCE(ss_agg.stewards, '[]'::json) AS stewards," : ''}
549+
${opts.includeStewards === true ? 'ss_agg.stewards AS stewards,' : ''}
549550
COUNT(*) OVER() AS total
550551
FROM packages p
551552
${laterals}

services/libs/data-access-layer/src/osspckgs/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ export * from './packages'
33
export * from './maintainers'
44
export * from './versions'
55
export * from './repos'
6+
export * from './sqlFragments'
67
export * from './stewardships'
78
export * from './api'
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Severity stored as uppercase in advisories table.
2+
// Ranks: CRITICAL=4, HIGH=3, MEDIUM=2, LOW=1
3+
export const SEVERITY_RANK_EXPR = `MAX(CASE a.severity
4+
WHEN 'CRITICAL' THEN 4
5+
WHEN 'HIGH' THEN 3
6+
WHEN 'MEDIUM' THEN 2
7+
WHEN 'LOW' THEN 1
8+
ELSE 0 END)::int`
9+
10+
export const STEWARD_MENTIONED_JOIN = `
11+
LEFT JOIN stewards st_mentioned
12+
ON sa.activity_type = 'steward_added'
13+
AND st_mentioned.user_id = (sa.metadata->>'userId')`
14+
15+
export const STEWARD_DISPLAY_NAME_METADATA = `CASE
16+
WHEN sa.activity_type = 'steward_added' AND st_mentioned.display_name IS NOT NULL
17+
THEN COALESCE(sa.metadata, '{}'::jsonb) || jsonb_build_object('stewardDisplayName', st_mentioned.display_name)
18+
ELSE sa.metadata
19+
END`

services/libs/data-access-layer/src/osspckgs/stewardships.ts

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { QueryExecutor } from '../queryExecutor'
22

3-
import { SEVERITY_RANK_EXPR } from './api'
3+
import {
4+
SEVERITY_RANK_EXPR,
5+
STEWARD_DISPLAY_NAME_METADATA,
6+
STEWARD_MENTIONED_JOIN,
7+
} from './sqlFragments'
48

59
export interface StewardshipRecord {
610
id: string
@@ -261,6 +265,7 @@ export async function assignSteward(
261265
metadata: JSON.stringify({
262266
userId: data.userId,
263267
role: data.role,
268+
...(data.displayName != null ? { stewardDisplayName: data.displayName } : {}),
264269
...(data.note ? { note: data.note } : {}),
265270
}),
266271
},
@@ -350,6 +355,8 @@ export interface ActivityFeedRow {
350355
total: string
351356
}
352357

358+
export { STEWARD_DISPLAY_NAME_METADATA, STEWARD_MENTIONED_JOIN } from './sqlFragments'
359+
353360
export async function listStewardshipActivity(
354361
qx: QueryExecutor,
355362
opts: { page: number; pageSize: number },
@@ -366,13 +373,14 @@ export async function listStewardshipActivity(
366373
sa.actor_type AS "actorType",
367374
sa.activity_type AS "activityType",
368375
sa.content AS content,
369-
sa.metadata AS metadata,
376+
${STEWARD_DISPLAY_NAME_METADATA} AS metadata,
370377
s.status AS "stewardshipStatus",
371378
sa.created_at AS "createdAt",
372379
COUNT(*) OVER()::text AS total
373380
FROM stewardship_activity sa
374381
JOIN stewardships s ON s.id = sa.stewardship_id
375382
JOIN packages p ON p.id = s.package_id
383+
${STEWARD_MENTIONED_JOIN}
376384
ORDER BY sa.created_at DESC, sa.id DESC
377385
LIMIT $(limit) OFFSET $(offset)
378386
`,
@@ -430,16 +438,17 @@ export async function listPackageHistory(
430438
stewardshipId: string,
431439
): Promise<PackageHistoryEvent[]> {
432440
const rows: Array<Record<string, unknown>> = await qx.select(
433-
`SELECT id::text AS id,
434-
actor_user_id AS "actorUserId",
435-
actor_type AS "actorType",
436-
activity_type AS "activityType",
437-
content,
438-
metadata,
439-
created_at AS "createdAt"
440-
FROM stewardship_activity
441-
WHERE stewardship_id = $(stewardshipId)::bigint
442-
ORDER BY created_at DESC`,
441+
`SELECT sa.id::text AS id,
442+
sa.actor_user_id AS "actorUserId",
443+
sa.actor_type AS "actorType",
444+
sa.activity_type AS "activityType",
445+
sa.content,
446+
${STEWARD_DISPLAY_NAME_METADATA} AS metadata,
447+
sa.created_at AS "createdAt"
448+
FROM stewardship_activity sa
449+
${STEWARD_MENTIONED_JOIN}
450+
WHERE sa.stewardship_id = $(stewardshipId)::bigint
451+
ORDER BY sa.created_at DESC`,
443452
{ stewardshipId },
444453
)
445454
return rows.map((r) => ({
@@ -593,8 +602,10 @@ export async function listMyPackages(
593602

594603
const displayLaterals = `
595604
LEFT JOIN LATERAL (
596-
SELECT sa.content, sa.activity_type, sa.metadata, sa.created_at
605+
SELECT sa.content, sa.activity_type, sa.created_at,
606+
${STEWARD_DISPLAY_NAME_METADATA} AS metadata
597607
FROM stewardship_activity sa
608+
${STEWARD_MENTIONED_JOIN}
598609
WHERE sa.stewardship_id = s.id
599610
ORDER BY sa.created_at DESC
600611
LIMIT 1
@@ -688,7 +699,11 @@ export async function listMyPackages(
688699
scorecardScore: row.scorecardScore != null ? Number(row.scorecardScore) : null,
689700
openVulns: Number(row.openVulns),
690701
maxVulnSeverity: row.maxVulnSeverity ?? null,
691-
lastActivityContent: row.lastActivityContent ?? null,
702+
lastActivityContent: translateActivityContent(
703+
row.lastActivityContent ?? null,
704+
row.lastActivityType,
705+
row.lastActivityMetadata as Record<string, unknown> | null,
706+
),
692707
lastActivityType: row.lastActivityType ?? null,
693708
lastActivityMetadata: row.lastActivityMetadata ?? null,
694709
lastActivityAt: row.lastActivityAt ?? null,
@@ -753,12 +768,13 @@ export async function listMyActivity(
753768
sa.actor_type AS "actorType",
754769
sa.activity_type AS "activityType",
755770
sa.content AS content,
756-
sa.metadata AS metadata,
771+
${STEWARD_DISPLAY_NAME_METADATA} AS metadata,
757772
s.status AS "stewardshipStatus",
758773
sa.created_at AS "createdAt"
759774
FROM stewardship_activity sa
760775
JOIN stewardships s ON s.id = sa.stewardship_id
761776
JOIN packages p ON p.id = s.package_id
777+
${STEWARD_MENTIONED_JOIN}
762778
WHERE s.id IN (
763779
SELECT stewardship_id FROM stewardship_stewards
764780
WHERE user_id = $(userId) AND deleted_at IS NULL
@@ -845,6 +861,13 @@ export function translateActivityContent(
845861
metadata?: Record<string, unknown> | null,
846862
): string | null {
847863
if (!content) return content
864+
if (activityType === 'steward_added') {
865+
const displayName = metadata?.stewardDisplayName as string | undefined
866+
const role = metadata?.role as string | undefined
867+
if (displayName && role) {
868+
return `Assigned steward ${displayName} as ${role}`
869+
}
870+
}
848871
if (activityType === 'escalation' && metadata?.resolutionPath) {
849872
const label =
850873
ESCALATION_RESOLUTION_PATH_LABELS[metadata.resolutionPath as EscalationResolutionPath]

0 commit comments

Comments
 (0)