| 390 | }; |
| 391 | } |
| 392 | |
| 393 | function resultSummary( |
| 394 | results: MergeTeamRunMemberResult[], |
| 395 | requested = results.length |
| 396 | ): MergeTeamRunMembersResponse['summary'] { |
| 397 | return { |
| 398 | requested, |
| 399 | considered: results.length, |
| 400 | merged: results.filter((item) => item.status === 'MERGED').length, |
| 401 | alreadyMerged: results.filter((item) => item.status === 'ALREADY_MERGED').length, |
| 402 | wouldMerge: results.filter((item) => item.status === 'WOULD_MERGE').length, |
| 403 | skipped: results.filter((item) => item.status === 'SKIPPED').length, |
| 404 | conflicts: results.filter((item) => item.status === 'CONFLICT').length, |
| 405 | failed: results.filter((item) => item.status === 'FAILED').length, |
| 406 | }; |
| 407 | } |
| 408 | |
| 409 | export class WorkspaceService { |
| 410 | private static readonly mainWorkspaceClaims = new Map<string, Promise<WorkspaceWithVisibleSessions>>(); |
| 411 | private static readonly dedicatedWorkspaceClaims = new Map<string, Promise<WorkspaceWithVisibleSessions>>(); |
| 412 | private sessionService = getSessionManager(); |
| 413 | private eventBus: EventBus = getEventBus(); |
| 414 | |
| 415 | constructor( |
| 416 | private readonly lockService: TeamLockService = defaultTeamLockService, |
| 417 | private readonly backgroundService: Pick<WorkspaceBackgroundService, 'stopAllForWorkspace'> |
| 418 | & Partial<Pick<WorkspaceBackgroundService, 'releaseLogsForWorkspace'>> = getWorkspaceBackgroundService(), |
| 419 | ) {} |
| 420 | |
| 421 | private getBaseBranch(workspace: { |
| 422 | baseBranch: string | null; |
| 423 | task: { project: { mainBranch: string } }; |
| 424 | }): string { |
| 425 | return workspace.baseBranch || workspace.task.project.mainBranch; |
| 426 | } |
| 427 | |
| 428 | // ── Queries ────────────────────────────────────────────────────────────────── |
| 429 | |
| 430 | async findById(id: string) { |
| 431 | const workspace = await prisma.workspace.findUnique({ |
| 432 | where: { id }, |
| 433 | include: { sessions: visibleSessionsFilter, task: { include: { project: true } } }, |
| 434 | }); |
| 435 | if (!workspace) return null; |
| 436 | ensureTaskNotDeleted(workspace.task); |
| 437 | return workspace; |
| 438 | } |
| 439 | |
| 440 | /** |
| 441 | * 获取 Task 下所有 Workspace |
| 442 | */ |
| 443 | async findByTaskId(taskId: string) { |
| 444 | const task = await prisma.task.findUnique({ where: { id: taskId } }); |
| 445 | if (!task) { |
| 446 | throw new NotFoundError('Task', taskId); |
| 447 | } |
| 448 | ensureTaskNotDeleted(task); |
| 449 |
nothing calls this directly
no test coverage detected