Improvement #172
Updated by Papassorn Phopong (Pipe) 14 days ago
# Bff
* [x] 3000 = main (new) พี่ไปร์ท
* [ ] 3001 = masterdata
* [ ] 3002 = jobpost
* [ ] 3003 = candidates
* [ ] 3004 = users
# Process
* [ ] 4002 = jobpost พี่ไปร์ท
* [ ] 4003 = candidates พี่ไปร์ท
* [ ] 4006 = jobapplication พี่ไปร์ท
* [ ] 4007 = batch พี่ไปร์ท
# System
* [ ] 5001 = masterdata พี่ไปร์ท
* [x] 5002 = jobpost พี่ไปร์ท
* [ ] 5003 = candidates พี่เจ
* [x] 5004 = users พี่ไปร์ท
* [ ] 5005 = document พี่ไปร์ท
* [ ] 5006 = jobapplication พี่เจ
* [ ] 5007 = batch พี่เจ
* [ ] 5008 = candidate-consumer พี่เจ
* [ ] 5009 = complete-candidate-consumer ก้อง
* [ ] 5010 = recruit-dlq-consumer ก้อง
* [ ] 5011 = job-appointment ก้อง
* [ ] 5012 = notification ก้อง
* [ ] xxxx = hrr-system-create-jobpost-consumer พี่ไปร์ท
* [ ] xxxx = hrr-system-create-candidate-consumer พี่ไปร์ท
==================
### Dockerfile please backup name (Dockerfile.backup)
### Dockerfile
```
# ----------------------------------------------------
# Stage 1: Build the Application
# ----------------------------------------------------
FROM node:24.11.0-alpine3.22 AS builder
# Install build dependencies in a single layer
RUN apk update && \
apk add --no-cache \
tzdata \
busybox-extras \
openssl \
libssl3 \
libc6-compat && \
cp /usr/share/zoneinfo/Asia/Bangkok /etc/localtime && \
rm -rf /var/cache/apk/*
WORKDIR /app
# Copy package files for dependency installation
COPY package*.json ./
# Install all dependencies (including devDependencies for build)
RUN npm install && \
npm cache clean --force
# Copy source code
COPY . .
# Build application
RUN npm run build
# ----------------------------------------------------
# Stage 2: Production Image (Minimal & Secure)
# ----------------------------------------------------
FROM node:24.11.0-alpine3.22 AS production
# Install runtime dependencies
RUN apk update && \
apk add --no-cache \
tzdata \
openssl \
libssl3 \
libc6-compat \
dumb-init && \
cp /usr/share/zoneinfo/Asia/Bangkok /etc/localtime && \
rm -rf /var/cache/apk/*
WORKDIR /app
# Set NODE_ENV
ARG NODE_ENV=prod
ENV NODE_ENV=${NODE_ENV}
# Copy package files
COPY --from=builder /app/package*.json ./
# Install production dependencies only
RUN npm install --omit=dev && \
npm cache clean --force
# Copy compiled application
COPY --from=builder /app/dist/src ./dist
COPY --from=builder /app/dist/config ./config
COPY --from=builder /app/env ./env
# Set ownership
RUN chown -R node:node /app
# Use non-root user
USER node
# Set port configuration
ARG APPLICATION_PORT=80
ENV PORT=${APPLICATION_PORT}
EXPOSE ${APPLICATION_PORT}
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD node -e "require('http').get('http://localhost:' + process.env.PORT + '/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"
# Use dumb-init for proper signal handling
CMD ["dumb-init", "node", "dist/main"]
```
# package.json
## เพิ่ม
```
"start:pre": "cross-env NODE_ENV=pre nest start",
```
# config/env.ts
## แก้เป็น
```
export enum ENV {
DEV = "dev",
UAT = "uat",
SIT = "sit",
PROD = "prod",
PRE = "pre",
}
```
# env.dev
## ลบ prefix ให้เป็นตามในตัวอย่าง
```
SYSTEM_JOB_POST_BASE_URL=http://localhost:5002/v1
```
# env.uat
## แก้ port=80
## แก้ตาม prefix ให้ตรงตามตัวอย่าง
```
SYSTEM_JOB_POST_BASE_URL=http://hrr-system-jobpost-svc.development.svc.cluster.local
```
# env.sit
## copy env.uat มาเป็นตัวตั้งและเปลี่ยน NODE_ENV=sit
# env.pre
## copy env.uat มาเป็นตัวตั้งและเปลี่ยน NODE_ENV=pre
# env.prod
## copy env.uat มาเป็นตัวตั้งและเปลี่ยน NODE_ENV=prod
# main.ts
## enableCors ตามตัวอย่าง
```javascript
app.enableCors({
origin: CORS_ORIGIN,
credentials: false,
methods: ["GET", "POST", "OPTIONS"],
allowedHeaders: [
"Content-Type",
"Authorization",
"X-Request-ID",
"sender",
"refer",
"forward",
"senddate",
"clientid",
],
exposedHeaders: ["X-Request-ID"],
});
```
## ลบ
```
app.setGlobalPrefix(`${API_PREFIX}/${API_VERSION}`);
```
## เพิ่ม
```javascript
// Enable API versioning
app.enableVersioning({
type: VersioningType.URI,
defaultVersion: "1",
prefix: "v",
});
```
# modules/health/controllers/health.controller.ts
## แก้ตามตัวอย่างทั้งไฟล์
```javascript
import { Controller, Get, VERSION_NEUTRAL } from "@nestjs/common";
import { SkipEnvelope } from "@shared/http/skip-envelope.decorator";
@Controller({ version: VERSION_NEUTRAL })
export class HealthController {
@Get("health")
@SkipEnvelope()
health(): { status: string } {
return { status: "ok" };
}
@Get("alive")
@SkipEnvelope()
alive(): { status: string } {
return { status: "ok" };
}
}
```
# ถ้าไม่มีไฟล์ @shared/http/skip-envelope.decorator.ts ให้เพิ่ม
``` javascript
import { SetMetadata } from "@nestjs/common";
export const SKIP_ENVELOPE_KEY = "skipEnvelope";
export const SkipEnvelope = () => SetMetadata(SKIP_ENVELOPE_KEY, true);
```