Skip to content

Commit

Permalink
Add Swagger documentation for locking (#1304)
Browse files Browse the repository at this point in the history
This adds the Swagger documentation for the locking-relevant endpoints.
  • Loading branch information
iamacook committed Mar 15, 2024
1 parent 9a8188b commit 5b0f867
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 16 deletions.
17 changes: 8 additions & 9 deletions src/domain/locking/entities/__tests__/locking-event.builder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { Builder, IBuilder } from '@/__tests__/builder';
import {
LockEventItem,
UnlockEventItem,
WithdrawEventItem,
} from '@/domain/locking/entities/locking-event.entity';
import {
LockEventItemSchema,
LockingEventType,
Expand All @@ -9,9 +14,7 @@ import { faker } from '@faker-js/faker';
import { Hex, getAddress } from 'viem';
import { z } from 'zod';

export function lockEventItemBuilder(): IBuilder<
z.infer<typeof LockEventItemSchema>
> {
export function lockEventItemBuilder(): IBuilder<LockEventItem> {
return new Builder<z.infer<typeof LockEventItemSchema>>()
.with('eventType', LockingEventType.LOCKED)
.with('executionDate', faker.date.recent())
Expand All @@ -21,9 +24,7 @@ export function lockEventItemBuilder(): IBuilder<
.with('logIndex', faker.string.numeric());
}

export function unlockEventItemBuilder(): IBuilder<
z.infer<typeof UnlockEventItemSchema>
> {
export function unlockEventItemBuilder(): IBuilder<UnlockEventItem> {
return new Builder<z.infer<typeof UnlockEventItemSchema>>()
.with('eventType', LockingEventType.UNLOCKED)
.with('executionDate', faker.date.recent())
Expand All @@ -34,9 +35,7 @@ export function unlockEventItemBuilder(): IBuilder<
.with('logIndex', faker.string.numeric());
}

export function withdrawEventItemBuilder(): IBuilder<
z.infer<typeof WithdrawEventItemSchema>
> {
export function withdrawEventItemBuilder(): IBuilder<WithdrawEventItem> {
return new Builder<z.infer<typeof WithdrawEventItemSchema>>()
.with('eventType', LockingEventType.WITHDRAWN)
.with('executionDate', faker.date.recent())
Expand Down
13 changes: 12 additions & 1 deletion src/domain/locking/entities/locking-event.entity.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
import { LockingEventSchema } from '@/domain/locking/entities/schemas/locking-event.schema';
import {
LockEventItemSchema,
LockingEventSchema,
UnlockEventItemSchema,
WithdrawEventItemSchema,
} from '@/domain/locking/entities/schemas/locking-event.schema';
import { z } from 'zod';

export type LockEventItem = z.infer<typeof LockEventItemSchema>;

export type UnlockEventItem = z.infer<typeof UnlockEventItemSchema>;

export type WithdrawEventItem = z.infer<typeof WithdrawEventItemSchema>;

export type LockingEvent = z.infer<typeof LockingEventSchema>;
74 changes: 74 additions & 0 deletions src/routes/locking/entities/locking-event.page.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import {
LockEventItem as DomainLockEventItem,
UnlockEventItem as DomainUnlockEventItem,
WithdrawEventItem as DomainWithdrawEventItem,
} from '@/domain/locking/entities/locking-event.entity';
import { LockingEventType } from '@/domain/locking/entities/schemas/locking-event.schema';
import { Page } from '@/routes/common/entities/page.entity';
import { ApiExtraModels, ApiProperty, getSchemaPath } from '@nestjs/swagger';

class LockEventItem implements DomainLockEventItem {
@ApiProperty({ enum: [LockingEventType.LOCKED] })
eventType!: LockingEventType.LOCKED;
@ApiProperty({ type: String })
executionDate!: Date;
@ApiProperty()
transactionHash!: `0x${string}`;
@ApiProperty()
holder!: `0x${string}`;
@ApiProperty()
amount!: string;
@ApiProperty()
logIndex!: string;
}

class UnlockEventItem implements DomainUnlockEventItem {
@ApiProperty({ enum: [LockingEventType.UNLOCKED] })
eventType!: LockingEventType.UNLOCKED;
@ApiProperty({ type: String })
executionDate!: Date;
@ApiProperty()
transactionHash!: `0x${string}`;
@ApiProperty()
holder!: `0x${string}`;
@ApiProperty()
amount!: string;
@ApiProperty()
logIndex!: string;
@ApiProperty()
unlockIndex!: string;
}

class WithdrawEventItem implements DomainWithdrawEventItem {
@ApiProperty({ enum: [LockingEventType.WITHDRAWN] })
eventType!: LockingEventType.WITHDRAWN;
@ApiProperty({ type: String })
executionDate!: Date;
@ApiProperty()
transactionHash!: `0x${string}`;
@ApiProperty()
holder!: `0x${string}`;
@ApiProperty()
amount!: string;
@ApiProperty()
logIndex!: string;
@ApiProperty()
unlockIndex!: string;
}

@ApiExtraModels(LockEventItem, UnlockEventItem, WithdrawEventItem)
export class LockingEventPage extends Page<
DomainLockEventItem | DomainUnlockEventItem | DomainWithdrawEventItem
> {
@ApiProperty({
isArray: true,
oneOf: [
{ $ref: getSchemaPath(LockEventItem) },
{ $ref: getSchemaPath(UnlockEventItem) },
{ $ref: getSchemaPath(WithdrawEventItem) },
],
})
results!: Array<
DomainLockEventItem | DomainUnlockEventItem | DomainWithdrawEventItem
>;
}
15 changes: 15 additions & 0 deletions src/routes/locking/entities/rank.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Rank as DomainRank } from '@/domain/locking/entities/rank.entity';
import { ApiProperty } from '@nestjs/swagger';

export class Rank implements DomainRank {
@ApiProperty()
holder!: `0x${string}`;
@ApiProperty()
position!: string;
@ApiProperty()
lockedAmount!: string;
@ApiProperty()
unlockedAmount!: string;
@ApiProperty()
withdrawnAmount!: string;
}
8 changes: 8 additions & 0 deletions src/routes/locking/entities/rank.page.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { ApiProperty } from '@nestjs/swagger';
import { Page } from '@/routes/common/entities/page.entity';
import { Rank } from '@/routes/locking/entities/rank.entity';

export class RankPage extends Page<Rank> {
@ApiProperty({ type: Rank })
results!: Array<Rank>;
}
25 changes: 19 additions & 6 deletions src/routes/locking/locking.controller.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { LockingEvent } from '@/domain/locking/entities/locking-event.entity';
import { Rank } from '@/domain/locking/entities/rank.entity';
import { LockingEventPage } from '@/routes/locking/entities/locking-event.page.entity';
import { Rank } from '@/routes/locking/entities/rank.entity';
import { PaginationDataDecorator } from '@/routes/common/decorators/pagination.data.decorator';
import { RouteUrlDecorator } from '@/routes/common/decorators/route.url.decorator';
import { Page } from '@/routes/common/entities/page.entity';
import { RankPage } from '@/routes/locking/entities/rank.page.entity';
import { PaginationData } from '@/routes/common/pagination/pagination.data';
import { LockingService } from '@/routes/locking/locking.service';
import { AddressSchema } from '@/validation/entities/schemas/address.schema';
import { ValidationPipe } from '@/validation/pipes/validation.pipe';
import { Controller, Get, Param } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';
import { ApiOkResponse, ApiQuery, ApiTags } from '@nestjs/swagger';
import { z } from 'zod';

@ApiTags('locking')
Expand All @@ -19,6 +19,7 @@ import { z } from 'zod';
export class LockingController {
constructor(private readonly lockingService: LockingService) {}

@ApiOkResponse({ type: Rank })
@Get('/leaderboard/:safeAddress')
async getRank(
@Param('safeAddress', new ValidationPipe(AddressSchema))
Expand All @@ -27,21 +28,33 @@ export class LockingController {
return this.lockingService.getRank(safeAddress);
}

@ApiOkResponse({ type: RankPage })
@ApiQuery({
name: 'cursor',
required: false,
type: String,
})
@Get('/leaderboard')
async getLeaderboard(
@RouteUrlDecorator() routeUrl: URL,
@PaginationDataDecorator() paginationData: PaginationData,
): Promise<Page<Rank>> {
): Promise<RankPage> {
return this.lockingService.getLeaderboard({ routeUrl, paginationData });
}

@ApiOkResponse({ type: LockingEventPage })
@ApiQuery({
name: 'cursor',
required: false,
type: String,
})
@Get('/:safeAddress/history')
async getLockingHistory(
@Param('safeAddress', new ValidationPipe(AddressSchema))
safeAddress: z.infer<typeof AddressSchema>,
@RouteUrlDecorator() routeUrl: URL,
@PaginationDataDecorator() paginationData: PaginationData,
): Promise<Page<LockingEvent>> {
): Promise<LockingEventPage> {
return this.lockingService.getLockingHistory({
safeAddress,
routeUrl,
Expand Down

0 comments on commit 5b0f867

Please sign in to comment.