feat: report user local git project count

This commit is contained in:
Curry Yang
2025-10-14 17:24:54 +08:00
parent 1118429b8e
commit 64e41370be
3 changed files with 43 additions and 1 deletions

View File

@@ -3,6 +3,7 @@ import { href, redirect } from 'react-router';
import { database } from '~/common/database';
import { projectLock } from '~/common/project';
import * as models from '~/models';
import { reportGitProjectCount } from '~/routes/organization.$organizationId.project.new';
import { insomniaFetch } from '~/ui/insomniaFetch';
import { invariant } from '~/utils/invariant';
import { createFetcherSubmitHook, getInitialRouteForOrganization } from '~/utils/router';
@@ -53,6 +54,8 @@ export async function clientAction({ params }: Route.ClientActionArgs) {
await database.flushChanges(bufferId);
project.gitRepositoryId && reportGitProjectCount(organizationId, sessionId);
// When redirect to `/organizations/:organizationId`, it sometimes doesn't reload the index loader, so manually redirect to the initial route for the organization
const initialOrganizationRoute = await getInitialRouteForOrganization({ organizationId });
return redirect(initialOrganizationRoute);

View File

@@ -7,6 +7,7 @@ import type { OauthProviderName } from '~/models/git-credentials';
import type { GitCredentials } from '~/models/git-repository';
import { EMPTY_GIT_PROJECT_ID } from '~/models/project';
import type { WorkspaceMeta } from '~/models/workspace-meta';
import { reportGitProjectCount } from '~/routes/organization.$organizationId.project.new';
import { SegmentEvent } from '~/ui/analytics';
import { insomniaFetch } from '~/ui/insomniaFetch';
import { invariant } from '~/utils/invariant';
@@ -179,6 +180,8 @@ export async function clientAction({ request, params }: Route.ClientActionArgs)
}
await models.project.update(project, { name, remoteId: newCloudProject.id, gitRepositoryId: null });
project.gitRepositoryId && reportGitProjectCount(organizationId, sessionId);
return {
success: true,
};
@@ -278,6 +281,8 @@ export async function clientAction({ request, params }: Route.ClientActionArgs)
}
}
reportGitProjectCount(organizationId, sessionId);
return {
success: true,
};
@@ -290,6 +295,8 @@ export async function clientAction({ request, params }: Route.ClientActionArgs)
gitRepository && (await models.gitRepository.remove(gitRepository));
await models.project.update(project, { name, gitRepositoryId: null });
reportGitProjectCount(organizationId, sessionId);
return {
success: true,
};

View File

@@ -1,9 +1,11 @@
import { href, redirect } from 'react-router';
import { database } from '~/common/database';
import { isNotNullOrUndefined } from '~/common/misc';
import { projectLock } from '~/common/project';
import * as models from '~/models';
import type { GitCredentials, OauthProviderName } from '~/models/git-repository';
import { EMPTY_GIT_PROJECT_ID } from '~/models/project';
import { EMPTY_GIT_PROJECT_ID, type Project } from '~/models/project';
import { SegmentEvent } from '~/ui/analytics';
import { insomniaFetch } from '~/ui/insomniaFetch';
import { invariant } from '~/utils/invariant';
@@ -29,6 +31,34 @@ export interface CreateProjectData {
connectRepositoryLater?: boolean;
}
export const reportGitProjectCount = async (organizationId: string, sessionId: string, maxRetries = 3) => {
const projects = await database.find<Project>(models.project.type, {
parentId: organizationId,
});
const gitRepositoryIds = projects.map(p => p.gitRepositoryId).filter(isNotNullOrUndefined);
const gitProjectsCount = gitRepositoryIds.length;
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
await insomniaFetch({
method: 'PATCH',
path: `/v1/organizations/${organizationId}/git-projects`,
sessionId,
onlyResolveOnSuccess: true,
data: {
count: gitProjectsCount,
},
});
return;
} catch (err) {
if (attempt < maxRetries) {
await new Promise(resolve => setTimeout(resolve, attempt * 1000));
}
}
}
console.warn('Report git project count failed');
};
export const createProject = async (organizationId: string, newProjectData: CreateProjectData) => {
const createProjectImpl = async (organizationId: string, newProjectData: CreateProjectData) => {
const user = await models.userSession.getOrCreate();
@@ -51,6 +81,7 @@ export const createProject = async (organizationId: string, newProjectData: Crea
parentId: organizationId,
gitRepositoryId: EMPTY_GIT_PROJECT_ID,
});
reportGitProjectCount(organizationId, sessionId);
return project._id;
}
@@ -91,6 +122,7 @@ export const createProject = async (organizationId: string, newProjectData: Crea
if (errors) {
throw new Error(errors.join(', '));
}
reportGitProjectCount(organizationId, sessionId);
return projectId;
}