feat: backend rebuild

This commit is contained in:
admin
2025-10-11 09:24:40 +07:00
parent 360ab1ac12
commit 15145260f9
19 changed files with 92 additions and 71 deletions

3
.gitignore vendored
View File

@@ -5,9 +5,12 @@
Documents/
mariadb/data/
n8n*/
n8n-postgres/
npm/
phpmyadmin/
pgadmin/
.tmp.driveupload
.qsync
# =====================================================
# IDE/Editor settings
# =====================================================

View File

@@ -0,0 +1,29 @@
# Backend build
## วิธีสร้าง package-lock.json ด้วย Docker
### 1. เช็ค uid:gid ของโฟลเดอร์โปรเจกต์บน QNAP
stat -c "%u:%g" .
### 2. ใช้ค่าที่ได้มาแทน UID:GID
```bash
docker run --rm \
-v "/share/Container/dms/frontend:/app" -w /app \
--user UID:GID -e HOME=/tmp \
node:20-alpine sh -lc 'mkdir -p /tmp && npm install --package-lock-only --ignore-scripts'
```
สร้าง package-lock.json โดย ไม่ติดตั้ง node_modules
--user $(id -u):$(id -g) ทำให้ไฟล์ที่ได้เป็นเจ้าของโดยยูสเซอร์ปัจจุบัน (กันปัญหา root-owned)
## ขั้นตอน Build บน QNAP
docker compose -f docker-backend-build.yml build --no-cache 2>&1 | tee backend_build.log
## สำหรับ build local
cd backend
docker build -t dms-backend:dev --target dev .

View File

View File

@@ -1,8 +1,11 @@
.git
.vscode
.backup
node_modules
logs
*.log
Dockerfile*
Dockerfile*.*
*.yml
README*.md
coverage
tmp

15
backend/.eslintrc.json Normal file
View File

@@ -0,0 +1,15 @@
{
"env": {
"node": true,
"es2021": true,
"jest": true
},
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"prettier/prettier": "warn"
}
}

7
backend/.prettierrc.json Normal file
View File

@@ -0,0 +1,7 @@
{
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"arrowParens": "always",
"printWidth": 80
}

View File

@@ -67,3 +67,4 @@ EXPOSE 3001
HEALTHCHECK --interval=30s --timeout=5s --retries=10 \
CMD wget -qO- http://127.0.0.1:3001/health || exit 1
CMD ["node","src/index.js"]

View File

@@ -51,7 +51,7 @@ services:
JWT_EXPIRES_IN: "12h"
PASSWORD_SALT_ROUNDS: "10"
FRONTEND_ORIGIN: "https://lcbp3.np-dms.work"
CORS_ORIGINS: "https://lcbp3.np-dms.work,http://localhost:3000,http://127.0.0.1:3000"
CORS_ORIGINS: "https://backend.np-dms.work,http://localhost:3000,http://127.0.0.1:3000,https://lcbp3.np-dms.work"
COOKIE_DOMAIN: ".np-dms.work"
RATE_LIMIT_WINDOW_MS: "900000"
RATE_LIMIT_MAX: "200"

View File

@@ -1,6 +1,6 @@
{
"name": "dms-backend",
"version": "0.6.0",
"version": "0.8.0",
"private": true,
"type": "module",
"main": "src/index.js",
@@ -11,7 +11,12 @@
"dev": "nodemon --watch src src/index.js",
"dev:desktop": "node --watch src/index.js",
"start": "node src/index.js",
"lint": "echo 'lint placeholder'",
"lint": "eslint . --ext .js",
"lint:fix": "eslint . --ext .js --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:watch:coverage": "jest --watch --coverage",
"health": "node -e \"fetch('http://localhost:'+ (process.env.BACKEND_PORT||3001) +'/health').then(r=>r.text()).then(console.log).catch(e=>{console.error(e);process.exit(1)})\"",
"postinstall": "node -e \"console.log('Installed dms-backend %s','0.6.0')\""
},
@@ -33,6 +38,12 @@
"winston": "^3.13.0"
},
"devDependencies": {
"nodemon": "^3.1.10"
"nodemon": "^3.1.10",
"eslint": "^8.56.0",
"prettier": "^3.1.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.7.0",
"supertest": "^6.3.4"
}
}

View File

@@ -1,25 +0,0 @@
{
"name": "dms-backend",
"version": "0.5.0",
"private": true,
"type": "module",
"scripts": {
"dev": "node --env-file=../.env src/index.js",
"start": "node src/index.js",
"health": "node -e \"fetch('http://localhost:'+ (process.env.BACKEND_PORT||3001) +'/health').then(r=>r.text()).then(console.log).catch(e=>{console.error(e);process.exit(1)})\""
},
"dependencies": {
"bcrypt": "5.1.1",
"cors": "2.8.5",
"dotenv": "16.4.5",
"express": "4.19.2",
"express-rate-limit": "7.4.0",
"helmet": "7.1.0",
"jsonwebtoken": "9.0.2",
"mariadb": "3.3.1",
"morgan": "1.10.0",
"sequelize": "6.37.3"
}
}

View File

@@ -1,38 +0,0 @@
{
"name": "dms-backend",
"version": "0.6.0",
"private": true,
"type": "module",
"main": "src/index.js",
"engines": {
"node": ">=20.0.0"
},
"scripts": {
"dev": "nodemon --watch src src/index.js",
"start": "node src/index.js",
"lint": "echo 'lint placeholder'",
"health": "node -e \"fetch('http://localhost:'+ (process.env.BACKEND_PORT||3001) +'/health').then(r=>r.text()).then(console.log).catch(e=>{console.error(e);process.exit(1)})\"",
"postinstall": "node -e \"console.log('Installed dms-backend %s','0.6.0')\""
},
"dependencies": {
"bcrypt": "5.1.1",
"bcryptjs": "^2.4.3",
"cookie-parser": "^1.4.7",
"cors": "2.8.5",
"dotenv": "16.4.5",
"express": "^4.21.2",
"express-rate-limit": "7.4.0",
"helmet": "7.1.0",
"jsonwebtoken": "9.0.2",
"mariadb": "3.3.1",
"morgan": "^1.10.1",
"multer": "^2.0.2",
"mysql2": "^3.11.0",
"sequelize": "6.37.3",
"winston": "^3.13.0"
},
"devDependencies": {
"nodemon": "^3.1.10"
}
}

View File

@@ -0,0 +1,15 @@
import app from "../src/index.js"; // สมมติว่าคุณ export app จาก src/index.js
import request from "supertest";
// ปิด server หลังจากเทสเสร็จ
afterAll((done) => {
app.server.close(done);
});
describe("GET /health", () => {
it("should respond with 200 OK and a health message", async () => {
const response = await request(app).get("/health");
expect(response.statusCode).toBe(200);
expect(response.text).toContain("Backend is healthy");
});
});

View File

@@ -16,7 +16,7 @@ services:
target: prod
image: dms-backend:prod
command: ["true"]
# docker compose -f docker-backend-build.yml build --no-cache
# docker compose -f docker-backend-build.yml build --no-cache 2>&1 | tee backend_build.log
# ***** สำหรับ build บน server เอา ## ออก *****
# สำหรับ build บน local
# cd backend