Skip to content

Commit d64a67a

Browse files
resolve conflict
2 parents f7877ef + 2f2ac7b commit d64a67a

31 files changed

+867
-72
lines changed

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ DEBUGGER_HTTP_WRITE_INTO_CONSOLE=false
1313
DEBUGGER_SYSTEM_WRITE_INTO_FILE=true
1414
DEBUGGER_SYSTEM_WRITE_INTO_CONSOLE=true
1515

16-
JOB_ENABLE=false
16+
JOB_ENABLE=true
1717

1818
DATABASE_HOST=mongodb://localhost:30001,localhost:30002,localhost:30003
1919
DATABASE_NAME=ack

.github/workflows/cd.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ jobs:
1515
env:
1616
APP_NAME: ${{ github.event.repository.name }}
1717
APP_PORT: 3000
18+
APP_PORT_EXPOSE: 3000
1819
APP_NETWORK: app-network
1920

2021
steps:
@@ -58,7 +59,7 @@ jobs:
5859
docker network create ${{ env.APP_NETWORK }} --driver=bridge
5960
docker run -itd \
6061
--hostname ${{ env.APP_NAME}} \
61-
--publish ${{ env.APP_PORT }}:${{ env.APP_PORT }} \
62+
--publish ${{ env.APP_PORT_EXPOSE }}:${{ env.APP_PORT }} \
6263
--network ${{ env.APP_NETWORK }} \
6364
--volume /app/${{ env.APP_NAME}}/logs/:/app/logs/ \
6465
--volume /app/${{ env.APP_NAME}}/.env:/app/.env \

README.md

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
## Other Repo
2525

2626
* [Mongoose Mini Version][ack-mongoose] : Mini version
27-
* [Typeorm Integration][ack-typeorm] : Mini version with typeorm integration
28-
* [Kafka Integration][ack-kafka] : Integration with Apache Kafka
27+
* [Typeorm Integration][ack-typeorm] : Typeorm integration
28+
* [Kafka Integration][ack-kafka] : Apache Kafka integration
2929

3030
## Table of contents
3131

@@ -88,6 +88,8 @@ Next development
8888
* [x] Fix automation testing
8989
* [x] Pagination move from decorator to service pagination -> make pipe transformer -> wrap into group decorator ResponsePaging
9090
* [x] Check Swagger for pagination
91+
* [x] ApiKey add startDate and endDate
92+
* [x] Make docker port expose be difference with port app
9193
* [ ] SSO
9294
* [ ] Google
9395
* [ ] Apple
@@ -102,13 +104,13 @@ Describes which version.
102104

103105
| Name | Version |
104106
| ---------- | -------- |
105-
| NestJs | v9.1.x |
106-
| NodeJs | v18.4.x |
107-
| Typescript | v4.8.x |
108-
| Mongoose | v6.6.x |
107+
| NestJs | v9.2.x |
108+
| NodeJs | v18.12.x |
109+
| Typescript | v4.9.x |
110+
| Mongoose | v6.8.x |
109111
| MongoDB | v6.0.x |
110112
| Yarn | v1.22.x |
111-
| NPM | v8.12.x |
113+
| NPM | v8.19.x |
112114
| Docker | v20.10.x |
113115
| Docker Compose | v2.6.x |
114116
| Swagger | v6.1.x |
@@ -465,7 +467,6 @@ If your code behind commit with the original, please update your code and resolv
465467

466468
[![Github][github-shield]][author-github]
467469
[![LinkedIn][linkedin-shield]][author-linkedin]
468-
[![Instagram][instagram-shield]][author-instagram]
469470

470471
<!-- BADGE LINKS -->
471472
[ack-contributors-shield]: https://img.shields.io/github/contributors/andrechristikan/ack-nestjs-boilerplate?style=for-the-badge
@@ -485,11 +486,9 @@ If your code behind commit with the original, please update your code and resolv
485486

486487
[github-shield]: https://img.shields.io/badge/GitHub-100000?style=for-the-badge&logo=github&logoColor=white
487488
[linkedin-shield]: https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white
488-
[instagram-shield]: https://img.shields.io/badge/Instagram-E4405F?style=for-the-badge&logo=instagram&logoColor=white
489489

490490
<!-- CONTACTS -->
491491
[author-linkedin]: https://linkedin.com/in/andrechristikan
492-
[author-instagram]: https://www.instagram.com/___ac.k
493492
[author-email]: mailto:[email protected]
494493
[author-github]: https://github.com/andrechristikan
495494

