diff --git a/frontend/server/api/collection/[slug]/project-repos.ts b/frontend/server/api/collection/[slug]/project-repos.ts index db952b84a..1d4bb1820 100644 --- a/frontend/server/api/collection/[slug]/project-repos.ts +++ b/frontend/server/api/collection/[slug]/project-repos.ts @@ -3,7 +3,6 @@ import type { Pool } from 'pg'; import { postToTinybird } from '~~/server/data/tinybird/tinybird'; -import { legacyScoreFields } from '~~/server/helpers/health-score.helpers'; import { CommunityCollectionRepository } from '~~/server/repo/communityCollection.repo'; import { getOptionalUser } from '~~/server/utils/jwt'; import { paginationTotal, paginationHasMore } from '~~/server/utils/pagination'; @@ -121,9 +120,7 @@ export default defineEventHandler(async (event): Promise | E ); const data = response.data.map((item) => ({ - ...Object.fromEntries( - Object.entries(item).filter(([key]) => !legacyScoreFields.includes(key)), - ), + ...item, healthScore: item.healthScoreV2 ?? null, isLF: !!item.isLF, achievements: diff --git a/frontend/server/api/collection/[slug]/project-routes.test.ts b/frontend/server/api/collection/[slug]/project-routes.test.ts index 810e535fb..5972d8ad1 100644 --- a/frontend/server/api/collection/[slug]/project-routes.test.ts +++ b/frontend/server/api/collection/[slug]/project-routes.test.ts @@ -43,11 +43,6 @@ beforeEach(() => { type: 'project', slug: 'k8s', isLF: 1, - healthScore: 86, - contributorHealthScore: 90, - popularityHealthScore: 95, - developmentHealthScore: 80, - securityHealthScore: 85, healthScoreV2: 71, achievements: [], }, @@ -72,17 +67,6 @@ describe.each(['projects', 'project-repos'])('GET /api/collection/[slug]/%s', (r expect(res.data[1]).toMatchObject({ type: 'repo', healthScore: null }); }); - it.each([ - 'contributorHealthScore', - 'popularityHealthScore', - 'developmentHealthScore', - 'securityHealthScore', - ])('omits the v1 %s', async (field) => { - const res = await handlers[route](event); - - expect(res.data[0]).not.toHaveProperty(field); - }); - it.each([ ['healthScore_desc', 'healthScoreV2', 'desc'], ['healthScore_asc', 'healthScoreV2', 'asc'], diff --git a/frontend/server/api/collection/[slug]/projects.ts b/frontend/server/api/collection/[slug]/projects.ts index 347c08965..f9c401166 100644 --- a/frontend/server/api/collection/[slug]/projects.ts +++ b/frontend/server/api/collection/[slug]/projects.ts @@ -3,7 +3,6 @@ import type { Pool } from 'pg'; import { postToTinybird } from '~~/server/data/tinybird/tinybird'; -import { legacyScoreFields } from '~~/server/helpers/health-score.helpers'; import { CommunityCollectionRepository } from '~~/server/repo/communityCollection.repo'; import { getOptionalUser } from '~~/server/utils/jwt'; import { paginationTotal, paginationHasMore } from '~~/server/utils/pagination'; @@ -92,9 +91,7 @@ export default defineEventHandler(async (event): Promise | E ); const data = response.data.map((project) => ({ - ...Object.fromEntries( - Object.entries(project).filter(([key]) => !legacyScoreFields.includes(key)), - ), + ...project, healthScore: project.healthScoreV2 ?? null, isLF: !!project.isLF, achievements: diff --git a/frontend/server/api/ossindex/categories.ts b/frontend/server/api/ossindex/categories.ts index 931dccc0c..5c9a0e1c0 100644 --- a/frontend/server/api/ossindex/categories.ts +++ b/frontend/server/api/ossindex/categories.ts @@ -55,7 +55,6 @@ export default defineEventHandler(async (event): Promise { const [id, count, name, logo, softwareValue, avgScore] = project; - // Read the tail by distance from the end so it works with or without the upstream v1 health slot const [description, healthScoreV2, healthLabel, , healthMaxScore] = project.slice(-5); return { id: id as string, diff --git a/frontend/server/api/ossindex/collections.ts b/frontend/server/api/ossindex/collections.ts index 6a21bad2c..e2885e80e 100644 --- a/frontend/server/api/ossindex/collections.ts +++ b/frontend/server/api/ossindex/collections.ts @@ -51,7 +51,6 @@ export default defineEventHandler(async (event): Promise { const [id, count, name, logo, softwareValue, avgScore] = project; - // Read the tail by distance from the end so it works with or without the upstream v1 health slot const [description, slug, status, healthScoreV2, healthLabel, , healthMaxScore] = project.slice(-7); return { diff --git a/frontend/server/api/ossindex/groups.ts b/frontend/server/api/ossindex/groups.ts index d759a6fc7..41adbffa7 100644 --- a/frontend/server/api/ossindex/groups.ts +++ b/frontend/server/api/ossindex/groups.ts @@ -43,7 +43,6 @@ export default defineEventHandler(async (event): Promise { const [id, count, name, logo, softwareValue, avgScore] = project; - // Read the tail by distance from the end so it works with or without the upstream v1 health slot const [description, status, healthScoreV2, healthLabel, , healthMaxScore] = project.slice(-6); return { diff --git a/frontend/server/api/ossindex/ossindex.test.ts b/frontend/server/api/ossindex/ossindex.test.ts index 3b66ea64c..91d89fafd 100644 --- a/frontend/server/api/ossindex/ossindex.test.ts +++ b/frontend/server/api/ossindex/ossindex.test.ts @@ -47,35 +47,14 @@ const collectionRow = (topProjects: unknown[][]) => ({ topProjects, }); -// The upstream tuple drops its v1 health slot at index 6 in a later release, so both shapes must map. -const layouts = [ - { name: 'with the v1 health slot', v1: [99] }, - { name: 'without the v1 health slot', v1: [] }, -]; - -describe.each(layouts)('OSS index tuple mapping $name', ({ v1 }) => { +describe('OSS index tuple mapping', () => { it('maps the collections tuple', async () => { mockFetchFromTinybird.mockResolvedValue({ data: [ collectionRow([ - ['p1', 10, 'Proj', 'logo', 5, 1, ...v1, 'desc', 'proj', 'active', 71, 'healthy', 71, 100], - [ - 'p2', - 10, - 'Partial', - 'logo', - 5, - 1, - ...v1, - 'desc', - 'part', - 'active', - 64, - 'excellent', - 85, - 75, - ], - ['p3', 10, 'Korg', 'logo', 5, 1, ...v1, 'desc', 'korg', 'active', null, null, null, null], + ['p1', 10, 'Proj', 'logo', 5, 1, 'desc', 'proj', 'active', 71, 'healthy', 71, 100], + ['p2', 10, 'Partial', 'logo', 5, 1, 'desc', 'part', 'active', 64, 'excellent', 85, 75], + ['p3', 10, 'Korg', 'logo', 5, 1, 'desc', 'korg', 'active', null, null, null, null], ]), ], }); @@ -115,7 +94,7 @@ describe.each(layouts)('OSS index tuple mapping $name', ({ v1 }) => { { ...collectionRow([]), topCollections: [], - topProjects: [['p1', 10, 'Proj', 'logo', 5, 1, ...v1, 'desc', 40, 'fair', 40, 100]], + topProjects: [['p1', 10, 'Proj', 'logo', 5, 1, 'desc', 40, 'fair', 40, 100]], }, ], }); @@ -137,9 +116,7 @@ describe.each(layouts)('OSS index tuple mapping $name', ({ v1 }) => { { ...collectionRow([]), topCollections: [], - topProjects: [ - ['p1', 10, 'Proj', 'logo', 5, 1, ...v1, 'desc', 'active', 22, 'critical', 22, 65], - ], + topProjects: [['p1', 10, 'Proj', 'logo', 5, 1, 'desc', 'active', 22, 'critical', 22, 65]], }, ], }); diff --git a/frontend/server/api/project/[slug]/index.test.ts b/frontend/server/api/project/[slug]/index.test.ts index 7881a188e..6f479d753 100644 --- a/frontend/server/api/project/[slug]/index.test.ts +++ b/frontend/server/api/project/[slug]/index.test.ts @@ -36,7 +36,6 @@ const mockProjectRow = (row: Record) => describe('GET /api/project/[slug]', () => { it('serves the raw v2 score as healthScore', async () => { mockProjectRow({ - healthScore: 87.5, healthScoreV2: 52, healthMaxScore: 65, healthLabel: 'excellent', diff --git a/frontend/server/api/project/[slug]/insights.get.test.ts b/frontend/server/api/project/[slug]/insights.get.test.ts index 015caf911..789c3e338 100644 --- a/frontend/server/api/project/[slug]/insights.get.test.ts +++ b/frontend/server/api/project/[slug]/insights.get.test.ts @@ -26,17 +26,12 @@ beforeEach(() => { const event = { context: { params: { slug: 'k8s' } } } as unknown as H3Event; describe('GET /api/project/[slug]/insights', () => { - it('serves the v2 score as healthScore and omits the v1 sub-scores', async () => { + it('serves the v2 score as healthScore', async () => { mockFetchFromTinybird.mockResolvedValue({ data: [ { slug: 'k8s', isLF: 1, - healthScore: 87.5, - contributorHealthScore: 90, - popularityHealthScore: 95, - developmentHealthScore: 80, - securityHealthScore: 85, healthScoreV2: 71, healthLabel: 'healthy', achievements: [], @@ -47,10 +42,6 @@ describe('GET /api/project/[slug]/insights', () => { const res = await handler(event); expect(res).toMatchObject({ slug: 'k8s', healthScore: 71, healthLabel: 'healthy', isLF: true }); - expect(res).not.toHaveProperty('contributorHealthScore'); - expect(res).not.toHaveProperty('popularityHealthScore'); - expect(res).not.toHaveProperty('developmentHealthScore'); - expect(res).not.toHaveProperty('securityHealthScore'); }); it('returns a null healthScore for a project without a v2 score', async () => { diff --git a/frontend/server/api/project/[slug]/insights.get.ts b/frontend/server/api/project/[slug]/insights.get.ts index f52c7e39a..426772afe 100644 --- a/frontend/server/api/project/[slug]/insights.get.ts +++ b/frontend/server/api/project/[slug]/insights.get.ts @@ -1,7 +1,6 @@ // Copyright (c) 2025 The Linux Foundation and each contributor. // SPDX-License-Identifier: MIT import { fetchFromTinybird } from '~~/server/data/tinybird/tinybird'; -import { legacyScoreFields } from '~~/server/helpers/health-score.helpers'; import { useApiTrackEvent } from '~~/server/utils/plausible'; import type { ProjectInsightsTinybird } from '~~/types/project'; @@ -33,16 +32,13 @@ export default defineEventHandler(async (event) => { }, }); - const row = response.data?.[0]; - if (!row) { + const project = response.data?.[0]; + if (!project) { throw createError({ statusCode: 404, statusMessage: 'Project not found', }); } - const project = Object.fromEntries( - Object.entries(row).filter(([key]) => !legacyScoreFields.includes(key)), - ) as typeof row; return { ...project, diff --git a/frontend/server/api/project/index.test.ts b/frontend/server/api/project/index.test.ts index 0a297e583..e1b54a2dd 100644 --- a/frontend/server/api/project/index.test.ts +++ b/frontend/server/api/project/index.test.ts @@ -28,7 +28,7 @@ beforeEach(() => { data: params.count ? [{ 'count(id)': 2 }] : [ - { slug: 'k8s', isLF: 1, healthScore: 87.5, healthScoreV2: 52, healthMaxScore: 65 }, + { slug: 'k8s', isLF: 1, healthScoreV2: 52, healthMaxScore: 65 }, { slug: 'korg', isLF: 0, healthScoreV2: null, healthMaxScore: null }, ], }), diff --git a/frontend/server/helpers/health-score.helpers.ts b/frontend/server/helpers/health-score.helpers.ts index 7616389fe..269af7f2e 100644 --- a/frontend/server/helpers/health-score.helpers.ts +++ b/frontend/server/helpers/health-score.helpers.ts @@ -12,14 +12,6 @@ export interface HealthScoreFilters { endDate?: DateTime; } -// Tinybird returns these v1 columns until crowd.dev drops them; API responses omit them. -export const legacyScoreFields = [ - 'contributorHealthScore', - 'popularityHealthScore', - 'developmentHealthScore', - 'securityHealthScore', -]; - const healthScores: string[] = [ 'active_contributors', 'contributor_dependency',