Skip to content
Draft
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
18 changes: 18 additions & 0 deletions frontend/server/api/project/[slug]/activity-types.get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) 2025 The Linux Foundation and each contributor.
// SPDX-License-Identifier: MIT
import {createDataSource} from "~~/server/data/data-sources";
import type {ActivityTypesFilter} from "~~/types/development/requests.types";

export default defineEventHandler(async (event) => {
const query = getQuery(event);
const project = (event.context.params as { slug: string }).slug;

const filter: ActivityTypesFilter = {
project,
repository: query?.repository as string,
};

const dataSource = createDataSource();

return await dataSource.fetchActivityTypes(filter);
});
8 changes: 6 additions & 2 deletions frontend/server/data/data-sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,16 @@ import type {
WaitTime1stReview,
MergeLeadTime,
CodeReviewEngagement,
ContributionOutsideHours
ContributionOutsideHours,
ActivityTypesResponse
} from "~~/types/development/responses.types";
import type {CodeReviewEngagementFilter} from "~~/types/development/requests.types";
import type {CodeReviewEngagementFilter, ActivityTypesFilter} from "~~/types/development/requests.types";
import {fetchMailingListsMessageActivities} from "~~/server/data/tinybird/mailing-lists-messages-data-source";
import {fetchCommitActivities} from "~~/server/data/tinybird/commit-activites-data-source";
import {fetchPackages} from "~~/server/data/tinybird/packages-data-source";
import {fetchPackageMetrics} from "~~/server/data/tinybird/package-metrics-data-source";
import type {PackageDownloadsResponse} from "~~/server/data/tinybird/package-metrics-data-source";
import {fetchActivityTypes} from "~~/server/data/tinybird/activity-types-data-source";

export interface DataSource {
fetchActiveContributors: (filter: ActiveContributorsFilter) => Promise<ActiveContributorsResponse>;
Expand All @@ -103,6 +105,7 @@ export interface DataSource {
=> Promise<ContributionOutsideHours>;
fetchPackages(filter: PackageFilter): Promise<Package[]>;
fetchPackageMetrics(filter: PackageMetricsFilter): Promise<PackageDownloadsResponse>;
fetchActivityTypes(filter: ActivityTypesFilter): Promise<ActivityTypesResponse>;
}

export function createDataSource(): DataSource {
Expand Down Expand Up @@ -130,5 +133,6 @@ export function createDataSource(): DataSource {
fetchContributionsOutsideWorkHours,
fetchPackages,
fetchPackageMetrics,
fetchActivityTypes,
};
}
76 changes: 76 additions & 0 deletions frontend/server/data/tinybird/activity-types-data-source.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright (c) 2025 The Linux Foundation and each contributor.
// SPDX-License-Identifier: MIT
import {
describe, test, expect, vi, beforeEach
} from 'vitest';
import type {ActivityTypesFilter} from "~~/types/development/requests.types";
import type {ActivityTypesTinybirdQuery} from "~~/server/data/tinybird/requests.types";

const mockFetchFromTinybird = vi.fn();

const mockActivityTypesResponse = {
data: {
github: ['pull_request-opened', 'pull_request-merged', 'issue-comment'],
gitlab: ['merge_request-opened', 'merge_request-merged'],
jira: ['issue-created', 'issue-updated']
}
};

describe('Activity Types Data Source', () => {
beforeEach(() => {
mockFetchFromTinybird.mockClear();

vi.doMock(import("./tinybird"), () => ({
fetchFromTinybird: mockFetchFromTinybird,
}));
});

test('should fetch activity types with correct parameters', async () => {
const {fetchActivityTypes} = await import("~~/server/data/tinybird/activity-types-data-source");

mockFetchFromTinybird.mockResolvedValueOnce(mockActivityTypesResponse);

const filter: ActivityTypesFilter = {
project: 'test-project',
repository: 'test-repo'
};

const result = await fetchActivityTypes(filter);

const expectedQuery: ActivityTypesTinybirdQuery = {
project: 'test-project',
repo: 'test-repo'
};

expect(mockFetchFromTinybird).toHaveBeenCalledWith(
'/v0/pipes/activity_types.json',
expectedQuery
);

expect(result).toEqual(mockActivityTypesResponse.data);
});

test('should fetch activity types without repository parameter', async () => {
const {fetchActivityTypes} = await import("~~/server/data/tinybird/activity-types-data-source");

mockFetchFromTinybird.mockResolvedValueOnce(mockActivityTypesResponse);

const filter: ActivityTypesFilter = {
project: 'test-project'
};

const result = await fetchActivityTypes(filter);

const expectedQuery: ActivityTypesTinybirdQuery = {
project: 'test-project',
repo: undefined
};

expect(mockFetchFromTinybird).toHaveBeenCalledWith(
'/v0/pipes/activity_types.json',
expectedQuery
);

expect(result).toEqual(mockActivityTypesResponse.data);
});
});
21 changes: 21 additions & 0 deletions frontend/server/data/tinybird/activity-types-data-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) 2025 The Linux Foundation and each contributor.
// SPDX-License-Identifier: MIT
import {fetchFromTinybird} from "~~/server/data/tinybird/tinybird";
import type {ActivityTypesFilter} from "~~/types/development/requests.types";
import type {ActivityTypesResponse} from "~~/types/development/responses.types";
import type {ActivityTypesTinybirdQuery} from "~~/server/data/tinybird/requests.types";
import type {TinybirdActivityTypesResponse} from "~~/server/data/tinybird/responses.types";

export async function fetchActivityTypes(filter: ActivityTypesFilter): Promise<ActivityTypesResponse> {
const query: ActivityTypesTinybirdQuery = {
project: filter.project,
repo: filter.repository,
};

const response = await fetchFromTinybird<TinybirdActivityTypesResponse>(
'/v0/pipes/activity_types.json',
query
);

return response.data;
}
8 changes: 7 additions & 1 deletion frontend/server/data/tinybird/requests.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type {Granularity} from "~~/types/shared/granularity";
* They don't necessarily match the types that the frontend uses because they are only meant to be used with TinyBird.
*/


export type ContributorsLeaderboardTinybirdQuery = {
project: string;
platform?: ActivityPlatforms;
Expand Down Expand Up @@ -69,4 +70,9 @@ export type ActivitiesCountTinybirdQuery = {
onlyContributions?: boolean;
startDate?: DateTime;
endDate?: DateTime;
}
}

export type ActivityTypesTinybirdQuery = {
project: string;
repo?: string;
}
4 changes: 4 additions & 0 deletions frontend/server/data/tinybird/responses.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,7 @@ export type TinyBirdActivitiesCountDataItem = {
endDate: string,
activityCount?: number
};

export type TinybirdActivityTypesResponse = {
[platform: string]: string[];
};
5 changes: 5 additions & 0 deletions frontend/types/development/requests.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ export type ContributionsOutsideWorkHoursFilter = {
startDate?: DateTime,
endDate?: DateTime,
};

export type ActivityTypesFilter = {
project: string,
repository?: string,
};
4 changes: 4 additions & 0 deletions frontend/types/development/responses.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,7 @@ export interface WaitTime1stReview {
waitTime: number;
}[];
}

export type ActivityTypesResponse = {
[platform: string]: string[];
};
Loading