mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-15 00:54:06 -08:00
wip: evaluation/tests endpoint CRUD
This commit is contained in:
parent
961d42fd51
commit
de4d486223
|
@ -1,4 +1,4 @@
|
||||||
import type { FindManyOptions, FindOptionsSelect, FindOptionsWhere } from '@n8n/typeorm';
|
import type { FindManyOptions, FindOptionsWhere } from '@n8n/typeorm';
|
||||||
import { DataSource, In, Repository } from '@n8n/typeorm';
|
import { DataSource, In, Repository } from '@n8n/typeorm';
|
||||||
import { Service } from 'typedi';
|
import { Service } from 'typedi';
|
||||||
|
|
||||||
|
@ -21,32 +21,12 @@ export class TestRepository extends Repository<TestEntity> {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
type Select = FindOptionsSelect<TestEntity>;
|
|
||||||
|
|
||||||
const select: Select = {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
createdAt: true,
|
|
||||||
updatedAt: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
const relations: string[] = ['workflow', 'evaluationWorkflow', 'annotationTag'];
|
|
||||||
|
|
||||||
const isDefaultSelect = options?.select === undefined;
|
|
||||||
|
|
||||||
const findManyOptions: FindManyOptions<TestEntity> = {
|
const findManyOptions: FindManyOptions<TestEntity> = {
|
||||||
select: { ...select, id: true },
|
|
||||||
where,
|
where,
|
||||||
|
relations: ['annotationTag'],
|
||||||
|
order: { createdAt: 'DESC' },
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isDefaultSelect || options?.select?.updatedAt === true) {
|
|
||||||
findManyOptions.order = { updatedAt: 'ASC' };
|
|
||||||
}
|
|
||||||
|
|
||||||
if (relations.length > 0) {
|
|
||||||
findManyOptions.relations = relations;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (options?.take) {
|
if (options?.take) {
|
||||||
findManyOptions.skip = options.skip;
|
findManyOptions.skip = options.skip;
|
||||||
findManyOptions.take = options.take;
|
findManyOptions.take = options.take;
|
||||||
|
@ -56,4 +36,25 @@ export class TestRepository extends Repository<TestEntity> {
|
||||||
|
|
||||||
return { tests, count };
|
return { tests, count };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getOne(id: number, sharedWorkflowIds: string[]) {
|
||||||
|
return await this.findOne({
|
||||||
|
where: {
|
||||||
|
id,
|
||||||
|
workflow: {
|
||||||
|
id: In(sharedWorkflowIds),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
relations: ['annotationTag'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteById(id: number, sharedWorkflowIds: string[]) {
|
||||||
|
return await this.delete({
|
||||||
|
id,
|
||||||
|
workflow: {
|
||||||
|
id: In(sharedWorkflowIds),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
import { Get, /*Patch, Post,*/ RestController } from '@/decorators';
|
import { Get, Post, Patch, RestController, Delete } from '@/decorators';
|
||||||
|
import { BadRequestError } from '@/errors/response-errors/bad-request.error';
|
||||||
|
import { NotFoundError } from '@/errors/response-errors/not-found.error';
|
||||||
import { listQueryMiddleware } from '@/middlewares';
|
import { listQueryMiddleware } from '@/middlewares';
|
||||||
|
import { getSharedWorkflowIds } from '@/public-api/v1/handlers/workflows/workflows.service';
|
||||||
|
import { isPositiveInteger } from '@/utils';
|
||||||
|
|
||||||
import { TestsService } from './tests.service';
|
import { TestsService } from './tests.service';
|
||||||
import { TestsRequest } from './tests.types';
|
import { TestsRequest } from './tests.types';
|
||||||
|
@ -8,62 +12,61 @@ import { TestsRequest } from './tests.types';
|
||||||
export class TestsController {
|
export class TestsController {
|
||||||
constructor(private readonly testsService: TestsService) {}
|
constructor(private readonly testsService: TestsService) {}
|
||||||
|
|
||||||
// private async getAccessibleWorkflowIds(user: User, scope: Scope) {
|
|
||||||
// if (this.license.isSharingEnabled()) {
|
|
||||||
// return await this.workflowSharingService.getSharedWorkflowIds(user, { scopes: [scope] });
|
|
||||||
// } else {
|
|
||||||
// return await this.workflowSharingService.getSharedWorkflowIds(user, {
|
|
||||||
// workflowRoles: ['workflow:owner'],
|
|
||||||
// projectRoles: ['project:personalOwner'],
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
@Get('/', { middlewares: listQueryMiddleware })
|
@Get('/', { middlewares: listQueryMiddleware })
|
||||||
async getMany(req: TestsRequest.GetMany) {
|
async getMany(req: TestsRequest.GetMany) {
|
||||||
return await this.testsService.getMany(req.user, req.listQueryOptions);
|
const workflowIds = await getSharedWorkflowIds(req.user, ['workflow:read']);
|
||||||
|
|
||||||
|
return await this.testsService.getMany(req.user, req.listQueryOptions, workflowIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Get('/:id')
|
@Get('/:id')
|
||||||
// async getOne(req: ExecutionRequest.GetOne) {
|
async getOne(req: TestsRequest.GetOne) {
|
||||||
// if (!isPositiveInteger(req.params.id)) {
|
if (!isPositiveInteger(req.params.id)) {
|
||||||
// throw new BadRequestError('Execution ID is not a number');
|
throw new BadRequestError('Test ID is not a number');
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// const workflowIds = await this.getAccessibleWorkflowIds(req.user, 'workflow:read');
|
const workflowIds = await getSharedWorkflowIds(req.user, ['workflow:read']);
|
||||||
//
|
|
||||||
// if (workflowIds.length === 0) throw new NotFoundError('Execution not found');
|
return await this.testsService.findOne(Number(req.params.id), workflowIds);
|
||||||
//
|
}
|
||||||
// return this.license.isSharingEnabled()
|
|
||||||
// ? await this.enterpriseExecutionService.findOne(req, workflowIds)
|
@Post('/')
|
||||||
// : await this.executionService.findOne(req, workflowIds);
|
async create(req: TestsRequest.Create) {
|
||||||
// }
|
const workflowIds = await getSharedWorkflowIds(req.user, ['workflow:read']);
|
||||||
//
|
|
||||||
// @Post('/delete')
|
if (!workflowIds.includes(req.body.workflowId)) {
|
||||||
// async delete(req: ExecutionRequest.Delete) {
|
throw new BadRequestError('User does not have access to the workflow');
|
||||||
// const workflowIds = await this.getAccessibleWorkflowIds(req.user, 'workflow:execute');
|
}
|
||||||
//
|
|
||||||
// if (workflowIds.length === 0) throw new NotFoundError('Execution not found');
|
return await this.testsService.save(this.testsService.toEntity(req.body));
|
||||||
//
|
}
|
||||||
// return await this.executionService.delete(req, workflowIds);
|
|
||||||
// }
|
@Delete('/:id')
|
||||||
//
|
async delete(req: TestsRequest.Delete) {
|
||||||
// @Patch('/:id')
|
if (!isPositiveInteger(req.params.id)) {
|
||||||
// async update(req: ExecutionRequest.Update) {
|
throw new BadRequestError('Test ID is not a number');
|
||||||
// if (!isPositiveInteger(req.params.id)) {
|
}
|
||||||
// throw new BadRequestError('Execution ID is not a number');
|
|
||||||
// }
|
const workflowIds = await getSharedWorkflowIds(req.user, ['workflow:read']);
|
||||||
//
|
|
||||||
// const workflowIds = await this.getAccessibleWorkflowIds(req.user, 'workflow:read');
|
if (workflowIds.length === 0) throw new NotFoundError('Test not found');
|
||||||
//
|
|
||||||
// // Fail fast if no workflows are accessible
|
return await this.testsService.delete(Number(req.params.id), workflowIds);
|
||||||
// if (workflowIds.length === 0) throw new NotFoundError('Execution not found');
|
}
|
||||||
//
|
|
||||||
// const { body: payload } = req;
|
@Patch('/:id')
|
||||||
// const validatedPayload = validateExecutionUpdatePayload(payload);
|
async update(req: TestsRequest.Update) {
|
||||||
//
|
if (!isPositiveInteger(req.params.id)) {
|
||||||
// await this.executionService.annotate(req.params.id, validatedPayload, workflowIds);
|
throw new BadRequestError('Test ID is not a number');
|
||||||
//
|
}
|
||||||
// return await this.executionService.findOne(req, workflowIds);
|
|
||||||
// }
|
const workflowIds = await getSharedWorkflowIds(req.user, ['workflow:read']);
|
||||||
|
|
||||||
|
// Fail fast if no workflows are accessible
|
||||||
|
if (workflowIds.length === 0) throw new NotFoundError('Workflow not found');
|
||||||
|
|
||||||
|
return await this.testsService.save(
|
||||||
|
this.testsService.toEntity({ ...req.body, id: Number(req.params.id) }),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,38 @@ export class TestsService {
|
||||||
private readonly workflowSharingService: WorkflowSharingService,
|
private readonly workflowSharingService: WorkflowSharingService,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
// toEntity(attrs: { name: string; id?: string }) {
|
toEntity(attrs: {
|
||||||
// attrs.name = attrs.name.trim();
|
name?: string;
|
||||||
//
|
workflowId?: string;
|
||||||
// return this.testRepository.create(attrs);
|
evaluationWorkflowId?: string;
|
||||||
// }
|
id?: number;
|
||||||
|
}) {
|
||||||
|
const entity = {
|
||||||
|
name: attrs.name?.trim(),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (attrs.id) {
|
||||||
|
entity.id = attrs.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs.workflowId) {
|
||||||
|
entity.workflow = {
|
||||||
|
id: attrs.workflowId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attrs.evaluationWorkflowId) {
|
||||||
|
entity.evaluationWorkflow = {
|
||||||
|
id: attrs.evaluationWorkflowId,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.testRepository.create(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
async findOne(id: number, accessibleWorkflowIds: string[]) {
|
||||||
|
return await this.testRepository.getOne(id, accessibleWorkflowIds);
|
||||||
|
}
|
||||||
|
|
||||||
async save(test: TestEntity) {
|
async save(test: TestEntity) {
|
||||||
await validateEntity(test);
|
await validateEntity(test);
|
||||||
|
@ -26,15 +53,11 @@ export class TestsService {
|
||||||
return await this.testRepository.save(test);
|
return await this.testRepository.save(test);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(id: string) {
|
async delete(id: number, accessibleWorkflowIds: string[]) {
|
||||||
return await this.testRepository.delete(id);
|
return await this.testRepository.deleteById(id, accessibleWorkflowIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getMany(user: User, options: ListQuery.Options) {
|
async getMany(user: User, options: ListQuery.Options, accessibleWorkflowIds: string[] = []) {
|
||||||
const sharedWorkflowIds = await this.workflowSharingService.getSharedWorkflowIds(user, {
|
return await this.testRepository.getMany(accessibleWorkflowIds, options);
|
||||||
scopes: ['workflow:read'],
|
|
||||||
});
|
|
||||||
|
|
||||||
return await this.testRepository.getMany(sharedWorkflowIds, options);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import type { TestEntity } from '@/databases/entities/test-entity';
|
|
||||||
import type { AuthenticatedRequest, ListQuery } from '@/requests';
|
import type { AuthenticatedRequest, ListQuery } from '@/requests';
|
||||||
|
|
||||||
// ----------------------------------
|
// ----------------------------------
|
||||||
|
@ -8,7 +7,7 @@ import type { AuthenticatedRequest, ListQuery } from '@/requests';
|
||||||
export declare namespace TestsRequest {
|
export declare namespace TestsRequest {
|
||||||
namespace RouteParams {
|
namespace RouteParams {
|
||||||
type TestId = {
|
type TestId = {
|
||||||
id: TestEntity['id'];
|
id: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue