Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Endpoint to assign a job to user and to retrieve assigned jobs #16

Merged
merged 7 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from 6 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
2 changes: 2 additions & 0 deletions packages/apps/human-app/server/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ REPUTATION_ORACLE_URL=
E2E_TESTING_EMAIL_ADDRESS=
E2E_TESTING_PASSWORD=
E2E_TESTING_EXCHANGE_ORACLE_URL=
E2E_TESTING_ESCROW_ADDRESS=
E2E_TESTING_ESCROW_CHAIN_ID=
4 changes: 4 additions & 0 deletions packages/apps/human-app/server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { WorkerController } from './modules/user-worker/worker.controller';
import { CommonConfigModule } from './common/config/common-config.module';
import { JobsDiscoveryModule } from './modules/jobs-discovery/jobs-discovery.module';
import { JobsDiscoveryController } from './modules/jobs-discovery/jobs-discovery.controller';
import { JobAssignmentController } from './modules/job-assignment/job-assignment.controller';
import { JobAssignmentModule } from './modules/job-assignment/job-assignment.module';

@Module({
imports: [
Expand All @@ -28,6 +30,7 @@ import { JobsDiscoveryController } from './modules/jobs-discovery/jobs-discovery
WorkerModule,
OperatorModule,
JobsDiscoveryModule,
JobAssignmentModule,
ReputationOracleModule,
CommonConfigModule,
],
Expand All @@ -36,6 +39,7 @@ import { JobsDiscoveryController } from './modules/jobs-discovery/jobs-discovery
OperatorController,
WorkerController,
JobsDiscoveryController,
JobAssignmentController,
],
providers: [],
exports: [HttpModule],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,23 @@ export class TestEnvironmentConfigService {
return this.configService.get<string>('E2E_TESTING_PASSWORD', '');
}
get e2eTestingExchangeOracleUrl(): string {
return this.configService.get<string>('E2E_TESTING_EXCHANGE_ORACLE_URL', '');
return this.configService.get<string>(
'E2E_TESTING_EXCHANGE_ORACLE_URL',
'',
);
}
get e2eTestingEscrowAddress(): string {
return this.configService.get<string>('E2E_TESTING_ESCROW_ADDRESS', '');
}
get e2eTestingEscrowChainId(): string {
return this.configService.get<string>('E2E_TESTING_ESCROW_CHAIN_ID', '');
}
}

export const testEnvValidator = Joi.object({
E2E_TESTING_EMAIL_ADDRESS: Joi.string().required(),
E2E_TESTING_PASSWORD: Joi.string().required(),
E2E_TESTING_EXCHANGE_ORACLE_URL: Joi.string().required(),
E2E_TESTING_ESCROW_ADDRESS: Joi.string().required(),
E2E_TESTING_ESCROW_CHAIN_ID: Joi.string().required(),
});
22 changes: 22 additions & 0 deletions packages/apps/human-app/server/src/common/enums/job-assignment.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export enum StatusEnum {
ACTIVE = 'ACTIVE',
VALIDATION = 'VALIDATION',
COMPLETED = 'COMPLETED',
EXPIRED = 'EXPIRED',
CANCELED = 'CANCELED',
REJECTED = 'REJECTED',
}

export enum SortOrder {
ASC = 'ASC',
DESC = 'DESC',
}

export enum SortField {
CHAIN_ID = 'chain_id',
JOB_TYPE = 'job_type',
STATUS = 'status',
REWARD_AMOUNT = 'reward_amount',
CREATED_AT = 'created_at',
EXPIRES_AT = 'expires_at',
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { ApiProperty } from '@nestjs/swagger';
import { AutoMap } from '@automapper/classes';
import {
SortField,
SortOrder,
StatusEnum,
} from '../../../common/enums/job-assignment';

export class JobAssignmentDto {
@AutoMap()
@ApiProperty({ example: 'string' })
exchange_oracle_url: string;

@AutoMap()
@ApiProperty({ example: 'string' })
escrow_address: string;

@AutoMap()
@ApiProperty({ example: 0 })
chain_id: number;
}

export class JobAssignmentCommand {
@AutoMap()
exchange_oracle_url: string;
@AutoMap()
escrow_address: string;
@AutoMap()
chain_id: number;
}

export class JobAssignmentData {
@AutoMap()
exchange_oracle_url: string;
@AutoMap()
escrow_address: string;
@AutoMap()
chain_id: number;
}

export class JobAssignmentResponse {
assignment_id: string;
escrow_address: string;
chain_id: number;
job_type: string;
url?: string; //Only for ACTIVE status
status: string;
reward_amount: string;
reward_token: string;
created_at: string;
updated_at?: string; //Only for COMPLETED, EXPIRED, CANCELED and REJECTED status
expires_at: string;
}

export class JobsFetchParamsDto {
@AutoMap()
@ApiProperty({ example: 'string' })
exchange_oracle_url: string;

@AutoMap()
@ApiProperty({ example: 'string', required: false })
assignment_id: string;

@AutoMap()
@ApiProperty({ example: 'string', required: false })
escrow_address: string;

@AutoMap()
@ApiProperty({ example: 0, required: false })
chain_id: number;

@AutoMap()
@ApiProperty({ example: 'job type', required: false })
job_type: string;

@AutoMap()
@ApiProperty({ example: 'ACTIVE', required: false })
status: StatusEnum;

@AutoMap()
@ApiProperty({ example: 5, default: 5, maximum: 10, required: false })
page_size: number;

@AutoMap()
@ApiProperty({ example: 0, default: 0, required: false })
page: number;

@AutoMap()
@ApiProperty({ example: 'ASC', default: 'ASC', required: false })
sort: SortOrder;

@AutoMap()
@ApiProperty({ example: 'created_at', default: 'created_at', required: false })
sort_field: SortField;
}

export class JobsFetchParamsCommand {
@AutoMap()
exchange_oracle_url: string;
@AutoMap()
assignment_id: string;
@AutoMap()
escrow_address: string;
@AutoMap()
chain_id: number;
@AutoMap()
job_type: string;
@AutoMap()
status: StatusEnum;
@AutoMap()
page_size: number;
@AutoMap()
page: number;
@AutoMap()
sort: SortOrder;
@AutoMap()
sort_field: SortField;
}

export class JobsFetchParamsData {
@AutoMap()
exchange_oracle_url: string;
@AutoMap()
assignment_id: string;
@AutoMap()
escrow_address: string;
@AutoMap()
chain_id: number;
@AutoMap()
job_type: string;
@AutoMap()
status: StatusEnum;
@AutoMap()
page_size: number;
@AutoMap()
page: number;
@AutoMap()
sort: SortOrder;
@AutoMap()
sort_field: SortField;
}

export class JobsFetchResponseItem {
assignment_id: string;
escrow_address: string;
chain_id: number;
job_type: string;
url?: string; //Only for ACTIVE status
status: string;
reward_amount: string;
reward_token: string;
created_at: string;
updated_at: string; //Only for VALIDATION, COMPLETED, EXPIRED, CANCELED and REJECTED status
expires_at: string;
}

export class JobsFetchResponse {
data: JobsFetchResponseItem[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import {
Body,
Controller,
Get,
Post,
Query,
UsePipes,
ValidationPipe,
} from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { InjectMapper } from '@automapper/nestjs';
import { Mapper } from '@automapper/core';
import { JobAssignmentService } from './job-assignment.service';
import {
JobAssignmentDto,
JobAssignmentCommand,
JobAssignmentResponse,
JobsFetchParamsDto,
JobsFetchParamsCommand,
JobsFetchResponse,
} from './interfaces/job-assignment.interface';

@Controller()
export class JobAssignmentController {
constructor(
private readonly jobAssignmentService: JobAssignmentService,
@InjectMapper() private readonly mapper: Mapper,
) {}

@ApiTags('Job-Assignment')
@Post('/assignment/job')
@ApiOperation({
summary: 'Request to assign a job to a logged user',
})
@UsePipes(new ValidationPipe())
public async assignJob(
@Body() jobAssignmentDto: JobAssignmentDto,
): Promise<JobAssignmentResponse> {
const jobAssignmentCommand = this.mapper.map(
jobAssignmentDto,
JobAssignmentDto,
JobAssignmentCommand,
);
return this.jobAssignmentService.processJobAssignment(jobAssignmentCommand);
}

@ApiTags('Job-Assignment')
@Get('/assignment/job')
@ApiOperation({
summary: 'Request to get a jobs assigned to a logged user',
})
public async getAssignedJobs(
@Query() jobsAssignmentParamsDto: JobsFetchParamsDto,
): Promise<JobsFetchResponse> {
const jobsAssignmentParamsCommand = this.mapper.map(
jobsAssignmentParamsDto,
JobsFetchParamsDto,
JobsFetchParamsCommand,
);
return this.jobAssignmentService.processGetAssignedJobs(
jobsAssignmentParamsCommand,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { AutomapperProfile, InjectMapper } from '@automapper/nestjs';
import { Injectable } from '@nestjs/common';
import { createMap, Mapper } from '@automapper/core';
import {
JobAssignmentCommand,
JobAssignmentData,
JobAssignmentDto,
JobsFetchParamsCommand,
JobsFetchParamsData,
JobsFetchParamsDto,
} from './interfaces/job-assignment.interface';

@Injectable()
export class JobAssignmentProfile extends AutomapperProfile {
constructor(@InjectMapper() mapper: Mapper) {
super(mapper);
}

override get profile() {
return (mapper: Mapper) => {
createMap(mapper, JobAssignmentDto, JobAssignmentCommand);
createMap(mapper, JobAssignmentCommand, JobAssignmentData);
createMap(mapper, JobsFetchParamsDto, JobsFetchParamsCommand);
createMap(mapper, JobsFetchParamsCommand, JobsFetchParamsData);
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { JobAssignmentService } from './job-assignment.service';
import { JobAssignmentProfile } from './job-assignment.mapper';
import { HttpModule } from '@nestjs/axios';

@Module({
imports: [HttpModule],
providers: [JobAssignmentService, JobAssignmentProfile],
exports: [JobAssignmentService],
})
export class JobAssignmentModule {}
Loading
Loading