From f4200f2a82eda0afaaa5479b61719f6aec0d21c3 Mon Sep 17 00:00:00 2001 From: Methapon2001 <61303214+Methapon2001@users.noreply.github.com> Date: Fri, 5 Sep 2025 13:20:59 +0700 Subject: [PATCH 1/8] feat(ci/cd): add script --- .forgejo/workflows/build.yml | 49 +++++++++++++++++++++++++++++++++++ .forgejo/workflows/deploy.yml | 29 +++++++++++++++++++++ 2 files changed, 78 insertions(+) create mode 100644 .forgejo/workflows/build.yml create mode 100644 .forgejo/workflows/deploy.yml diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml new file mode 100644 index 00000000..ba3556e0 --- /dev/null +++ b/.forgejo/workflows/build.yml @@ -0,0 +1,49 @@ +name: Build + +on: + push: + tags: + - "v[0-9]+.[0-9]+.[0-9]+" + - "v[0-9]+.[0-9]+.[0-9]+*" + workflow_dispatch: + +env: + REGISTRY: ${{ vars.CONTAINER_REGISTRY }} + REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }} + REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} + CONTAINER_IMAGE_NAME: ${{ vars.CONTAINER_REGISTRY }}/${{ vars.CONTAINER_IMAGE_OWNER }}/${{ vars.CONTAINER_IMAGE_NAME }} + IMAGE_VERSION: build + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + with: + config-inline: | + [registry."${{ env.REGISTRY }}"] + ca=["/etc/ssl/certs/ca-certificates.crt"] + - name: Tag Version + run: | + if [[ "${{ github.event_name }}" == "push" ]]; then + echo "IMAGE_VERSION=${{ github.ref_name }}" | sed 's/v//g' >> $GITHUB_ENV + else + echo "IMAGE_VERSION=${{ env.IMAGE_VERSION }}-${{ github.run_number }}" >> $GITHUB_ENV + fi + - name: Login in to registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ env.REGISTRY_USERNAME }} + password: ${{ env.REGISTRY_PASSWORD }} + - name: Build and push docker image + uses: docker/build-push-action@v3 + with: + platforms: linux/amd64 + context: . + file: ./docker/Dockerfile + tags: ${{ env.CONTAINER_IMAGE_NAME }}:latest,${{ env.CONTAINER_IMAGE_NAME }}:${{ env.IMAGE_VERSION }} + push: true diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml new file mode 100644 index 00000000..0dc28bce --- /dev/null +++ b/.forgejo/workflows/deploy.yml @@ -0,0 +1,29 @@ +name: Build + +on: + workflow_dispatch: + inputs: + version: + description: "Version to deploy" + type: string + required: false + default: "latest" + +env: + IMAGE_VERSION: build + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - name: Remote Deploy + uses: appleboy/ssh-action@v1.2.1 + with: + host: ${{ vars.SSH_DEPLOY_HOST }} + port: ${{ vars.SSH_DEPLOY_PORT }} + username: ${{ secrets.SSH_DEPLOY_USER }} + password: ${{ secrets.SSH_DEPLOY_PASSWORD }} + script: | + cd ~/repo + ./replace-env.sh API_ORG "${{ inputs.version }}" + ./deploy.sh hrms-api-org From db30910b6c3d9956c269b11c7dc997490f17000d Mon Sep 17 00:00:00 2001 From: AdisakKanthawilang Date: Wed, 10 Sep 2025 11:28:17 +0700 Subject: [PATCH 2/8] update ci-di config --- .forgejo/workflows/ci-cd.yml | 60 ++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 .forgejo/workflows/ci-cd.yml diff --git a/.forgejo/workflows/ci-cd.yml b/.forgejo/workflows/ci-cd.yml new file mode 100644 index 00000000..723dc81b --- /dev/null +++ b/.forgejo/workflows/ci-cd.yml @@ -0,0 +1,60 @@ +name: Build + +on: + push: + tags: + - "dev[0-9]+.[0-9]+.[0-9]+" + - "dev[0-9]+.[0-9]+.[0-9]+*" + workflow_dispatch: + +env: + REGISTRY: ${{ vars.CONTAINER_REGISTRY }} + REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }} + REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} + CONTAINER_IMAGE_NAME: ${{ vars.CONTAINER_REGISTRY }}/${{ vars.CONTAINER_IMAGE_OWNER }}/${{ vars.CONTAINER_IMAGE_NAME }} + IMAGE_VERSION: build + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + with: + config-inline: | + [registry."${{ env.REGISTRY }}"] + ca=["/etc/ssl/certs/ca-certificates.crt"] + - name: Tag Version + run: | + if [[ "${{ github.event_name }}" == "push" ]]; then + echo "IMAGE_VERSION=${{ github.ref_name }}" | sed 's/dev//g' >> $GITHUB_ENV + else + echo "IMAGE_VERSION=${{ env.IMAGE_VERSION }}-${{ github.run_number }}" >> $GITHUB_ENV + fi + - name: Login in to registry + uses: docker/login-action@v2 + with: + registry: ${{ env.REGISTRY }} + username: ${{ env.REGISTRY_USERNAME }} + password: ${{ env.REGISTRY_PASSWORD }} + - name: Build and push docker image + uses: docker/build-push-action@v3 + with: + platforms: linux/amd64 + context: . + file: ./docker/Dockerfile + tags: ${{ env.CONTAINER_IMAGE_NAME }}:latest,${{ env.CONTAINER_IMAGE_NAME }}:${{ env.IMAGE_VERSION }} + push: true + - name: Remote Deploy + uses: appleboy/ssh-action@v1.2.1 + with: + host: ${{ vars.SSH_DEPLOY_HOST }} + port: ${{ vars.SSH_DEPLOY_PORT }} + username: ${{ secrets.SSH_DEPLOY_USER }} + password: ${{ secrets.SSH_DEPLOY_PASSWORD }} + script: | + cd ~/repo + ./replace-env.sh API_ORG "${{ inputs.version }}" + ./deploy.sh hrms-api-org From 99307abff4172a112ad6f6b407157daac780d9f3 Mon Sep 17 00:00:00 2001 From: forgejo Date: Wed, 10 Sep 2025 11:50:37 +0700 Subject: [PATCH 3/8] Update .forgejo/workflows/ci-cd.yml --- .forgejo/workflows/ci-cd.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/ci-cd.yml b/.forgejo/workflows/ci-cd.yml index 723dc81b..6520416e 100644 --- a/.forgejo/workflows/ci-cd.yml +++ b/.forgejo/workflows/ci-cd.yml @@ -56,5 +56,5 @@ jobs: password: ${{ secrets.SSH_DEPLOY_PASSWORD }} script: | cd ~/repo - ./replace-env.sh API_ORG "${{ inputs.version }}" + ./replace-env.sh API_ORG "${{ env.IMAGE_VERSION }}" ./deploy.sh hrms-api-org From 78f9e9496e8d99e1ec8bb36016f5a604b66058c3 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Tue, 16 Sep 2025 14:02:19 +0700 Subject: [PATCH 4/8] feat: Add Discord Notification --- .forgejo/workflows/ci-cd.yml | 39 +++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/.forgejo/workflows/ci-cd.yml b/.forgejo/workflows/ci-cd.yml index 6520416e..0f913ddc 100644 --- a/.forgejo/workflows/ci-cd.yml +++ b/.forgejo/workflows/ci-cd.yml @@ -1,10 +1,10 @@ -name: Build +# /.forgejo/workflows/ci-cd.yml +name: Build & Deploy on Dev on: push: - tags: - - "dev[0-9]+.[0-9]+.[0-9]+" - - "dev[0-9]+.[0-9]+.[0-9]+*" + branches: + - dev workflow_dispatch: env: @@ -12,7 +12,8 @@ env: REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }} REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} CONTAINER_IMAGE_NAME: ${{ vars.CONTAINER_REGISTRY }}/${{ vars.CONTAINER_IMAGE_OWNER }}/${{ vars.CONTAINER_IMAGE_NAME }} - IMAGE_VERSION: build + IMAGE_VERSION: latest + DISCORD_WEBHOOK: ${{ vars.DISCORD_WEBHOOK }} jobs: build: @@ -28,11 +29,7 @@ jobs: ca=["/etc/ssl/certs/ca-certificates.crt"] - name: Tag Version run: | - if [[ "${{ github.event_name }}" == "push" ]]; then - echo "IMAGE_VERSION=${{ github.ref_name }}" | sed 's/dev//g' >> $GITHUB_ENV - else - echo "IMAGE_VERSION=${{ env.IMAGE_VERSION }}-${{ github.run_number }}" >> $GITHUB_ENV - fi + echo "IMAGE_VERSION=latest" - name: Login in to registry uses: docker/login-action@v2 with: @@ -58,3 +55,25 @@ jobs: cd ~/repo ./replace-env.sh API_ORG "${{ env.IMAGE_VERSION }}" ./deploy.sh hrms-api-org + + - name: Discord Notification + if: always() + run: | + STATUS="${{ job.status == 'success' && '✅ Success' || '❌ Failed' }}" + COLOR="${{ job.status == 'success' && '3066993' || '15158332' }}" + TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) + curl -H "Content-Type: application/json" \ + -X POST \ + -d "{ + \"embeds\": [{ + \"title\": \"$STATUS\", + \"description\": \"**Build & Deploy**\\n- Image: \`${{ env.CONTAINER_IMAGE_NAME }}\`\\n- Version: \`${{ env.IMAGE_VERSION }}\`\\n- By: \`${{ github.actor }}\`\", + \"color\": $COLOR, + \"footer\": { + \"text\": \"Release Notification\", + \"icon_url\": \"https://example.com/success-icon.png\" + }, + \"timestamp\": \"$TIMESTAMP\" + }] + }" \ + ${{ env.DISCORD_WEBHOOK }} From b2fafc68e84e75379163fedcc8405c4432e48a80 Mon Sep 17 00:00:00 2001 From: "DESKTOP-1R2VSQH\\Lenovo ThinkPad E490" Date: Thu, 2 Oct 2025 14:44:12 +0700 Subject: [PATCH 5/8] add retirement --- src/controllers/ExRetirementController.ts | 126 ++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/controllers/ExRetirementController.ts diff --git a/src/controllers/ExRetirementController.ts b/src/controllers/ExRetirementController.ts new file mode 100644 index 00000000..232f9a8c --- /dev/null +++ b/src/controllers/ExRetirementController.ts @@ -0,0 +1,126 @@ +import axios from "axios"; +import { + Controller, + Post, + Delete, + Route, + Security, + Tags, + Body, + Path, + Request, + Response, + Get, +} from "tsoa"; +import HttpError from "../interfaces/http-error"; +import HttpStatusCode from "../interfaces/http-status"; + +interface CachedToken { + token: string; + expiry: Date; +} +const API_URL_BANGKOK = "https://exprofile.bangkok.go.th/API"; +const clientId = "e5f6ad6ce374177eef023bf5d0c018b6"; +const clientSecret = "5EhOvN5DwHOKakupqT9FmCk7MOwpT3zLqLPkPh4ZhJpxBN2nMG@2022"; + +class TokenCache { + private static cache: Map = new Map(); + + static get(key: string): string | null { + const cached = this.cache.get(key); + if (!cached) return null; + return cached.token; + } + + static set(key: string, token: string): void { + this.cache.set(key, { token, expiry: new Date(Date.now() + 50 * 60 * 1000) }); + } + + static delete(key: string): void { + this.cache.delete(key); + } +} + +@Route("api/v1/org/ex/retirement") +@Tags("ExRetirement") +@Security("bearerAuth") +export class ExRetirementController extends Controller { + @Post() + async getExRetirement( + @Body() + requestBody: { + type: string; //ประเภท + retireYear: string; //ปีที่เกษียณ + citizenID: string; //เลขบัตรประชาชน + firstNameTH: string; //ชื่อ + lastNameTH: string; //นามสกุล + page: number; //หน้า + }, + ) { + let retryCount = 0; + const maxRetries = 2; + + while (retryCount < maxRetries) { + try { + const token = await getToken(clientId, clientSecret); + + if (!token) { + throw new HttpError(HttpStatusCode.NOT_FOUND, "ไม่สามารถขอ Token ได้"); + } + + const scope = requestBody.type === "officer" ? "getOfficerRetireData" : ""; + const startRecord = requestBody.page !== 1 ? (requestBody.page - 1) * 25 : 0; + + const formData = new FormData(); + formData.append("scope", scope); + formData.append("startRecord", startRecord.toString()); + formData.append("retireYear", requestBody.retireYear); + formData.append("citizenID", requestBody.citizenID); + formData.append("firstNameTH", requestBody.firstNameTH); + formData.append("lastNameTH", requestBody.lastNameTH); + + const res = await axios.post(API_URL_BANGKOK + "/getData", formData, { + headers: { + Authorization: `Bearer ${token}`, + }, + }); + + return res.data; + } catch (error: any) { + if (error.response?.status === 500 && retryCount < maxRetries - 1) { + TokenCache.delete(`${clientId}:${clientSecret}`); + retryCount++; + continue; + } + throw new HttpError(HttpStatusCode.INTERNAL_SERVER_ERROR, "ไม่สามารถติดต่อ API ได้"); + } + } + } +} + +async function getToken(ClientID: string, ClientSecret: string): Promise { + const cacheKey = `${ClientID}:${ClientSecret}`; + + // ลองหา token ใน cache ก่อน + const cachedToken = TokenCache.get(cacheKey); + if (cachedToken) { + return cachedToken; + } + + // ถ้าไม่มีใน cache ให้ขอใหม่ + try { + const formData = new FormData(); + formData.append("ClientID", ClientID); + formData.append("ClientSecret", ClientSecret); + const res = await axios.post(API_URL_BANGKOK + "/authorize", formData, { + headers: { + "Content-Type": "application/json", + }, + }); + const token = res.data.token; + TokenCache.set(cacheKey, token); + return token; + } catch (error) { + return Promise.reject({ message: "Error occurred", error }); + } +} From 1a1da7b5846cb42e13dcb2a63af8761604ea83c2 Mon Sep 17 00:00:00 2001 From: "Warunee.T" Date: Thu, 2 Oct 2025 14:49:59 +0700 Subject: [PATCH 6/8] Delete .forgejo/workflows/build.yml --- .forgejo/workflows/build.yml | 49 ------------------------------------ 1 file changed, 49 deletions(-) delete mode 100644 .forgejo/workflows/build.yml diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml deleted file mode 100644 index ba3556e0..00000000 --- a/.forgejo/workflows/build.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: Build - -on: - push: - tags: - - "v[0-9]+.[0-9]+.[0-9]+" - - "v[0-9]+.[0-9]+.[0-9]+*" - workflow_dispatch: - -env: - REGISTRY: ${{ vars.CONTAINER_REGISTRY }} - REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }} - REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} - CONTAINER_IMAGE_NAME: ${{ vars.CONTAINER_REGISTRY }}/${{ vars.CONTAINER_IMAGE_OWNER }}/${{ vars.CONTAINER_IMAGE_NAME }} - IMAGE_VERSION: build - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - with: - config-inline: | - [registry."${{ env.REGISTRY }}"] - ca=["/etc/ssl/certs/ca-certificates.crt"] - - name: Tag Version - run: | - if [[ "${{ github.event_name }}" == "push" ]]; then - echo "IMAGE_VERSION=${{ github.ref_name }}" | sed 's/v//g' >> $GITHUB_ENV - else - echo "IMAGE_VERSION=${{ env.IMAGE_VERSION }}-${{ github.run_number }}" >> $GITHUB_ENV - fi - - name: Login in to registry - uses: docker/login-action@v2 - with: - registry: ${{ env.REGISTRY }} - username: ${{ env.REGISTRY_USERNAME }} - password: ${{ env.REGISTRY_PASSWORD }} - - name: Build and push docker image - uses: docker/build-push-action@v3 - with: - platforms: linux/amd64 - context: . - file: ./docker/Dockerfile - tags: ${{ env.CONTAINER_IMAGE_NAME }}:latest,${{ env.CONTAINER_IMAGE_NAME }}:${{ env.IMAGE_VERSION }} - push: true From 58c9833be932cec3d971bd7fb9e44fe451d0b7b6 Mon Sep 17 00:00:00 2001 From: "Warunee.T" Date: Thu, 2 Oct 2025 14:50:25 +0700 Subject: [PATCH 7/8] Delete .forgejo/workflows/ci-cd.yml --- .forgejo/workflows/ci-cd.yml | 79 ------------------------------------ 1 file changed, 79 deletions(-) delete mode 100644 .forgejo/workflows/ci-cd.yml diff --git a/.forgejo/workflows/ci-cd.yml b/.forgejo/workflows/ci-cd.yml deleted file mode 100644 index 0f913ddc..00000000 --- a/.forgejo/workflows/ci-cd.yml +++ /dev/null @@ -1,79 +0,0 @@ -# /.forgejo/workflows/ci-cd.yml -name: Build & Deploy on Dev - -on: - push: - branches: - - dev - workflow_dispatch: - -env: - REGISTRY: ${{ vars.CONTAINER_REGISTRY }} - REGISTRY_USERNAME: ${{ vars.CONTAINER_REGISTRY_USERNAME }} - REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} - CONTAINER_IMAGE_NAME: ${{ vars.CONTAINER_REGISTRY }}/${{ vars.CONTAINER_IMAGE_OWNER }}/${{ vars.CONTAINER_IMAGE_NAME }} - IMAGE_VERSION: latest - DISCORD_WEBHOOK: ${{ vars.DISCORD_WEBHOOK }} - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - with: - config-inline: | - [registry."${{ env.REGISTRY }}"] - ca=["/etc/ssl/certs/ca-certificates.crt"] - - name: Tag Version - run: | - echo "IMAGE_VERSION=latest" - - name: Login in to registry - uses: docker/login-action@v2 - with: - registry: ${{ env.REGISTRY }} - username: ${{ env.REGISTRY_USERNAME }} - password: ${{ env.REGISTRY_PASSWORD }} - - name: Build and push docker image - uses: docker/build-push-action@v3 - with: - platforms: linux/amd64 - context: . - file: ./docker/Dockerfile - tags: ${{ env.CONTAINER_IMAGE_NAME }}:latest,${{ env.CONTAINER_IMAGE_NAME }}:${{ env.IMAGE_VERSION }} - push: true - - name: Remote Deploy - uses: appleboy/ssh-action@v1.2.1 - with: - host: ${{ vars.SSH_DEPLOY_HOST }} - port: ${{ vars.SSH_DEPLOY_PORT }} - username: ${{ secrets.SSH_DEPLOY_USER }} - password: ${{ secrets.SSH_DEPLOY_PASSWORD }} - script: | - cd ~/repo - ./replace-env.sh API_ORG "${{ env.IMAGE_VERSION }}" - ./deploy.sh hrms-api-org - - - name: Discord Notification - if: always() - run: | - STATUS="${{ job.status == 'success' && '✅ Success' || '❌ Failed' }}" - COLOR="${{ job.status == 'success' && '3066993' || '15158332' }}" - TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ) - curl -H "Content-Type: application/json" \ - -X POST \ - -d "{ - \"embeds\": [{ - \"title\": \"$STATUS\", - \"description\": \"**Build & Deploy**\\n- Image: \`${{ env.CONTAINER_IMAGE_NAME }}\`\\n- Version: \`${{ env.IMAGE_VERSION }}\`\\n- By: \`${{ github.actor }}\`\", - \"color\": $COLOR, - \"footer\": { - \"text\": \"Release Notification\", - \"icon_url\": \"https://example.com/success-icon.png\" - }, - \"timestamp\": \"$TIMESTAMP\" - }] - }" \ - ${{ env.DISCORD_WEBHOOK }} From b7a609dc798fa911cd5cc54eaa078b0d1cc77d1a Mon Sep 17 00:00:00 2001 From: "Warunee.T" Date: Thu, 2 Oct 2025 14:50:56 +0700 Subject: [PATCH 8/8] Delete .forgejo/workflows/deploy.yml --- .forgejo/workflows/deploy.yml | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 .forgejo/workflows/deploy.yml diff --git a/.forgejo/workflows/deploy.yml b/.forgejo/workflows/deploy.yml deleted file mode 100644 index 0dc28bce..00000000 --- a/.forgejo/workflows/deploy.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: Build - -on: - workflow_dispatch: - inputs: - version: - description: "Version to deploy" - type: string - required: false - default: "latest" - -env: - IMAGE_VERSION: build - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - name: Remote Deploy - uses: appleboy/ssh-action@v1.2.1 - with: - host: ${{ vars.SSH_DEPLOY_HOST }} - port: ${{ vars.SSH_DEPLOY_PORT }} - username: ${{ secrets.SSH_DEPLOY_USER }} - password: ${{ secrets.SSH_DEPLOY_PASSWORD }} - script: | - cd ~/repo - ./replace-env.sh API_ORG "${{ inputs.version }}" - ./deploy.sh hrms-api-org