@@ -502,15 +501,14 @@ If your code behind commit with the original, please update your code and resolv
502501
<!-- Other Repo Links -->
503502
[ack]: https://github.com/andrechristikan/ack-nestjs-boilerplate
504503
[ack-typeorm]: https://github.com/andrechristikan/nestjs-boilerplate-typeorm
505-
[ack-mongoose]: https://github.com/andrechristikan/ack-nestjs-boilerplate-kafka
506-
[ack-kafka]: https://github.com/andrechristikan/ack-nestjs-boilerplate-mongoose
504+
[ack-mongoose]: https://github.com/andrechristikan/ack-nestjs-boilerplate-mongoose
505+
[ack-kafka]: https://github.com/andrechristikan/ack-nestjs-boilerplate-kafka
507506

508507
<!-- license -->
509508
[license]: LICENSE.md
510509

511510
<!-- Reference -->
512511
[ref-nestjs]: http://nestjs.com
513-
[ref-nestjs-cqrs]: https://docs.nestjs.com/recipes/cqrs
514512
[ref-mongoose]: https://mongoosejs.com
515513
[ref-mongodb]: https://docs.mongodb.com/
516514
[ref-nodejs]: https://nodejs.org/

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ack-nestjs-boilerplate",
3-
"version": "4.0.3",
3+
"version": "4.1.1",
44
"description": "Ack NestJs Boilerplate",
55
"repository": {
66
"type": "git",

scripts/jenkinsfile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ pipeline {
99
APP_NAME = 'ack' // this will be container name
1010
APP_NETWORK = 'app-network' // this network name
1111
APP_PORT = 3000 // this project will serve in port 0.0.0.0:3000
12+
APP_EXPOSE_PORT = 3000 // this project will expose at port 0.0.0.0:3000
1213

1314
NODE_JS = 'lts' // depends with our jenkins setting
1415

@@ -184,7 +185,7 @@ pipeline {
184185

185186
sshCommand remote: remote, command: "docker run -itd \
186187
--hostname ${APP_NAME} \
187-
--publish ${APP_PORT}:${APP_PORT} \
188+
--publish ${APP_EXPOSE_PORT}:${APP_PORT} \
188189
--network ${APP_NETWORK} \
189190
--volume /app/${APP_NAME}/logs/:/app/logs/ \
190191
--volume /app/${APP_NAME}/.env:/app/.env \

src/common/api-key/constants/api-key.status-code.constant.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ export enum ENUM_API_KEY_STATUS_CODE_ERROR {
22
API_KEY_NEEDED_ERROR = 5120,
33
API_KEY_NOT_FOUND_ERROR = 5121,
44
API_KEY_IS_ACTIVE_ERROR = 5122,
5-
API_KEY_INACTIVE_ERROR = 5123,
6-
API_KEY_INVALID_ERROR = 5124,
7-
API_KEY_WRONG_ERROR = 5125,
5+
API_KEY_EXPIRED_ERROR = 5123,
6+
API_KEY_INACTIVE_ERROR = 5124,
7+
API_KEY_INVALID_ERROR = 5125,
8+
API_KEY_WRONG_ERROR = 5126,
89
}

src/common/api-key/controllers/api-key.admin.controller.ts

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import {
1818
import {
1919
ApiKeyGetGuard,
2020
ApiKeyUpdateActiveGuard,
21+
ApiKeyUpdateGuard,
2122
ApiKeyUpdateInactiveGuard,
2223
ApiKeyUpdateResetGuard,
2324
} from 'src/common/api-key/decorators/api-key.admin.decorator';
@@ -29,9 +30,12 @@ import {
2930
ApiKeyInactiveDoc,
3031
ApiKeyListDoc,
3132
ApiKeyResetDoc,
33+
ApiKeyUpdateDoc,
3234
} from 'src/common/api-key/docs/api-key.admin.doc';
3335
import { ApiKeyCreateDto } from 'src/common/api-key/dtos/api-key.create.dto';
3436
import { ApiKeyRequestDto } from 'src/common/api-key/dtos/api-key.request.dto';
37+
import { ApiKeyUpdateDateDto } from 'src/common/api-key/dtos/api-key.update-date.dto';
38+
import { ApiKeyUpdateNameDto } from 'src/common/api-key/dtos/api-key.update-name.dto';
3539
import { IApiKeyEntity } from 'src/common/api-key/interfaces/api-key.interface';
3640
import { ApiKeyEntity } from 'src/common/api-key/repository/entities/api-key.entity';
3741
import { ApiKeyCreateSerialization } from 'src/common/api-key/serializations/api-key.create.serialization';
@@ -58,6 +62,7 @@ import {
5862
IResponse,
5963
IResponsePaging,
6064
} from 'src/common/response/interfaces/response.interface';
65+
import { ResponseIdSerialization } from 'src/common/response/serializations/response.id.serialization';
6166

6267
@ApiTags('admin.apiKey')
6368
@Controller({
@@ -225,7 +230,7 @@ export class ApiKeyAdminController {
225230
ENUM_AUTH_PERMISSIONS.API_KEY_RESET
226231
)
227232
@AuthJwtAdminAccessProtected()
228-
@Put('/update/:apiKey/reset')
233+
@Patch('/update/:apiKey/reset')
229234
async reset(@GetApiKey() apiKey: ApiKeyEntity): Promise<IResponse> {
230235
try {
231236
const updated: IApiKeyEntity = await this.apiKeyService.reset(
@@ -245,4 +250,59 @@ export class ApiKeyAdminController {
245250
});
246251
}
247252
}
253+
254+
@ApiKeyUpdateDoc()
255+
@Response('apiKey.update', { serialization: ResponseIdSerialization })
256+
@ApiKeyUpdateGuard()
257+
@RequestParamGuard(ApiKeyRequestDto)
258+
@AuthPermissionProtected(
259+
ENUM_AUTH_PERMISSIONS.API_KEY_READ,
260+
ENUM_AUTH_PERMISSIONS.API_KEY_UPDATE
261+
)
262+
@AuthJwtAdminAccessProtected()
263+
@Put('/update/:apiKey')
264+
async updateName(
265+
@Body() body: ApiKeyUpdateNameDto,
266+
@GetApiKey() apiKey: ApiKeyEntity
267+
): Promise<IResponse> {
268+
try {
269+
await this.apiKeyService.updateName(apiKey._id, body);
270+
} catch (err: any) {
271+
throw new InternalServerErrorException({
272+
statusCode: ENUM_ERROR_STATUS_CODE_ERROR.ERROR_UNKNOWN,
273+
message: 'http.serverError.internalServerError',
274+
error: err.message,
275+
});
276+
}
277+
278+
return { _id: apiKey._id };
279+
}
280+
281+
@ApiKeyUpdateDoc()
282+
@Response('apiKey.updateDate', { serialization: ResponseIdSerialization })
283+
@ApiKeyUpdateGuard()
284+
@RequestParamGuard(ApiKeyRequestDto)
285+
@AuthPermissionProtected(
286+
ENUM_AUTH_PERMISSIONS.API_KEY_READ,
287+
ENUM_AUTH_PERMISSIONS.API_KEY_UPDATE,
288+
ENUM_AUTH_PERMISSIONS.API_KEY_UPDATE_DATE
289+
)
290+
@AuthJwtAdminAccessProtected()
291+
@Put('/update/:apiKey/date')
292+
async updateDate(
293+
@Body() body: ApiKeyUpdateDateDto,
294+
@GetApiKey() apiKey: ApiKeyEntity
295+
): Promise<IResponse> {
296+
try {
297+
await this.apiKeyService.updateDate(apiKey._id, body);
298+
} catch (err: any) {
299+
throw new InternalServerErrorException({
300+
statusCode: ENUM_ERROR_STATUS_CODE_ERROR.ERROR_UNKNOWN,
301+
message: 'http.serverError.internalServerError',
302+
error: err.message,
303+
});
304+
}
305+
306+
return { _id: apiKey._id };
307+
}
248308
}

src/common/api-key/decorators/api-key.admin.decorator.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { applyDecorators, SetMetadata, UseGuards } from '@nestjs/common';
22
import { API_KEY_ACTIVE_META_KEY } from 'src/common/api-key/constants/api-key.constant';
33
import { ApiKeyActiveGuard } from 'src/common/api-key/guards/api-key.active.guard';
4+
import { ApiKeyExpiredGuard } from 'src/common/api-key/guards/api-key.expired.guard';
45
import { ApiKeyNotFoundGuard } from 'src/common/api-key/guards/api-key.not-found.guard';
56
import { ApiKeyPutToRequestGuard } from 'src/common/api-key/guards/api-key.put-to-request.guard';
67

@@ -10,12 +11,25 @@ export function ApiKeyGetGuard(): MethodDecorator {
1011
);
1112
}
1213

14+
export function ApiKeyUpdateGuard(): MethodDecorator {
15+
return applyDecorators(
16+
UseGuards(
17+
ApiKeyPutToRequestGuard,
18+
ApiKeyNotFoundGuard,
19+
ApiKeyActiveGuard,
20+
ApiKeyExpiredGuard
21+
),
22+
SetMetadata(API_KEY_ACTIVE_META_KEY, [true])
23+
);
24+
}
25+
1326
export function ApiKeyUpdateResetGuard(): MethodDecorator {
1427
return applyDecorators(
1528
UseGuards(
1629
ApiKeyPutToRequestGuard,
1730
ApiKeyNotFoundGuard,
18-
ApiKeyActiveGuard
31+
ApiKeyActiveGuard,
32+
ApiKeyExpiredGuard
1933
),
2034
SetMetadata(API_KEY_ACTIVE_META_KEY, [true])
2135
);
@@ -26,7 +40,8 @@ export function ApiKeyUpdateActiveGuard(): MethodDecorator {
2640
UseGuards(
2741
ApiKeyPutToRequestGuard,
2842
ApiKeyNotFoundGuard,
29-
ApiKeyActiveGuard
43+
ApiKeyActiveGuard,
44+
ApiKeyExpiredGuard
3045
),
3146
SetMetadata(API_KEY_ACTIVE_META_KEY, [false])
3247
);
@@ -37,7 +52,8 @@ export function ApiKeyUpdateInactiveGuard(): MethodDecorator {
3752
UseGuards(
3853
ApiKeyPutToRequestGuard,
3954
ApiKeyNotFoundGuard,
40-
ApiKeyActiveGuard
55+
ApiKeyActiveGuard,
56+
ApiKeyExpiredGuard
4157
),
4258
SetMetadata(API_KEY_ACTIVE_META_KEY, [true])
4359
);

src/common/api-key/docs/api-key.admin.doc.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { ApiKeyCreateSerialization } from 'src/common/api-key/serializations/api
1111
import { ApiKeyGetSerialization } from 'src/common/api-key/serializations/api-key.get.serialization';
1212
import { ApiKeyListSerialization } from 'src/common/api-key/serializations/api-key.list.serialization';
1313
import { Doc, DocPaging } from 'src/common/doc/decorators/doc.decorator';
14+
import { ResponseIdSerialization } from 'src/common/response/serializations/response.id.serialization';
1415

1516
export function ApiKeyListDoc(): MethodDecorator {
1617
return applyDecorators(
@@ -99,3 +100,19 @@ export function ApiKeyResetDoc(): MethodDecorator {
99100
})
100101
);
101102
}
103+
104+
export function ApiKeyUpdateDoc(): MethodDecorator {
105+
return applyDecorators(
106+
Doc<ResponseIdSerialization>('apiKey.update', {
107+
auth: {
108+
jwtAccessToken: true,
109+
},
110+
request: {
111+
params: ApiKeyDocParamsGet,
112+
},
113+
response: {
114+
serialization: ResponseIdSerialization,
115+
},
116+
})
117+
);
118+
}

src/common/api-key/dtos/api-key.create.dto.ts

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
1+
import { faker } from '@faker-js/faker';
12
import { ApiProperty, PartialType } from '@nestjs/swagger';
2-
import { IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';
3+
import { Type } from 'class-transformer';
4+
import {
5+
IsDate,
6+
IsNotEmpty,
7+
IsOptional,
8+
IsString,
9+
MaxLength,
10+
} from 'class-validator';
311

412
export class ApiKeyCreateDto {
513
@ApiProperty({
@@ -12,6 +20,28 @@ export class ApiKeyCreateDto {
1220
@MaxLength(50)
1321
name: string;
1422

23+
@ApiProperty({
24+
description: 'Api Key start date',
25+
example: faker.date.recent(),
26+
required: false,
27+
nullable: true,
28+
})
29+
@IsOptional()
30+
@Type(() => Date)
31+
@IsDate()
32+
startDate?: Date;
33+
34+
@ApiProperty({
35+
description: 'Api Key end date',
36+
example: faker.date.recent(),
37+
required: false,
38+
nullable: true,
39+
})
40+
@IsOptional()
41+
@Type(() => Date)
42+
@IsDate()
43+
endDate?: Date;
44+
1545
@ApiProperty({
1646
description: 'Description of api key',
1747
example: 'blabla description',

0 commit comments

Comments
 (0)