diff --git a/ReadMe.md b/ReadMe.md index db70d5c..7524f5d 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -4,6 +4,15 @@ [![Deploy to Production environment](https://github.com/kaiyuanshe/KYS-service/actions/workflows/deploy-production.yml/badge.svg)][2] +## Technology stack + +1. HTTP server: [Koa][3] +2. Controller framework: [Routing Controllers][4] +3. Model framework: [Class Transformer][5] & [Class Validator][6] +4. ORM framework: [TypeORM][7] +5. API document: [Swagger][8] +6. Mock API: [OpenAPI backend][9] + ## API Usage ### Production environment @@ -14,7 +23,7 @@ https://service.kaiyuanshe.cn/docs/ #### Sign in GitHub packages with NPM -1. Generate a [PAT][3] with `read:packages` authorization +1. Generate a [PAT][10] with `read:packages` authorization 2. Run Sign-in command in your terminal: ```shell @@ -29,6 +38,17 @@ npm i pnpm -g pnpm i @kaiyuanshe/kys-service ``` +## Environment variables + +| Name | Usage | +| :---------------------: | :---------------------------------------: | +| `DATABASE_URL` | [PostgreSQL][11] connection string | +| `AZURE_BLOB_CONNECTION` | [Azure Blob Storage][12] service | +| `WEB_HOOK_TOKEN` | `Authorization` token of Custom Web hooks | +| `AUTHING_APP_SECRET` | encrypt Password & Token | +| `LARK_APP_ID` | App ID of [Lark API][13] | +| `LARK_APP_SECRET` | App Secret of [Lark API][13] | + ## Development ### Installation @@ -38,30 +58,39 @@ npm i pnpm -g pnpm i ``` -### Start Dev Env +### Start Development environment ```shell pnpm dev ``` -### Database migration +or just press F5 key in [VS Code][14]. + +### Migration ```shell pnpm upgrade:dev -# or -pnpm upgrade:pro ``` -### Build Docker Image +## Deployment + +### Start Production environment + +```shell +npm start +``` + +### Migration ```shell -pnpm dock +pnpm upgrade:pro ``` -### Run Docker Image +### Docker ```shell -pnpm docker +pnpm pack-image +pnpm container ``` ## Releasing @@ -84,4 +113,15 @@ git push origin master --tags [1]: https://kaiyuanshe.cn [2]: https://github.com/kaiyuanshe/KYS-service/actions/workflows/deploy-production.yml -[3]: https://github.com/settings/tokens +[3]: https://koajs.com/ +[4]: https://github.com/typestack/routing-controllers +[5]: https://github.com/typestack/class-transformer +[6]: https://github.com/typestack/class-validator +[7]: https://typeorm.io/ +[8]: https://swagger.io/ +[9]: https://github.com/anttiviljami/openapi-backend +[10]: https://github.com/settings/tokens +[11]: https://www.postgresql.org/ +[12]: https://azure.microsoft.com/en-us/products/storage/blobs +[13]: https://open.feishu.cn/ +[14]: https://code.visualstudio.com/ diff --git a/package.json b/package.json index f346c9b..92c66f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "kys-service", - "version": "0.6.0", + "version": "0.6.1", "license": "AGPL-3.0", "author": "shiy2008@gmail.com", "description": "RESTful API service of KaiYuanShe", @@ -78,7 +78,7 @@ "migration:run": "npm run typeorm -- migration:run", "upgrade:dev": "npm run migration:generate -- migration/version && npm run migration:run", "upgrade:pro": "cross-env NODE_ENV=production npm run migration:generate -- .tmp/version && npm run migration:run", - "dock": "docker build . -t kys-service:latest", - "docker": "docker rm -f kys-service && docker run --name kys-service -p 8080:8080 -d kys-service" + "pack-image": "docker build . -t kys-service:latest", + "container": "docker rm -f kys-service && docker run --name kys-service -p 8080:8080 -d kys-service" } } diff --git a/src/controller/CheckEvent.ts b/src/controller/CheckEvent.ts index 1454b97..b70f8df 100644 --- a/src/controller/CheckEvent.ts +++ b/src/controller/CheckEvent.ts @@ -2,6 +2,7 @@ import { Authorized, Body, CurrentUser, + ForbiddenError, Get, JsonController, Post, @@ -10,9 +11,9 @@ import { import { ResponseSchema } from 'routing-controllers-openapi'; import { - BaseFilter, CheckEvent, CheckEventChunk, + CheckEventFilter, CheckEventInput, User, dataSource @@ -25,7 +26,14 @@ export class CheckEventController { @Post() @Authorized() @ResponseSchema(CheckEvent) - createOne(@CurrentUser() createdBy: User, @Body() data: CheckEventInput) { + async createOne( + @CurrentUser() createdBy: User, + @Body() data: CheckEventInput + ) { + const oldOne = await this.store.find({ where: { createdBy, ...data } }); + + if (oldOne) throw new ForbiddenError('No duplicated check'); + return this.store.save({ ...data, createdBy }); } @@ -34,10 +42,11 @@ export class CheckEventController { @ResponseSchema(CheckEventChunk) async getSessionList( @CurrentUser() createdBy: User, - @QueryParams() { pageSize, pageIndex }: BaseFilter + @QueryParams() + { activityId, agendaId, pageSize, pageIndex }: CheckEventFilter ) { const [list, count] = await this.store.findAndCount({ - where: { createdBy }, + where: { createdBy, activityId, agendaId }, skip: pageSize * (pageIndex - 1), take: pageSize }); diff --git a/src/model/CheckEvent.ts b/src/model/CheckEvent.ts index e36b895..cf52993 100644 --- a/src/model/CheckEvent.ts +++ b/src/model/CheckEvent.ts @@ -9,7 +9,7 @@ import { } from 'class-validator'; import { Column, Entity } from 'typeorm'; -import { ListChunk } from './Base'; +import { BaseFilter, ListChunk } from './Base'; import { UserBase, UserInputData } from './User'; @Entity() @@ -54,6 +54,19 @@ export class CheckEventInput implements UserInputData { agendaTitle: string; } +export class CheckEventFilter + extends BaseFilter + implements Partial +{ + @IsString() + @IsOptional() + activityId?: string; + + @IsString() + @IsOptional() + agendaId?: string; +} + export class CheckEventChunk implements ListChunk { @IsInt() @Min(0) diff --git a/type/package.json b/type/package.json index c9151bb..a1237bf 100644 --- a/type/package.json +++ b/type/package.json @@ -1,6 +1,6 @@ { "name": "@kaiyuanshe/kys-service", - "version": "0.6.0", + "version": "0.6.1", "types": "index.d.ts", "dependencies": { "@types/jsonwebtoken": "^9.0.3",