mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-23 11:44:06 -08:00
feat(core): Filter executions by project ID in internal API (#10976)
This commit is contained in:
parent
5a99e93f8d
commit
06d749ffa7
|
@ -54,6 +54,8 @@ import { ExecutionDataRepository } from './execution-data.repository';
|
|||
import type { ExecutionData } from '../entities/execution-data';
|
||||
import { ExecutionEntity } from '../entities/execution-entity';
|
||||
import { ExecutionMetadata } from '../entities/execution-metadata';
|
||||
import { SharedWorkflow } from '../entities/shared-workflow';
|
||||
import { WorkflowEntity } from '../entities/workflow-entity';
|
||||
|
||||
export interface IGetExecutionsQueryFilter {
|
||||
id?: FindOperator<string> | string;
|
||||
|
@ -874,6 +876,7 @@ export class ExecutionRepository extends Repository<ExecutionEntity> {
|
|||
metadata,
|
||||
annotationTags,
|
||||
vote,
|
||||
projectId,
|
||||
} = query;
|
||||
|
||||
const fields = Object.keys(this.summaryFields)
|
||||
|
@ -945,6 +948,12 @@ export class ExecutionRepository extends Repository<ExecutionEntity> {
|
|||
}
|
||||
}
|
||||
|
||||
if (projectId) {
|
||||
qb.innerJoin(WorkflowEntity, 'w', 'w.id = execution.workflowId')
|
||||
.innerJoin(SharedWorkflow, 'sw', 'sw.workflowId = w.id')
|
||||
.where('sw.projectId = :projectId', { projectId });
|
||||
}
|
||||
|
||||
return qb;
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ export namespace ExecutionSummaries {
|
|||
startedBefore: string;
|
||||
annotationTags: string[]; // tag IDs
|
||||
vote: AnnotationVote;
|
||||
projectId: string;
|
||||
}>;
|
||||
|
||||
type AccessFields = {
|
||||
|
|
|
@ -6,6 +6,7 @@ import { ExecutionRepository } from '@/databases/repositories/execution.reposito
|
|||
import { WorkflowRepository } from '@/databases/repositories/workflow.repository';
|
||||
import { ExecutionService } from '@/executions/execution.service';
|
||||
import type { ExecutionSummaries } from '@/executions/execution.types';
|
||||
import { createTeamProject } from '@test-integration/db/projects';
|
||||
|
||||
import { annotateExecution, createAnnotationTags, createExecution } from './shared/db/executions';
|
||||
import { createWorkflow } from './shared/db/workflows';
|
||||
|
@ -294,6 +295,37 @@ describe('ExecutionService', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('should filter executions by `projectId`', async () => {
|
||||
const firstProject = await createTeamProject();
|
||||
const secondProject = await createTeamProject();
|
||||
|
||||
const firstWorkflow = await createWorkflow(undefined, firstProject);
|
||||
const secondWorkflow = await createWorkflow(undefined, secondProject);
|
||||
|
||||
await createExecution({ status: 'success' }, firstWorkflow);
|
||||
await createExecution({ status: 'success' }, firstWorkflow);
|
||||
await createExecution({ status: 'success' }, secondWorkflow); // to filter out
|
||||
|
||||
const query: ExecutionSummaries.RangeQuery = {
|
||||
kind: 'range',
|
||||
range: { limit: 20 },
|
||||
accessibleWorkflowIds: [firstWorkflow.id],
|
||||
projectId: firstProject.id,
|
||||
};
|
||||
|
||||
const output = await executionService.findRangeWithCount(query);
|
||||
|
||||
expect(output).toEqual({
|
||||
count: 2,
|
||||
estimated: false,
|
||||
results: expect.arrayContaining([
|
||||
expect.objectContaining({ workflowId: firstWorkflow.id }),
|
||||
expect.objectContaining({ workflowId: firstWorkflow.id }),
|
||||
// execution for workflow in second project was filtered out
|
||||
]),
|
||||
});
|
||||
});
|
||||
|
||||
test('should exclude executions by inaccessible `workflowId`', async () => {
|
||||
const accessibleWorkflow = await createWorkflow();
|
||||
const inaccessibleWorkflow = await createWorkflow();
|
||||
|
|
Loading…
Reference in a new issue