Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
17 changes: 17 additions & 0 deletions nest-cli.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,23 @@
"include": "src/playerTasks/playerTasks.json",
"outDir": "dist"
}
],
"plugins": [
{
"name": "@nestjs/swagger",
"options": {
"dtoFileNameSuffix": [".dto.ts", ".schema.ts", "APIError.ts"],
"controllerFileNameSuffix": ".controller.ts",

"dtoKeyOfComment": "description",
"controllerKeyOfComment": "summary",

"classValidatorShim": true,
"introspectComments": true,
"skipAutoHttpCode": true,
"esmCompatible": false
}
}
]
}
}
1 change: 0 additions & 1 deletion src/__tests__/clanShop/clanShopService/buyItem.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,6 @@ describe('ClanShopService.buyItem() test suite', () => {
additional: null,
field: 'gameCoins',
message: 'Clan does not have enough coins to buy the item',
objectType: 'ServiceError',
reason: 'LESS_THAN_MIN',
value: null,
},
Expand Down
147 changes: 144 additions & 3 deletions src/clan/clan.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,17 @@ import { publicReferences } from './clan.schema';
import { RoomService } from '../clanInventory/room/room.service';
import { ItemService } from '../clanInventory/item/item.service';
import { PlayerService } from '../player/player.service';
import { ClanItemsResponseDto } from './join/dto/clanItemsResponse.dto';
import HasClanRights from './role/decorator/guard/HasClanRights';
import { ClanBasicRight } from './role/enum/clanBasicRight.enum';
import DetermineClanId from '../common/guard/clanId.guard';
import { APIError } from '../common/controller/APIError';
import { APIErrorReason } from '../common/controller/APIErrorReason';
import { ApiStandardErrors } from '../common/swagger/response/errors/ApiStandardErrors.decorator';
import { ApiSuccessResponse } from '../common/swagger/response/success/ApiSuccessResponse.decorator';
import ApiResponseDescription from '../common/swagger/response/ApiResponseDescription';
import ClanItemsDto from './dto/clanItems.dto';
import { ApiExtraModels } from '@nestjs/swagger';
import { ItemDto } from '../clanInventory/item/dto/item.dto';

@Controller('clan')
export class ClanController {
Expand All @@ -54,15 +59,49 @@ export class ClanController {
private readonly playerService: PlayerService,
) {}

/**
* Create a new Clan.
*
* @remarks The creator of the Clan becomes its admin.
* Notice that if Player is creating a new Clan, he/she becomes a member of it,
* that means that if Player is member of some Clan it can not create a new one, before leaving the old one.
*
* Also, endpoint creates Clan's Stock, as well as Clan's SoulHome and Rooms.
*
* For the created Clan a set of default Items will be added to Stock and to one of the SoulHome Rooms.
*/
@ApiResponseDescription({
success: {
dto: ClanDto,
status: 201,
modelName: ModelName.CLAN,
},
errors: [400, 401, 403, 409],
})
@Post()
@Authorize({ action: Action.create, subject: ClanDto })
@UniformResponse(ModelName.CLAN)
public async create(@Body() body: CreateClanDto, @LoggedUser() user: User) {
return this.service.createOne(body, user.player_id);
}

/**
* Get items of the logged-in user clan.
*
* @remarks Get items of the logged-in user clan.
*
* Notice that it will return 403 if the logged-in player is not in any clan.
*/
@ApiResponseDescription({
success: {
dto: ClanItemsDto,
modelName: ModelName.ITEM,
},
errors: [401, 403],
})
@ApiExtraModels(ItemDto)
@Get('items')
@UniformResponse(ModelName.ITEM, ClanItemsResponseDto)
@UniformResponse(ModelName.ITEM, ClanItemsDto)
async getClanItems(@LoggedUser() user: User) {
const clanId = await this.playerService.getPlayerClanId(user.player_id);
const [clan, clanErrors] = await this.service.readOneById(clanId, {
Expand All @@ -84,6 +123,19 @@ export class ClanController {
return { stockItems, soulHomeItems };
}

/**
* Get Clan by _id.
*
* @remarks Read Clan data by its _id field
*/
@ApiResponseDescription({
success: {
dto: ClanDto,
modelName: ModelName.CLAN,
},
errors: [400, 404],
hasAuth: false,
})
@Get('/:_id')
@NoAuth()
@UniformResponse(ModelName.CLAN)
Expand All @@ -94,7 +146,26 @@ export class ClanController {
return this.service.readOneById(param._id, { includeRefs });
}

/**
* Read all clans.
*
* @remarks Read all created Clans
*/
@ApiResponseDescription({
success: {
dto: ClanDto,
modelName: ModelName.CLAN,
returnsArray: true,
},
errors: [404],
hasAuth: false,
})
@Get()
@ApiSuccessResponse(ClanDto, {
modelName: ModelName.CLAN,
returnsArray: true,
})
@ApiStandardErrors(404)
@NoAuth()
@UniformResponse(ModelName.CLAN, ClanDto)
@OffsetPaginate(ModelName.CLAN)
Expand All @@ -104,6 +175,19 @@ export class ClanController {
return this.service.readAll(query);
}

/**
* Update a clan
*
* @remarks Update the Clan, which _id is specified in the body.
*
* Notice that the player must be in the same clan and it must have a basic right "Edit clan data"
*/
@ApiResponseDescription({
success: {
status: 204,
},
errors: [400, 401, 403, 404, 409],
})
@Put()
@DetermineClanId()
@HasClanRights([ClanBasicRight.EDIT_CLAN_DATA])
Expand All @@ -121,11 +205,25 @@ export class ClanController {
}),
],
];

const [, errors] = await this.service.updateOneById(body);
if (errors) return [null, errors];
}

/**
* Delete a clan
*
* @remarks Delete Clan its _id field.
*
* Notice that only Clan admins can delete the Clan.
*
* Notice that the player must be in the same clan and it must have a basic right "Edit clan data"
*/
@ApiResponseDescription({
success: {
status: 204,
},
errors: [400, 401, 403, 404],
})
@Delete('/:_id')
@Authorize({ action: Action.delete, subject: UpdateClanDto })
@UniformResponse()
Expand All @@ -134,20 +232,63 @@ export class ClanController {
if (errors) return [null, errors];
}

/**
* Player requests join to clan
*
* @remarks Request to join a Clan.
*
* Notice that if the Clan is open the Player will be joined automatically without admin approval.
*
* Notice that if the Player was in another Clan then he/she will be removed from the old one and if in this Clan was no other Players, it will be removed.
*/
@ApiResponseDescription({
success: {
dto: JoinDto,
modelName: ModelName.JOIN,
status: 201,
},
errors: [400, 401, 403, 404],
})
@Post('join')
@Authorize({ action: Action.create, subject: JoinDto })
@BasicPOST(JoinDto)
public async createJoin(@Body() body: JoinRequestDto) {
return this.joinService.handleJoinRequest(body);
}

/**
* Player requests leave a clan
*
* @remarks Request to leave a Clan.
*
* Notice that Player can leave any Clan without admin approval.
*/
@ApiResponseDescription({
success: {
status: 204,
},
errors: [401, 404],
})
@Post('leave')
@HttpCode(204)
@Authorize({ action: Action.create, subject: PlayerLeaveClanDto })
public leaveClan(@Req() request: Request, @LoggedUser() user: User) {
return this.joinService.leaveClan(user.player_id);
}

/**
* Exclude the player from clan.
*
* @remarks Request exclude the player from clan.
*
* Notice that only Clan admin can remove the Player
*/
@ApiResponseDescription({
success: {
status: 204,
},
errors: [400, 401, 404],
})
@Post('exclude')
@HttpCode(204)
@DetermineClanId()
Expand Down
Loading