diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..4c2459314cebc9be95199ca7b1f850985371d119
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,3 @@
+node_modules
+dist
+.env.local
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f94630c5927fb227c3b6544afbd8f8163149dc69..be863f261ef0afe2e22304795751351582853359 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,25 @@
+# Node.js
 node_modules/
 dist/
-.env
\ No newline at end of file
+*.log
+*.tsbuildinfo
+
+# Docker
+.docker/
+docker-compose.override.yml
+docker-compose.prod.yml
+
+# .env files (สำคัญที่สุด!)
+.env
+.env.local
+.env.docker
+.env.production
+
+# IDE & OS files
+.vscode/
+.idea/
+*.swp
+.DS_Store
+
+# NPM package-lock.json files (จะ add หรือ commit ขึ้นอยู่กับสถานการณ์)
+package-lock.json
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b2e0b90125d653bbe53840d742824b0eb29ca841
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,49 @@
+services:
+  nestjs:
+    build:
+      context: .  # ✅ ชี้ไปยังโฟลเดอร์ที่มี package.json และ Dockerfile
+      dockerfile: Dockerfile
+    container_name: LOOKOAD_NestJS
+    ports:
+      - "8012:4000"
+    environment:
+      NODE_ENV: docker
+      DB_HOST: mysql
+      DB_PORT: 3306
+      DB_USERNAME: root
+      DB_PASSWORD: Lookoad2024!
+      DB_NAME: water
+    depends_on:
+      - mysql
+    restart: always
+
+  mysql:
+    image: mysql:8.0
+    container_name: lookoad-mysql
+    environment:
+      MYSQL_ROOT_PASSWORD: Lookoad2024!
+      MYSQL_DATABASE: water
+    volumes:
+      - mysql_data:/var/lib/mysql
+    restart: always
+    healthcheck:
+      test: ["CMD", "mysqladmin", "ping", "--silent"]
+      interval: 10s
+      retries: 5
+      start_period: 30s
+      timeout: 20s
+
+  phpmyadmin:
+    image: phpmyadmin/phpmyadmin
+    container_name: LOOKOAD_Phpmyadmin
+    ports:
+      - "8014:80"
+    environment:
+      PMA_HOST: mysql
+      MYSQL_ROOT_PASSWORD: Lookoad2024!
+    depends_on:
+      - mysql
+    restart: always
+
+volumes:
+  mysql_data:
diff --git a/dockerfile b/dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..23cef4c6af078cb8bfdb870544e418187275e98b
--- /dev/null
+++ b/dockerfile
@@ -0,0 +1,20 @@
+FROM node:18 AS builder
+WORKDIR /app
+
+COPY package*.json ./
+RUN npm install
+
+COPY . .
+RUN npm run build
+
+FROM node:18
+WORKDIR /app
+
+COPY --from=builder /app/dist ./dist
+COPY --from=builder /app/node_modules ./node_modules
+COPY --from=builder /app/package*.json ./
+
+EXPOSE 4000
+
+# ✅ รันตรง ๆ ด้วย Node ไม่ผ่าน npm
+CMD ["node", "dist/main.js"]
diff --git a/node_modules/.package-lock.json b/node_modules/.package-lock.json
index 41594d94ee8a6b21a3864b2e3b63d275dbaf7848..768931bc9d613a8656f89634126528493a7a6fb1 100644
--- a/node_modules/.package-lock.json
+++ b/node_modules/.package-lock.json
@@ -1719,6 +1719,21 @@
         }
       }
     },
+    "node_modules/@nestjs/config": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.2.tgz",
+      "integrity": "sha512-McMW6EXtpc8+CwTUwFdg6h7dYcBUpH5iUILCclAsa+MbCEvC9ZKu4dCHRlJqALuhjLw97pbQu62l4+wRwGeZqA==",
+      "license": "MIT",
+      "dependencies": {
+        "dotenv": "16.4.7",
+        "dotenv-expand": "12.0.1",
+        "lodash": "4.17.21"
+      },
+      "peerDependencies": {
+        "@nestjs/common": "^10.0.0 || ^11.0.0",
+        "rxjs": "^7.1.0"
+      }
+    },
     "node_modules/@nestjs/core": {
       "version": "10.3.3",
       "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.3.tgz",
@@ -4321,9 +4336,25 @@
       }
     },
     "node_modules/dotenv": {
-      "version": "16.4.5",
-      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
-      "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
+      "version": "16.4.7",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
+      "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://dotenvx.com"
+      }
+    },
+    "node_modules/dotenv-expand": {
+      "version": "12.0.1",
+      "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.1.tgz",
+      "integrity": "sha512-LaKRbou8gt0RNID/9RoI+J2rvXsBRPMV7p+ElHlPhcSARbCPDYcYG2s1TIzAfWv4YSgyY5taidWzzs31lNV3yQ==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "dotenv": "^16.4.5"
+      },
       "engines": {
         "node": ">=12"
       },
diff --git a/node_modules/dotenv/CHANGELOG.md b/node_modules/dotenv/CHANGELOG.md
index e35152ae27046ea41693eb448deecc7efced6c83..e3e40d6e9bc447318b629ce322729df3fda43242 100644
--- a/node_modules/dotenv/CHANGELOG.md
+++ b/node_modules/dotenv/CHANGELOG.md
@@ -2,13 +2,26 @@
 
 All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
 
-## [Unreleased](https://github.com/motdotla/dotenv/compare/v16.4.5...master)
+## [Unreleased](https://github.com/motdotla/dotenv/compare/v16.4.7...master)
+
+## [16.4.7](https://github.com/motdotla/dotenv/compare/v16.4.6...v16.4.7 (2024-12-03)
+
+### Changed
+
+- Ignore `.tap` folder when publishing. (oops, sorry about that everyone. - @motdotla) [#848](https://github.com/motdotla/dotenv/pull/848)
+
+## [16.4.6](https://github.com/motdotla/dotenv/compare/v16.4.5...v16.4.6) (2024-12-02)
+
+### Changed
+
+- Clean up stale dev dependencies [#847](https://github.com/motdotla/dotenv/pull/847)
+- Various README updates clarifying usage and alternative solutions using [dotenvx](https://github.com/dotenvx/dotenvx)
 
 ## [16.4.5](https://github.com/motdotla/dotenv/compare/v16.4.4...v16.4.5) (2024-02-19)
 
 ### Changed
 
-- 🐞 fix recent regression when using `path` option. return to historical behavior: do not attempt to auto find `.env` if `path` set. (regression was introduced in `16.4.3`) [#814](https://github.com/motdotla/dotenv/pull/814)
+- 🐞 Fix recent regression when using `path` option. return to historical behavior: do not attempt to auto find `.env` if `path` set. (regression was introduced in `16.4.3`) [#814](https://github.com/motdotla/dotenv/pull/814)
 
 ## [16.4.4](https://github.com/motdotla/dotenv/compare/v16.4.3...v16.4.4) (2024-02-13)
 
diff --git a/node_modules/dotenv/README.md b/node_modules/dotenv/README.md
index e54075ee764a41ea69028a19db5140bc9446c4ef..3bd511c42f59b9e4381566ae2f5c12e79553a952 100644
--- a/node_modules/dotenv/README.md
+++ b/node_modules/dotenv/README.md
@@ -33,16 +33,6 @@
     <sup>Add Single Sign-On, Multi-Factor Auth, and more, in minutes instead of months.</sup>
   </div>
 </a>
-<br/>
-<a href="https://runalloy.com/?utm_source=github&utm_medium=referral&utm_campaign=1224_dotenv">
-  <div>
-    <img src="https://res.cloudinary.com/dotenv-org/image/upload/c_crop,g_center,h_65,w_290,x_0,y_0/v1704258787/AlloyAutomation-logo_dqin8c.svg" width="370" alt="Alloy Automation">
-  </div>
-  <b>Launch user-facing integrations faster</b>
-  <div>
-    <sup>Easily spin up hundreds of integrations. Sign up free or read our docs first</sup>
-  </div>
-</a>
 <hr>
 </div>
 
@@ -59,7 +49,7 @@ Dotenv is a zero-dependency module that loads environment variables from a `.env
 * [🌱 Install](#-install)
 * [🏗️ Usage (.env)](#%EF%B8%8F-usage)
 * [🌴 Multiple Environments 🆕](#-manage-multiple-environments)
-* [🚀 Deploying (.env.vault) 🆕](#-deploying)
+* [🚀 Deploying (encryption) 🆕](#-deploying)
 * [📚 Examples](#-examples)
 * [📖 Docs](#-documentation)
 * [❓ FAQ](#-faq)
@@ -83,7 +73,7 @@ Or installing with yarn? `yarn add dotenv`
 </div>
 </a>
 
-Create a `.env` file in the root of your project:
+Create a `.env` file in the root of your project (if using a monorepo structure like `apps/backend/app.js`, put it in the root of the folder where your `app.js` process runs):
 
 ```dosini
 S3_BUCKET="YOURS3BUCKET"
@@ -107,6 +97,7 @@ That's it. `process.env` now has the keys and values you defined in your `.env`
 
 ```javascript
 require('dotenv').config()
+// or import 'dotenv/config' if you're using ES6
 
 ...
 
@@ -186,23 +177,41 @@ $ DOTENV_CONFIG_ENCODING=latin1 DOTENV_CONFIG_DEBUG=true node -r dotenv/config y
 
 You need to add the value of another variable in one of your variables? Use [dotenv-expand](https://github.com/motdotla/dotenv-expand).
 
+### Command Substitution
+
+Use [dotenvx](https://github.com/dotenvx/dotenvx) to use command substitution.
+
+Add the output of a command to one of your variables in your .env file.
+
+```ini
+# .env
+DATABASE_URL="postgres://$(whoami)@localhost/my_database"
+```
+```js
+// index.js
+console.log('DATABASE_URL', process.env.DATABASE_URL)
+```
+```sh
+$ dotenvx run --debug -- node index.js
+[dotenvx@0.14.1] injecting env (1) from .env
+DATABASE_URL postgres://yourusername@localhost/my_database
+```
+
 ### Syncing
 
-You need to keep `.env` files in sync between machines, environments, or team members? Use [dotenv-vault](https://github.com/dotenv-org/dotenv-vault).
+You need to keep `.env` files in sync between machines, environments, or team members? Use [dotenvx](https://github.com/dotenvx/dotenvx) to encrypt your `.env` files and safely include them in source control. This still subscribes to the twelve-factor app rules by generating a decryption key separate from code.
 
 ### Multiple Environments
 
-You need to manage your secrets across different environments and apply them as needed? Use a `.env.vault` file with a `DOTENV_KEY`.
+Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate `.env.ci`, `.env.production` files, and more.
 
 ### Deploying
 
-You need to deploy your secrets in a cloud-agnostic manner? Use a `.env.vault` file. See [deploying `.env.vault` files](https://github.com/motdotla/dotenv/tree/master#-deploying).
+You need to deploy your secrets in a cloud-agnostic manner? Use [dotenvx](https://github.com/dotenvx/dotenvx) to generate a private decryption key that is set on your production server.
 
 ## 🌴 Manage Multiple Environments
 
-Use [dotenvx](https://github.com/dotenvx/dotenvx) or [dotenv-vault](https://github.com/dotenv-org/dotenv-vault).
-
-### dotenvx
+Use [dotenvx](https://github.com/dotenvx/dotenvx)
 
 Run any environment locally. Create a `.env.ENVIRONMENT` file and use `--env-file` to load it. It's straightforward, yet flexible.
 
@@ -228,78 +237,23 @@ Hello local
 
 [more environment examples](https://dotenvx.com/docs/quickstart/environments)
 
-### dotenv-vault
-
-Edit your production environment variables.
-
-```bash
-$ npx dotenv-vault open production
-```
-
-Regenerate your `.env.vault` file.
-
-```bash
-$ npx dotenv-vault build
-```
-
-*ℹ️  🔐 Vault Managed vs 💻 Locally Managed: The above example, for brevity's sake, used the 🔐 Vault Managed solution to manage your `.env.vault` file. You can instead use the 💻 Locally Managed solution. [Read more here](https://github.com/dotenv-org/dotenv-vault#how-do-i-use--locally-managed-dotenv-vault). Our vision is that other platforms and orchestration tools adopt the `.env.vault` standard as they did the `.env` standard. We don't expect to be the only ones providing tooling to manage and generate `.env.vault` files.*
-
-<a href="https://github.com/dotenv-org/dotenv-vault#-manage-multiple-environments">Learn more at dotenv-vault: Manage Multiple Environments</a>
-
 ## 🚀 Deploying
 
-Use [dotenvx](https://github.com/dotenvx/dotenvx) or [dotenv-vault](https://github.com/dotenv-org/dotenv-vault).
+Use [dotenvx](https://github.com/dotenvx/dotenvx).
 
-### dotenvx
+Add encryption to your `.env` files with a single command. Pass the `--encrypt` flag.
 
-Encrypt your secrets to a `.env.vault` file and load from it (recommended for production and ci).
-
-```bash
-$ echo "HELLO=World" > .env
-$ echo "HELLO=production" > .env.production
+```
+$ dotenvx set HELLO Production --encrypt -f .env.production
 $ echo "console.log('Hello ' + process.env.HELLO)" > index.js
 
-$ dotenvx encrypt
-[dotenvx][info] encrypted to .env.vault (.env,.env.production)
-[dotenvx][info] keys added to .env.keys (DOTENV_KEY_PRODUCTION,DOTENV_KEY_PRODUCTION)
-
-$ DOTENV_KEY='<dotenv_key_production>' dotenvx run -- node index.js
-[dotenvx][info] loading env (1) from encrypted .env.vault
-Hello production
-^ :-]
+$ DOTENV_PRIVATE_KEY_PRODUCTION="<.env.production private key>" dotenvx run -- node index.js
+[dotenvx] injecting env (2) from .env.production
+Hello Production
 ```
 
 [learn more](https://github.com/dotenvx/dotenvx?tab=readme-ov-file#encryption)
 
-### dotenv-vault
-
-*Note: Requires dotenv >= 16.1.0*
-
-Encrypt your `.env.vault` file.
-
-```bash
-$ npx dotenv-vault build
-```
-
-Fetch your production `DOTENV_KEY`.
-
-```bash
-$ npx dotenv-vault keys production
-```
-
-Set `DOTENV_KEY` on your server.
-
-```bash
-# heroku example
-heroku config:set DOTENV_KEY=dotenv://:key_1234…@dotenvx.com/vault/.env.vault?environment=production
-```
-
-That's it! On deploy, your `.env.vault` file will be decrypted and its secrets injected as environment variables – just in time.
-
-*ℹ️ A note from [Mot](https://github.com/motdotla): Until recently, we did not have an opinion on how and where to store your secrets in production. We now strongly recommend generating a `.env.vault` file. It's the best way to prevent your secrets from being scattered across multiple servers and cloud providers – protecting you from breaches like the [CircleCI breach](https://techcrunch.com/2023/01/05/circleci-breach/). Also it unlocks interoperability WITHOUT native third-party integrations. Third-party integrations are [increasingly risky](https://coderpad.io/blog/development/heroku-github-breach/) to our industry. They may be the 'du jour' of today, but we imagine a better future.*
-
-<a href="https://github.com/dotenv-org/dotenv-vault#-deploying">Learn more at dotenv-vault: Deploying</a>
-
 ## 📚 Examples
 
 See [examples](https://github.com/dotenv-org/examples) of using dotenv with various frameworks, languages, and configurations.
@@ -308,7 +262,6 @@ See [examples](https://github.com/dotenv-org/examples) of using dotenv with vari
 * [nodejs (debug on)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nodejs-debug)
 * [nodejs (override on)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-nodejs-override)
 * [nodejs (processEnv override)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-custom-target)
-* [nodejs (DOTENV_KEY override)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-vault-custom-target)
 * [esm](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-esm)
 * [esm (preload)](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-esm-preload)
 * [typescript](https://github.com/dotenv-org/examples/tree/master/usage/dotenv-typescript)
@@ -409,20 +362,10 @@ Specify an object to write your secrets to. Defaults to `process.env` environmen
 const myObject = {}
 require('dotenv').config({ processEnv: myObject })
 
-console.log(myObject) // values from .env or .env.vault live here now.
+console.log(myObject) // values from .env
 console.log(process.env) // this was not changed or written to
 ```
 
-##### DOTENV_KEY
-
-Default: `process.env.DOTENV_KEY`
-
-Pass the `DOTENV_KEY` directly to config options. Defaults to looking for `process.env.DOTENV_KEY` environment variable. Note this only applies to decrypting `.env.vault` files. If passed as null or undefined, or not passed at all, dotenv falls back to its traditional job of parsing a `.env` file.
-
-```js
-require('dotenv').config({ DOTENV_KEY: 'dotenv://:key_1234…@dotenvx.com/vault/.env.vault?environment=production' })
-```
-
 ### Parse
 
 The engine which parses the contents of your file containing environment
@@ -493,22 +436,6 @@ Default: `false`
 
 Override any environment variables that have already been set.
 
-### Decrypt
-
-The engine which decrypts the ciphertext contents of your .env.vault file is available for use. It accepts a ciphertext and a decryption key. It uses AES-256-GCM encryption.
-
-For example, decrypting a simple ciphertext:
-
-```js
-const dotenv = require('dotenv')
-const ciphertext = 's7NYXa809k/bVSPwIAmJhPJmEGTtU0hG58hOZy7I0ix6y5HP8LsHBsZCYC/gw5DDFy5DgOcyd18R'
-const decryptionKey = 'ddcaa26504cd70a6fef9801901c3981538563a1767c297cb8416e8a38c62fe00'
-
-const decrypted = dotenv.decrypt(ciphertext, decryptionKey)
-
-console.log(decrypted) // # development@v6\nALPHA="zeta"
-```
-
 ## ❓ FAQ
 
 ### Why is the `.env` file not loading my environment variables successfully?
@@ -532,7 +459,7 @@ password than your development database.
 
 ### Should I have multiple `.env` files?
 
-We recommend creating on `.env` file per environment. Use `.env` for local/development, `.env.production` for production and so on. This still follows the twelve factor principles as each is attributed individually to its own environment. Avoid custom set ups that work in inheritance somehow (`.env.production` inherits values form `.env` for example). It is better to duplicate values if necessary across each `.env.environment` file.
+We recommend creating one `.env` file per environment. Use `.env` for local/development, `.env.production` for production and so on. This still follows the twelve factor principles as each is attributed individually to its own environment. Avoid custom set ups that work in inheritance somehow (`.env.production` inherits values form `.env` for example). It is better to duplicate values if necessary across each `.env.environment` file.
 
 > In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as “environments”, but instead are independently managed for each deploy. This is a model that scales up smoothly as the app naturally expands into more deploys over its lifetime.
 >
@@ -685,11 +612,7 @@ Try [dotenv-expand](https://github.com/motdotla/dotenv-expand)
 
 ### What about syncing and securing .env files?
 
-Use [dotenv-vault](https://github.com/dotenv-org/dotenv-vault)
-
-### What is a `.env.vault` file?
-
-A `.env.vault` file is an encrypted version of your development (and ci, staging, production, etc) environment variables. It is paired with a `DOTENV_KEY` to deploy your secrets more securely than scattering them across multiple platforms and tools. Use [dotenv-vault](https://github.com/dotenv-org/dotenv-vault) to manage and generate them.
+Use [dotenvx](https://github.com/dotenvx/dotenvx)
 
 ### What if I accidentally commit my `.env` file to code?
 
diff --git a/node_modules/dotenv/package.json b/node_modules/dotenv/package.json
index bb06025b4053564d243b5b4ef70f16b37fe9a2a7..528426b4c9110db5381cd69342a91c78b5fc8570 100644
--- a/node_modules/dotenv/package.json
+++ b/node_modules/dotenv/package.json
@@ -1,6 +1,6 @@
 {
   "name": "dotenv",
-  "version": "16.4.5",
+  "version": "16.4.7",
   "description": "Loads environment variables from .env file",
   "main": "lib/main.js",
   "types": "lib/main.d.ts",
@@ -21,10 +21,9 @@
   "scripts": {
     "dts-check": "tsc --project tests/types/tsconfig.json",
     "lint": "standard",
-    "lint-readme": "standard-markdown",
     "pretest": "npm run lint && npm run dts-check",
-    "test": "tap tests/*.js --100 -Rspec",
-    "test:coverage": "tap --coverage-report=lcov",
+    "test": "tap run --allow-empty-coverage --disable-coverage --timeout=60000",
+    "test:coverage": "tap run --show-full-coverage --timeout=60000 --coverage-report=lcov",
     "prerelease": "npm test",
     "release": "standard-version"
   },
@@ -45,15 +44,12 @@
   "readmeFilename": "README.md",
   "license": "BSD-2-Clause",
   "devDependencies": {
-    "@definitelytyped/dtslint": "^0.0.133",
     "@types/node": "^18.11.3",
-    "decache": "^4.6.1",
+    "decache": "^4.6.2",
     "sinon": "^14.0.1",
     "standard": "^17.0.0",
-    "standard-markdown": "^7.1.0",
     "standard-version": "^9.5.0",
-    "tap": "^16.3.0",
-    "tar": "^6.1.11",
+    "tap": "^19.2.0",
     "typescript": "^4.8.4"
   },
   "engines": {
diff --git a/package-lock.json b/package-lock.json
index 582dfb7918db55d4841bd353f76eadfdde1f8130..26a4d46187efa21050398064b15c1f4057513b68 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,7 @@
       "license": "UNLICENSED",
       "dependencies": {
         "@nestjs/common": "^10.3.3",
+        "@nestjs/config": "^4.0.2",
         "@nestjs/core": "^10.0.0",
         "@nestjs/jwt": "^10.2.0",
         "@nestjs/platform-express": "^10.0.0",
@@ -1770,6 +1771,21 @@
         }
       }
     },
+    "node_modules/@nestjs/config": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/@nestjs/config/-/config-4.0.2.tgz",
+      "integrity": "sha512-McMW6EXtpc8+CwTUwFdg6h7dYcBUpH5iUILCclAsa+MbCEvC9ZKu4dCHRlJqALuhjLw97pbQu62l4+wRwGeZqA==",
+      "license": "MIT",
+      "dependencies": {
+        "dotenv": "16.4.7",
+        "dotenv-expand": "12.0.1",
+        "lodash": "4.17.21"
+      },
+      "peerDependencies": {
+        "@nestjs/common": "^10.0.0 || ^11.0.0",
+        "rxjs": "^7.1.0"
+      }
+    },
     "node_modules/@nestjs/core": {
       "version": "10.3.3",
       "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.3.3.tgz",
@@ -4372,9 +4388,25 @@
       }
     },
     "node_modules/dotenv": {
-      "version": "16.4.5",
-      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz",
-      "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==",
+      "version": "16.4.7",
+      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
+      "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
+      "license": "BSD-2-Clause",
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://dotenvx.com"
+      }
+    },
+    "node_modules/dotenv-expand": {
+      "version": "12.0.1",
+      "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.1.tgz",
+      "integrity": "sha512-LaKRbou8gt0RNID/9RoI+J2rvXsBRPMV7p+ElHlPhcSARbCPDYcYG2s1TIzAfWv4YSgyY5taidWzzs31lNV3yQ==",
+      "license": "BSD-2-Clause",
+      "dependencies": {
+        "dotenv": "^16.4.5"
+      },
       "engines": {
         "node": ">=12"
       },
diff --git a/package.json b/package.json
index 485631460dc4cb0494cb38666b4b8228f2e39a4b..fdc6c1acfd3c693e5c4bbdd9a66aab891f7f59de 100644
--- a/package.json
+++ b/package.json
@@ -22,6 +22,7 @@
   },
   "dependencies": {
     "@nestjs/common": "^10.3.3",
+    "@nestjs/config": "^4.0.2",
     "@nestjs/core": "^10.0.0",
     "@nestjs/jwt": "^10.2.0",
     "@nestjs/platform-express": "^10.0.0",
diff --git a/src/app.module.ts b/src/app.module.ts
index eeb0491d561affdfda3eb160371ed24b85908f43..5be3db30d9e825ff5177419f0587a6ffe14b639d 100644
--- a/src/app.module.ts
+++ b/src/app.module.ts
@@ -6,6 +6,7 @@ import { join } from 'path';
 import { DataSource } from 'typeorm';
 import { AppController } from './app.controller';
 import { AppService } from './app.service';
+import { ConfigModule } from '@nestjs/config'; // เพิ่ม ConfigModule
 
 // Import Modules
 import { UsersModule } from './users/users.module';
@@ -55,13 +56,18 @@ import { ProductionTarget } from './production_targets/entities/production_targe
 import { QueueType } from './queue-types/entities/queue-type.entity';
 @Module({
   imports: [
+    ConfigModule.forRoot({
+      isGlobal: true, // ทำให้ใช้ได้ทั่วทั้งแอป
+      envFilePath:
+        process.env.NODE_ENV === 'docker' ? '.env.docker' : '.env.local', // หรือ '.env.local' / '.env.docker' ตามที่ต้องการ
+    }),
     TypeOrmModule.forRoot({
       type: 'mysql',
-      host: 'localhost',
-      port: 3306,
-      username: 'root',
-      password: '',
-      database: 'water',
+      host: process.env.DB_HOST,
+      port: parseInt(process.env.DB_PORT || '3306'),
+      username: process.env.DB_USERNAME || 'root',
+      password: process.env.DB_PASSWORD || '',
+      database: process.env.DB_NAME,
       entities: [
         User,
         Role,
@@ -86,6 +92,7 @@ import { QueueType } from './queue-types/entities/queue-type.entity';
         QueueType,
       ],
       synchronize: true,
+      autoLoadEntities: true,
     }),
     ServeStaticModule.forRoot({
       rootPath: join(__dirname, '..', 'public'),
diff --git a/src/main.ts b/src/main.ts
index 5d8d8da92f5814d263cfba527b8dde92520af6de..f28f67cfd32a2d0f1acb5f868fb0828bb2573146 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -5,6 +5,13 @@ import { ValidationPipe } from '@nestjs/common';
 import { exec } from 'child_process';
 
 async function bootstrap() {
+  console.log('✅ NestJS is running on http://localhost:4000');
+  console.log('🌱 ENV Loaded:');
+  console.log('DB_HOST:', process.env.DB_HOST);
+  console.log('DB_PORT:', process.env.DB_PORT);
+  console.log('DB_USERNAME:', process.env.DB_USERNAME);
+  console.log('DB_PASSWORD:', process.env.DB_PASSWORD);
+  console.log('DB_NAME:', process.env.DB_NAME);
   const app = await NestFactory.create(AppModule);
 
   // 🔹 เพิ่ม Swagger API Documentation
@@ -45,7 +52,7 @@ async function bootstrap() {
   // );
   // 🔹 Start NestJS
   await app.listen(4000);
-  console.log('✅ NestJS is running on http://localhost:4000');
+
   // console.log('✅ FastAPI started successfully: http://localhost:9000');
 }
 
diff --git a/src/queues/AutoQueue/Autoqueue.py b/src/queues/AutoQueue/Autoqueue.py
deleted file mode 100644
index cbc993e28f6586d57a5ba75ad2be1de591ca970d..0000000000000000000000000000000000000000
--- a/src/queues/AutoQueue/Autoqueue.py
+++ /dev/null
@@ -1,506 +0,0 @@
-import simpy
-from datetime import datetime, timedelta
-import math
-from fastapi import FastAPI
-from fastapi.middleware.cors import CORSMiddleware
-
-# ==============================================
-# 1) ข้อมูลเครื่องจักร (machines_info)
-# ==============================================
-machines_info = [
-    {
-        "machine_id": "MC001",
-        "machine_name": "เครื่องเป่าขวด",
-        "function": "เป่า",
-        "materials": ["Preform"],  # ใช้วัตถุดิบ Preform
-        "bottle_size": ["600 ml", "1500 ml"],
-        "speed": [2200, 1100],  # 600 ml => 2200 ขวด/ชม, 1500 ml => 1100 ขวด/ชม
-        "changeover_time": [3, 3],
-        "status": "พร้อมใช้งาน"
-    },
-    {
-        "machine_id": "MC002",
-        "machine_name": "เครื่องเป่าขวด 350ml",
-        "function": "เป่า",
-        "materials": ["Preform"],
-        "bottle_size": ["350 ml"],
-        "speed": [2000],
-        "changeover_time": [0],
-        "status": "พร้อมใช้งาน"
-    },
-    {
-        "machine_id": "MC003",
-        "machine_name": "เครื่องสวมฉลาก",
-        "function": "สวมฉลาก",
-        "materials": ["Label", "EmptyBottle"],
-        "bottle_size": ["350 ml", "600 ml", "1500 ml"],
-        "speed": [4000, 4000, 2000],
-        "changeover_time": [0, 0, 0],
-        "status": "พร้อมใช้งาน"
-    },
-    {
-        "machine_id": "MC004",
-        "machine_name": "เครื่องบรรจุ + แพ็ค",
-        "function": "บรรจุ, แพ็ค",
-        "materials": ["EmptyBottleLabeled", "Cap", "PE_film"],
-        "bottle_size": ["350 ml", "600 ml", "1500 ml"],
-        "speed": [2400, 2400, 2400],
-        "changeover_time": [0.5, 0.5, 0.5],
-        "status": "พร้อมใช้งาน"
-    }
-]
-
-# ==============================================
-# 2) สต็อกวัตถุดิบ
-# ==============================================
-raw_material_stock = {
-    "Preform": 20000,
-    "Label_A": 20000,
-    "Label_B": 20000,
-    "Cap_A":   20000,
-    "Cap_B":   20000,
-    # 1 roll => 9600 ขวด
-    "PE_film_roll": 20
-}
-
-# ==============================================
-# 3) Orders ลูกค้า (ตัวอย่าง)
-# ==============================================
-customer_orders = [
-    {
-        "customer": "Wittaya",  
-        "type": "water",
-        "size": "600 ml",
-        "brand": "A",
-        "quantity_bottles": 8400,
-        "due_date": "2025-01-08",
-        "priority": 2
-    },
-    {
-        "customer": "Aof",
-        "type": "water",
-        "size": "600 ml",
-        "brand": "A",
-        "quantity_bottles": 3600,
-        "due_date": "2025-01-07",
-        "priority": 1
-    }
-]
-
-# ==============================================
-# 4) ตาราง config Buffer Stock
-# ==============================================
-buffer_config = [
-    {"type": "water",  "size": "350 ml",  "brand": "A", "want_to_store": 0,    "current_store": 0},
-    {"type": "water",  "size": "600 ml",  "brand": "A", "want_to_store": 8000, "current_store": 0},
-    {"type": "water",  "size": "1500 ml", "brand": "A", "want_to_store": 6000, "current_store": 0},
-    {"type": "water",  "size": "350 ml",  "brand": "B", "want_to_store": 0,    "current_store": 0},
-    {"type": "water",  "size": "600 ml",  "brand": "B", "want_to_store": 6000, "current_store": 0},
-    {"type": "water",  "size": "1500 ml", "brand": "B", "want_to_store": 6000, "current_store": 0},
-    {"type": "bottle", "size": "350 ml",  "brand": None,"want_to_store": 0,    "current_store": 0},
-    {"type": "bottle", "size": "600 ml",  "brand": None,"want_to_store": 6000, "current_store": 0},
-    {"type": "bottle", "size": "1500 ml", "brand": None,"want_to_store": 6000, "current_store": 0}
-]
-
-# ==============================================
-# 5) ตาราง priority ของการผลิตเผื่อ
-# ==============================================
-buffer_priority = [
-    {"priority": 1, "type": "water",  "size": "600 ml",  "brand": "A"},
-    {"priority": 2, "type": "water",  "size": "1500 ml", "brand": "A"},
-    {"priority": 3, "type": "water",  "size": "350 ml",  "brand": "A"},
-    {"priority": 4, "type": "water",  "size": "600 ml",  "brand": "B"},
-    {"priority": 5, "type": "water",  "size": "1500 ml", "brand": "B"},
-    {"priority": 6, "type": "water",  "size": "350 ml",  "brand": "B"},
-    {"priority": 7, "type": "bottle", "size": "600 ml",  "brand": None},
-    {"priority": 8, "type": "bottle", "size": "1500 ml", "brand": None},
-    {"priority": 9, "type": "bottle", "size": "350 ml",  "brand": None}
-]
-
-# ==============================================
-# 6) เวลา และ Block การทำงาน
-# ==============================================
-WORK_START_1 = 8
-WORK_END_1   = 12
-WORK_START_2 = 13
-WORK_END_2   = 17
-MIN_BLOCK_LEFT = 0.5  # ถ้าบล็อกเหลือ < 0.5 ชม => ข้าม
-
-def get_current_datetime(env):
-    start_sim = datetime(2025, 1, 1, 8, 0, 0)
-    return start_sim + timedelta(hours=env.now)
-
-def skip_to_next_work_time(env):
-    while True:
-        now_dt = get_current_datetime(env)
-        wd = now_dt.weekday()
-        hr = now_dt.hour
-        if wd >= 5:  # เสาร์/อาทิตย์
-            days_to_monday = 7 - wd
-            next_mon_8 = datetime(now_dt.year, now_dt.month, now_dt.day, 8) + timedelta(days=days_to_monday)
-            yield env.timeout((next_mon_8 - now_dt).total_seconds()/3600)
-            continue
-
-        if hr < WORK_START_1:
-            next_8 = datetime(now_dt.year, now_dt.month, now_dt.day, WORK_START_1)
-            yield env.timeout((next_8 - now_dt).total_seconds()/3600)
-            continue
-
-        if WORK_END_1 <= hr < WORK_START_2:
-            next_13 = datetime(now_dt.year, now_dt.month, now_dt.day, WORK_START_2)
-            yield env.timeout((next_13 - now_dt).total_seconds()/3600)
-            continue
-
-        if hr >= WORK_END_2:
-            next_day_8 = datetime(now_dt.year, now_dt.month, now_dt.day, WORK_START_1) + timedelta(days=1)
-            yield env.timeout((next_day_8 - now_dt).total_seconds()/3600)
-            continue
-
-        # อยู่ในเวลางานแล้ว
-        break
-
-def get_time_to_block_end(env):
-    now_dt = get_current_datetime(env)
-    hr = now_dt.hour
-    if WORK_START_1 <= hr < WORK_END_1:
-        block_end = datetime(now_dt.year, now_dt.month, now_dt.day, WORK_END_1)
-    else:
-        block_end = datetime(now_dt.year, now_dt.month, now_dt.day, WORK_END_2)
-    return (block_end - now_dt).total_seconds()/3600
-
-# ==============================================
-# 7) Machine Resource + Log
-# ==============================================
-class MachineResource:
-    def __init__(self, env, machine_id):
-        self.env = env
-        self.machine_id = machine_id
-        self.resource = simpy.PriorityResource(env, capacity=1)
-        self.last_size_run = None  # เก็บ track ว่าล่าสุดผลิตขนาดไหน
-
-production_log = []
-queue_counter = 0
-
-def log_event(machine_id, order_id, page_id,
-              start_dt, finish_dt,
-              bottle_size, produced_qty, duration_hrs):
-    """
-    เก็บ Log ในรูปแบบเบื้องต้นก่อน
-    """
-    global queue_counter
-    queue_counter += 1
-    production_log.append({
-        "QueueID": queue_counter,
-        "MachineID": machine_id,
-        "OrderID": order_id,  # -1 สำหรับงานเผื่อ, -2 สำหรับ Changeover
-        "PageID": page_id,
-        "startTime": start_dt.strftime("%Y-%m-%d %H:%M:%S"),
-        "finishTime": finish_dt.strftime("%Y-%m-%d %H:%M:%S"),
-        "status": "Completed",
-        "bottleSize": bottle_size,
-        "producedQuantity": int(produced_qty),
-        "durationHours": round(duration_hrs, 2)
-    })
-
-def create_machines(env):
-    d = {}
-    for mc in machines_info:
-        d[mc["machine_id"]] = MachineResource(env, mc["machine_id"])
-    return d
-
-# ==============================================
-# 8) ฟังก์ชัน check/consume วัตถุดิบ
-# ==============================================
-def check_raw_materials(item_type, brand, size, quantity):
-    if item_type == "bottle":
-        # จะใช้ preform 1 ชิ้น/ขวด
-        if raw_material_stock["Preform"] < quantity:
-            return False
-    elif item_type == "water":
-        # สุดท้ายจะใช้ preform, label, cap, pe film
-        if raw_material_stock["Preform"] < quantity:
-            return False
-        label_key = f"Label_{brand}"
-        if label_key not in raw_material_stock or raw_material_stock[label_key] < quantity:
-            return False
-        cap_key = f"Cap_{brand}"
-        if cap_key not in raw_material_stock or raw_material_stock[cap_key] < quantity:
-            return False
-        rolls_needed = math.ceil(quantity / 9600)
-        if raw_material_stock["PE_film_roll"] < rolls_needed:
-            return False
-    return True
-
-def consume_raw_materials(item_type, brand, size, quantity):
-    if item_type == "bottle":
-        raw_material_stock["Preform"] -= quantity
-    elif item_type == "water":
-        raw_material_stock["Preform"] -= quantity
-        raw_material_stock[f"Label_{brand}"] -= quantity
-        raw_material_stock[f"Cap_{brand}"]   -= quantity
-        rolls_needed = math.ceil(quantity / 9600)
-        raw_material_stock["PE_film_roll"]   -= rolls_needed
-
-# ==============================================
-# 9) do_split_task: ทำงานจริง แบ่งเป็นบล็อก
-# ==============================================
-def do_split_task(env, machine_id, order_id, page_id,
-                  bottle_size, rate, hours_needed):
-    remain = hours_needed
-    while remain > 0:
-        # ข้ามเวลาจนกว่าจะเข้าสู่ช่วงเวลาทำงาน
-        yield from skip_to_next_work_time(env)
-
-        block_left = get_time_to_block_end(env)
-        if block_left < MIN_BLOCK_LEFT:
-            # ถ้าช่วงเวลาทำงานเหลือน้อยกว่า 0.5 ชม ให้ข้ามไปก่อน
-            yield env.timeout(block_left)
-            continue
-
-        work_hrs = min(remain, block_left)
-        start_dt = get_current_datetime(env)
-        yield env.timeout(work_hrs)
-        finish_dt = get_current_datetime(env)
-
-        remain -= work_hrs
-        produced = rate * work_hrs if rate>0 else 0
-        dur_hrs = (finish_dt - start_dt).total_seconds()/3600
-
-        # บันทึก event
-        log_event(machine_id, order_id, page_id, start_dt, finish_dt,
-                  bottle_size, produced, dur_hrs)
-
-# ==============================================
-# 10) Pipeline สำหรับ Orders ลูกค้า
-# ==============================================
-def customer_pipeline(env, order, machines):
-    order_id = order["customer"]
-    item_type = order["type"]
-    brand = order["brand"]
-    size = order["size"]
-    qty = order["quantity_bottles"]
-    priority = order["priority"]
-
-    # ตรวจสอบวัตถุดิบก่อน
-    if not check_raw_materials(item_type, brand, size, qty):
-        print(f"** วัตถุดิบไม่พอสำหรับ Order {order_id} => skip **")
-        return
-    consume_raw_materials(item_type, brand, size, qty)
-
-    # เลือก Pipeline
-    if item_type == "water":
-        if size == "350 ml":
-            pipeline_seq = ["MC002", "MC003", "MC004"]
-        else:
-            pipeline_seq = ["MC001", "MC003", "MC004"]
-    else:
-        if size == "350 ml":
-            pipeline_seq = ["MC002"]
-        else:
-            pipeline_seq = ["MC001"]
-
-    remain_qty = qty
-    for mc_id in pipeline_seq:
-        mc_info = next(m for m in machines_info if m["machine_id"]==mc_id)
-        idx = mc_info["bottle_size"].index(size)
-        rate = mc_info["speed"][idx]
-        cng = mc_info["changeover_time"][idx]
-
-        mc_res = machines[mc_id]
-        with mc_res.resource.request(priority=priority) as req:
-            yield req
-            # === ทำ Changeover แยกเป็น orderID = -2 ===
-            if mc_res.last_size_run != size:
-                if mc_res.last_size_run is not None:
-                    yield env.process(
-                        do_split_task(env, mc_id, -2, "Changeover", size, 0, cng)
-                    )
-                mc_res.last_size_run = size
-
-            hours_needed = remain_qty / rate
-            yield env.process(
-                do_split_task(env, mc_id, order_id, mc_id, size, rate, hours_needed)
-            )
-
-# ==============================================
-# 11) Pipeline สำหรับการผลิต “เผื่อ”
-# ==============================================
-def buffer_pipeline(env, item, machines, priority):
-    order_id = -1  # หมายถึงงานผลิตเพื่อ buffer
-    item_type = item["type"]
-    brand = item["brand"]
-    size = item["size"]
-
-    can_store = item["want_to_store"] - item["current_store"]
-    if can_store <= 0:
-        return
-
-    # ตรวจสอบวัตถุดิบ
-    if not check_raw_materials(item_type, brand, size, can_store):
-        return
-
-    # ตัดสต็อก
-    consume_raw_materials(item_type, brand, size, can_store)
-
-    # Pipeline
-    if item_type == "water":
-        if size == "350 ml":
-            pipeline_seq = ["MC002", "MC003", "MC004"]
-        else:
-            pipeline_seq = ["MC001", "MC003", "MC004"]
-    else:
-        if size == "350 ml":
-            pipeline_seq = ["MC002"]
-        else:
-            pipeline_seq = ["MC001"]
-
-    remain_qty = can_store
-    for mc_id in pipeline_seq:
-        mc_info = next(m for m in machines_info if m["machine_id"]==mc_id)
-        idx = mc_info["bottle_size"].index(size)
-        rate = mc_info["speed"][idx]
-        cng = mc_info["changeover_time"][idx]
-
-        mc_res = machines[mc_id]
-        with mc_res.resource.request(priority=priority) as req:
-            yield req
-            if mc_res.last_size_run != size:
-                if mc_res.last_size_run is not None:
-                    yield env.process(
-                        do_split_task(env, mc_id, -2, "Changeover", size, 0, cng)
-                    )
-                mc_res.last_size_run = size
-
-            hours_needed = remain_qty / rate
-            yield env.process(
-                do_split_task(env, mc_id, order_id, f"Buffer-{mc_id}", size, rate, hours_needed)
-            )
-
-    item["current_store"] += can_store
-
-# ==============================================
-# 12) Process หลักในการผลิตเผื่อ
-# ==============================================
-def buffer_production_flow(env, machines):
-    done = False
-    while not done:
-        done = True
-        for bf in sorted(buffer_priority, key=lambda x: x["priority"]):
-            bf_type = bf["type"]
-            bf_size = bf["size"]
-            bf_brand = bf["brand"]
-            item = next((it for it in buffer_config
-                         if it["type"]==bf_type and it["size"]==bf_size and it["brand"]==bf_brand),
-                        None)
-            if item is None:
-                continue
-
-            need = item["want_to_store"] - item["current_store"]
-            if need>0:
-                old_val = item["current_store"]
-                yield env.process(buffer_pipeline(env, item, machines, priority=9999))
-                if item["current_store"]>old_val:
-                    done = False
-
-# ==============================================
-# 13) run_simulation
-# ==============================================
-def run_simulation():
-    env = simpy.Environment()
-    machines = create_machines(env)
-
-    # สั่งผลิตตามลำดับ priority ของ order
-    sorted_orders = sorted(customer_orders, key=lambda x: x["priority"])
-    for od in sorted_orders:
-        env.process(customer_pipeline(env, od, machines))
-
-    # สั่งผลิต buffer
-    env.process(buffer_production_flow(env, machines))
-
-    # run จนถึง 2000 ชั่วโมง (เผื่อพอสำหรับคำสั่งทั้งหมด)
-    env.run(until=2000)
-
-    return production_log
-
-# ==============================================
-# ฟังก์ชันเสริม: แปลงโครงสร้าง production_log
-# ==============================================
-from datetime import datetime
-
-def transform_production_log(prod_log):
-    """
-    แปลงข้อมูลให้อยู่ใน structure ตามต้องการ
-    - orderID == -1 → "ผลิตเผื่อ"
-    - orderID == -2 → "เปลี่ยนขนาด"
-    - Mapping machineID (MC001 → MC1, etc.)
-    - แก้ format ของเวลาเป็น d/m/YYYY HH:MM
-    - ตัด space ออกจาก bottleSize เช่น "600 ml" -> "600ml"
-    """
-
-    # Mapping ค่าของ MachineID
-    machine_map = {
-        "MC001": "MC1",
-        "MC002": "MC2",
-        "MC003": "MC3",
-        "MC004": "MC4"
-    }
-
-    new_log = []
-    for row in prod_log:
-        # แปลง string "YYYY-mm-dd HH:MM:SS" เป็น datetime object
-        start_dt = datetime.strptime(row["startTime"], "%Y-%m-%d %H:%M:%S")
-        finish_dt = datetime.strptime(row["finishTime"], "%Y-%m-%d %H:%M:%S")
-
-        # format วัน-เวลาให้เป็น d/m/YYYY HH:MM
-        start_time_str  = f"{start_dt.day}/{start_dt.month}/{start_dt.year} {start_dt.hour:02d}:{start_dt.minute:02d}"
-        finish_time_str = f"{finish_dt.day}/{finish_dt.month}/{finish_dt.year} {finish_dt.hour:02d}:{finish_dt.minute:02d}"
-
-        # แปลง orderID ตามเงื่อนไขที่กำหนด
-        if row["OrderID"] == -1:
-            order_id = "ผลิตเผื่อ"
-        elif row["OrderID"] == -2:
-            order_id = "เปลี่ยนขนาด"
-        else:
-            order_id = row["OrderID"]
-
-        new_log.append({
-            "queueID": row["QueueID"],
-            "machineID": machine_map.get(row["MachineID"], row["MachineID"]),  # Map ค่า MachineID
-            "orderID": order_id,  # ใช้ค่าเปลี่ยนชื่อ orderID
-            "pageNumber": 1,  # Fix เป็น 1 ตามที่กำหนด
-            "status": row["status"],  
-            "startTime": start_time_str,
-            "finishTime": finish_time_str,
-            "bottleSize": row["bottleSize"].replace(" ", ""),  # ตัด space ใน bottleSize เช่น "600 ml" -> "600ml"
-            "producedQuantity": row["producedQuantity"],
-        })
-
-    return new_log
-
-
-
-
-# ==============================================
-# 14) FastAPI
-# ==============================================
-app = FastAPI()
-app.add_middleware(
-    CORSMiddleware,
-    allow_origins=["http://localhost:5173"],  # หรือใช้ ["*"] ถ้าต้องการอนุญาตทุกที่
-    allow_credentials=True,
-    allow_methods=["*"],
-    allow_headers=["*"],
-)
-
-@app.post("/run-simulation/")
-def run_simulation_endpoint():
-    # เรียก simulation
-    prod_log = run_simulation()
-    # แปลง log ให้ได้โครงสร้างตามที่ต้องการ
-    transformed_log = transform_production_log(prod_log)
-    return {
-        "message": "Simulation completed",
-        "production_log": transformed_log,
-        "buffer_config": buffer_config,
-        "raw_material_stock": raw_material_stock
-    }
diff --git a/src/queues/AutoQueue/Autoqueuenew.py b/src/queues/AutoQueue/Autoqueuenew.py
deleted file mode 100644
index ba87ba86d0598a0c46680f4f55d1e1d97bde910c..0000000000000000000000000000000000000000
--- a/src/queues/AutoQueue/Autoqueuenew.py
+++ /dev/null
@@ -1,446 +0,0 @@
-###########################
-# app.py (FastAPI)
-###########################
-
-import sys
-import os
-import requests
-import json
-from fastapi import FastAPI, Body
-from fastapi.middleware.cors import CORSMiddleware
-from typing import List, Dict, Any, Optional, Tuple
-from dataclasses import dataclass, field
-from datetime import datetime, timedelta
-
-###########################
-# 0) CONFIG
-###########################
-if os.name == "nt":
-    # ให้รองรับภาษาไทย + emoji บน Windows
-    sys.stdout.reconfigure(encoding='utf-8')
-
-API_BASE = "http://localhost:4000"  # TODO: ปรับตามจริง
-URLS = {
-    "products": f"{API_BASE}/products",
-    "materials": f"{API_BASE}/materials",
-    "machines": f"{API_BASE}/machines",
-    "stock_configs": f"{API_BASE}/stock-config",
-    # ถ้าจะโพสต์กลับ NestJS ก็เพิ่ม:
-    # "queues_batch": f"{API_BASE}/queues/batch",
-    # "production_targets_many": f"{API_BASE}/production-targets/many",
-}
-
-# เราจะใช้ fastAPI
-app = FastAPI()
-app.add_middleware(
-    CORSMiddleware,
-    allow_origins=["*"],  # หรือกำหนด origin ตามต้องการ
-    allow_credentials=True,
-    allow_methods=["*"],
-    allow_headers=["*"],
-)
-
-###########################
-# 1) DATACLASSES
-###########################
-@dataclass
-class ProductData:
-    ProductID: int
-    brand: str
-    size: str
-    unit: str
-    status: str
-    lowStockLevel: int
-    quantityInStock: int
-    pricePerUnit: str
-    name: str = field(init=False)
-
-    def __post_init__(self):
-        self.name = f"{self.brand} {self.size} ({self.unit})"
-
-
-@dataclass
-class MaterialData:
-    MaterialID: int
-    name: str
-    size: str
-    brand: str
-    quantityInStock: int
-    lowStockLevel: int
-    status: str
-    ReorderLevel: int
-    unit: str
-    pricePerUnit: str
-    LastUpdate: str
-
-@dataclass
-class IngredientData:
-    recipeIngredientID: int
-    quantityNeed: str
-    material: Dict[str,Any]  # ถ้าอยาก map เป็น MaterialData ก็ได้
-
-@dataclass
-class RecipeData:
-    recipeID: int
-    outputItemID: int
-    outputItemType: str
-    outputQuantity: int
-    ingredients: List[IngredientData]
-
-@dataclass
-class MachineDetailData:
-    MachineDetailID: int
-    outputRate: int
-    changOver: float
-    recipes: List[RecipeData]
-
-@dataclass
-class MachineData:
-    MachineID: int
-    name: str
-    type: str
-    lastMaintenanceDate: Optional[str]
-    status: str
-    notes: Optional[str]
-    machineDetails: List[MachineDetailData]
-
-@dataclass
-class StockConfigData:
-    stockConfigID: int
-    itemID: int
-    itemType: str
-    priorityLevel: int
-    targetStockLevel: int
-    status: str
-    lastUpdated: str
-    page: Any = None
-    itemName: Optional[str] = None
-    itemDetail: Optional[Dict[str,Any]] = None
-
-
-###########################
-# 2) LOAD & CLEAN FUNCTIONS
-###########################
-
-def load_products() -> List[ProductData]:
-    resp = requests.get(URLS["products"])
-    data_list = resp.json()
-    cleaned = []
-    for d in data_list:
-        # filter key
-        f = {
-            "ProductID": d.get("ProductID",0),
-            "brand": d.get("brand",""),
-            "size": d.get("size",""),
-            "unit": d.get("unit",""),
-            "status": d.get("status","ปกติ"),
-            "lowStockLevel": int(d.get("lowStockLevel",0)),
-            "quantityInStock": int(d.get("quantityInStock",0)),
-            "pricePerUnit": d.get("pricePerUnit","0.00"),
-        }
-        obj = ProductData(**f)
-        cleaned.append(obj)
-    return cleaned
-
-def load_materials() -> List[MaterialData]:
-    resp = requests.get(URLS["materials"])
-    data_list = resp.json()
-    cleaned = []
-    for d in data_list:
-        f = {
-            "MaterialID": d.get("MaterialID",0),
-            "name": d.get("name","Unknown"),
-            "size": d.get("size","any"),
-            "brand": d.get("brand","any"),
-            "quantityInStock": int(d.get("quantityInStock",0)),
-            "lowStockLevel": int(d.get("lowStockLevel",0)),
-            "status": d.get("status","ปกติ"),
-            "ReorderLevel": int(d.get("ReorderLevel",0)),
-            "unit": d.get("unit","ชิ้น"),
-            "pricePerUnit": d.get("pricePerUnit","0.00"),
-            "LastUpdate": d.get("LastUpdate","2023-01-01T00:00:00Z")
-        }
-        cleaned.append(MaterialData(**f))
-    return cleaned
-
-def load_machines() -> List[MachineData]:
-    resp = requests.get(URLS["machines"])
-    raw_list = resp.json()
-    machines = []
-    for mc in raw_list:
-        # filter machine
-        m = MachineData(
-            MachineID=mc.get("MachineID",0),
-            name=mc.get("name","Unknown"),
-            type=mc.get("type","Unknown"),
-            lastMaintenanceDate=mc.get("lastMaintenanceDate"),
-            status=mc.get("status","ACTIVE"),
-            notes=mc.get("notes"),
-            machineDetails=[]
-        )
-        md_list = mc.get("machineDetails",[])
-        for md in md_list:
-            detail = MachineDetailData(
-                MachineDetailID=md.get("MachineDetailID",0),
-                outputRate=md.get("outputRate",1000),
-                changOver=float(md.get("changOver",0)),
-                recipes=[]
-            )
-            for r in md.get("recipes",[]):
-                recipe = RecipeData(
-                    recipeID=r.get("recipeID",0),
-                    outputItemID=r.get("outputItemID",0),
-                    outputItemType=r.get("outputItemType","MATERIAL"),
-                    outputQuantity=r.get("outputQuantity",1),
-                    ingredients=[]
-                )
-                for ing in r.get("ingredients",[]):
-                    iobj = IngredientData(
-                        recipeIngredientID=ing.get("recipeIngredientID",0),
-                        quantityNeed=ing.get("quantityNeed","1.0"),
-                        material=ing.get("material",{})
-                    )
-                    recipe.ingredients.append(iobj)
-                detail.recipes.append(recipe)
-            m.machineDetails.append(detail)
-        machines.append(m)
-    return machines
-
-def load_stockconfigs() -> List[StockConfigData]:
-    resp = requests.get(URLS["stock_configs"])
-    data_list = resp.json()
-    cleaned = []
-    for sc in data_list:
-        # rename key
-        scid = sc.get("StockConfigID",0)
-        f = {
-            "stockConfigID": scid,
-            "itemID": sc.get("itemID",0),
-            "itemType": sc.get("itemType","PRODUCT"),
-            "priorityLevel": int(sc.get("priorityLevel",1)),
-            "targetStockLevel": int(sc.get("targetStockLevel",0)),
-            "status": sc.get("status","Active"),
-            "lastUpdated": sc.get("lastUpdated","2023-01-01T00:00:00Z"),
-            "page": sc.get("page"),
-            "itemName": sc.get("itemName"),
-            "itemDetail": sc.get("itemDetail"),
-        }
-        cleaned.append(StockConfigData(**f))
-    return cleaned
-
-###########################
-# 3) BFS + SCHEDULING
-###########################
-@dataclass
-class PipelineStep:
-    machine_id: int
-    machine_detail_id: int
-    item_id: int
-    item_type: str
-
-# dict -> (rate, co)
-machine_detail_map: Dict[Tuple[int,int],Tuple[int,float]] = {}
-
-def build_machine_detail_map(machines: List[MachineData]):
-    machine_detail_map.clear()
-    for mc in machines:
-        for md in mc.machineDetails:
-            machine_detail_map[(mc.MachineID, md.MachineDetailID)] = (
-                md.outputRate,
-                md.changOver
-            )
-    return machine_detail_map
-
-def find_recipe_for_item(machines: List[MachineData], item_id: int, item_type: str):
-    found = []
-    for mc in machines:
-        for md in mc.machineDetails:
-            for r in md.recipes:
-                if r.outputItemID == item_id and r.outputItemType.upper() == item_type.upper():
-                    found.append((mc, md, r))
-    return found
-
-def build_pipeline(machines: List[MachineData], item_id:int, item_type:str, visited=None)->List[PipelineStep]:
-    if visited is None:
-        visited = set()
-    key_ = f"{item_type}:{item_id}"
-    if key_ in visited:
-        return []
-    visited.add(key_)
-
-    matched = find_recipe_for_item(machines, item_id, item_type)
-    if not matched:
-        return []  # raw
-
-    # pick first
-    mc, md, recipe = matched[0]
-    # BFS for ingredient
-    for ing in recipe.ingredients:
-        mat_id = ing.material.get("MaterialID",0)
-        # assum item_type= "MATERIAL"
-        build_pipeline(machines, mat_id, "MATERIAL", visited)
-
-    # add final step
-    step = PipelineStep(machine_id=mc.MachineID,
-                        machine_detail_id=md.MachineDetailID,
-                        item_id=item_id,
-                        item_type=item_type)
-    return [step]
-
-# scheduling
-WORKBLOCKS = [(8,12),(13,17)]
-MIN_BLOCK_LEFT = 0.5
-
-def is_weekend(dt: datetime)->bool:
-    return dt.weekday() >= 5
-
-def next_work_time(dt: datetime)->datetime:
-    while True:
-        if is_weekend(dt):
-            add_days = 7 - dt.weekday()
-            dt = datetime(dt.year, dt.month, dt.day, 8,0,0) + timedelta(days=add_days)
-            return dt
-        hr = dt.hour
-        if hr < 8:
-            return datetime(dt.year, dt.month, dt.day, 8,0,0)
-        if 8<=hr<12:
-            return dt
-        if hr<13:
-            return datetime(dt.year, dt.month, dt.day, 13,0,0)
-        if hr<17:
-            return dt
-        dt = datetime(dt.year, dt.month, dt.day, 8,0,0) + timedelta(days=1)
-
-def get_block_end(dt: datetime)->datetime:
-    hr = dt.hour
-    if 8<=hr<12:
-        return datetime(dt.year, dt.month, dt.day, 12,0,0)
-    else:
-        return datetime(dt.year, dt.month, dt.day, 17,0,0)
-
-def get_rate_co(machine_id:int, md_id:int)->Tuple[int,float]:
-    if (machine_id,md_id) in machine_detail_map:
-        return machine_detail_map[(machine_id,md_id)]
-    return (1000,0)
-
-def schedule_pipeline(pipeline:List[PipelineStep], qty:int, start_dt:datetime, order_id:int):
-    """Return (events, finishTime)"""
-    events = []
-    current_dt = start_dt
-    for step in pipeline:
-        rate, co = get_rate_co(step.machine_id, step.machine_detail_id)
-        if rate<=0:
-            continue
-
-        hours_needed = qty / rate
-        remain = hours_needed
-        while remain>0:
-            current_dt = next_work_time(current_dt)
-            block_end = get_block_end(current_dt)
-            block_left = (block_end - current_dt).total_seconds()/3600
-            if block_left<MIN_BLOCK_LEFT:
-                current_dt = block_end
-                continue
-            used = min(remain, block_left)
-            st = current_dt
-            ft = st + timedelta(hours=used)
-            remain-=used
-            current_dt=ft
-
-            produced = rate*used
-            events.append({
-                "startTime": st.isoformat(),
-                "finishTime": ft.isoformat(),
-                "machineID": step.machine_id,
-                "itemID": step.item_id,
-                "itemType": step.item_type,
-                "producedQuantity": int(produced),
-                "orderID": order_id,
-                # "status": "Pending" # TODO: อาจใส่
-                # "bottleSize": "???" # TODO: ถ้าอยาก mapping size/brand
-            })
-    return events, current_dt
-
-
-###########################
-# 4) ตัวอย่าง Endpoint FastAPI
-###########################
-@app.post("/run-simulation")
-def run_simulation_endpoint(payload: dict = Body(...)):
-    """
-    ตัวอย่าง endpoint ที่ front-end จะยิงมา
-    เช่น JSON: {
-      "itemID": 12,
-      "itemType": "MATERIAL",
-      "qty": 5000,
-      "startDate": "2025-03-25T08:00:00",
-      "orderID": 1
-    }
-    """
-
-    item_id = payload.get("itemID",12)
-    item_type = payload.get("itemType","MATERIAL")
-    qty = payload.get("qty",1000)
-    startDateStr = payload.get("startDate","2025-03-25T08:00:00")
-    order_id = payload.get("orderID",1)
-
-    start_dt = datetime.fromisoformat(startDateStr)
-
-    # 1) load data
-    products = load_products()
-    materials = load_materials()
-    machines = load_machines()
-    stockconfigs = load_stockconfigs()
-
-    # 2) build machine_detail_map
-    build_machine_detail_map(machines)
-
-    # TODO: ตัวอย่างถ้ามี Logic เช็คของใน stock ว่าพอไหม => skip ถ้าไม่พอ
-    # (ยกตัวอย่างเล็กๆ)
-    # material_2 = next((m for m in materials if m.MaterialID==2), None)
-    # if material_2 and material_2.quantityInStock<qty:
-    #     return {"message":"Not enough raw material for item #2. Skip."}
-
-    # 3) BFS pipeline
-    pipeline = build_pipeline(machines, item_id, item_type)
-
-    # 4) schedule
-    events, finish_dt = schedule_pipeline(pipeline, qty, start_dt, order_id)
-
-    # 5) สร้าง ProductionTarget mock-up
-    production_target = {
-        "OrderID": order_id,
-        "itemID": item_id,
-        "itemType": item_type,
-        "TargetProduced": qty,
-        "ActualProduced": 0,
-        "Status": "กำลังรอ",
-        "Date": start_dt.strftime("%Y-%m-%d"),
-        # "startTime": start_dt.isoformat(),
-        # "endTime": finish_dt.isoformat()
-    }
-
-    # 6) ถ้าจะ POST ต่อไป NestJS => uncomment
-    # r1 = requests.post(URLS["production_targets_many"], json={"productionTargets":[production_target]})
-    # r2 = requests.post(URLS["queues_batch"], json=events)
-    # etc...
-
-    return {
-        "message": "Simulation completed",
-        "pipelineSteps": [f"{s.machine_id}:{s.machine_detail_id} => item {s.item_id}" for s in pipeline],
-        "queueEvents": events,
-        "productionTargetExample": production_target,
-        "finishedAt": finish_dt.isoformat()
-    }
-
-
-###########################
-# 5) ตัวอย่างวิธีรัน
-###########################
-# - เซฟไฟล์นี้เป็น app.py
-# - รันด้วยคำสั่ง: uvicorn app:app --reload
-#
-# แล้วลอง POST มาที่:
-# http://127.0.0.1:8000/run-simulation
-# ด้วย JSON ตามตัวอย่าง
-
diff --git a/src/queues/AutoQueue/Log copy.py b/src/queues/AutoQueue/Log copy.py
deleted file mode 100644
index dae9ed6b095c3f9adec9e8cb6d5966e3638b3442..0000000000000000000000000000000000000000
--- a/src/queues/AutoQueue/Log copy.py	
+++ /dev/null
@@ -1,438 +0,0 @@
-import requests
-import json
-import sys
-import os
-from dataclasses import dataclass, field
-from typing import List, Optional, Dict, Any
-
-# =======================================================
-# 0) CONFIG
-# =======================================================
-if os.name == "nt":
-    sys.stdout.reconfigure(encoding='utf-8')
-
-API_BASE = "http://localhost:4000"
-URLS = {
-    "products": f"{API_BASE}/products",
-    "materials": f"{API_BASE}/materials",
-    "machines": f"{API_BASE}/machines",
-    "stock_configs": f"{API_BASE}/stock-config",
-    "orders": f"{API_BASE}/orders",
-    "order_prio": f"{API_BASE}/orderpiorities"
-}
-
-# =======================================================
-# 1) DATACLASSES
-# =======================================================
-
-# ---------- 1.1 Product ----------
-@dataclass
-class ProductData:
-    ProductID: int
-    brand: str
-    size: str
-    unit: str
-    status: str
-    lowStockLevel: int
-    quantityInStock: int
-    pricePerUnit: str  # อาจเป็น string
-    name: str = field(init=False)
-
-    def __post_init__(self):
-        # เช่น รวม brand + size + unit เป็น name
-        self.name = f"{self.brand} {self.size} ({self.unit})"
-
-# ---------- 1.2 Material ----------
-@dataclass
-class MaterialData:
-    MaterialID: int
-    name: str
-    size: str
-    brand: str
-    quantityInStock: int
-    lowStockLevel: int
-    status: str
-    ReorderLevel: int
-    unit: str
-    pricePerUnit: str
-    LastUpdate: str
-    display_name: str = field(init=False)
-
-    def __post_init__(self):
-        self.display_name = f"{self.name} {self.size} {self.brand} ({self.unit})"
-
-# ---------- 1.3 Ingredient (Recipe_Ingredient) ----------
-@dataclass
-class IngredientData:
-    recipeIngredientID: int
-    quantityNeed: str  # เช่น "1.000000"
-    material: MaterialData
-
-# ---------- 1.4 Recipe ----------
-@dataclass
-class RecipeData:
-    recipeID: int
-    outputItemID: int
-    outputItemType: str  # 'PRODUCT' | 'MATERIAL'
-    outputQuantity: int
-    ingredients: List[IngredientData]
-
-# ---------- 1.5 MachineDetail ----------
-@dataclass
-class MachineDetailData:
-    MachineDetailID: int
-    outputRate: int
-    changOver: float
-    recipes: List[RecipeData]
-
-# ---------- 1.6 Machine ----------
-@dataclass
-class MachineData:
-    MachineID: int
-    name: str
-    type: str
-    lastMaintenanceDate: Optional[str]
-    status: str
-    notes: Optional[str]
-    machineDetails: List[MachineDetailData]
-
-# ---------- 1.7 StockConfigData ----------
-@dataclass
-class StockConfigData:
-    stockConfigID: int
-    itemID: int
-    itemType: str
-    priorityLevel: int
-    targetStockLevel: int
-    status: str
-    lastUpdated: str
-    # สมมุติ page เป็นอะไรก็ได้ (object/dict) หรือ int
-    page: Any = None
-    itemName: Optional[str] = None
-    itemDetail: Optional[Dict[str, Any]] = None
-
-# ---------- 1.8 Order ----------
-@dataclass
-class OrderData:
-    OrderID: int
-    status: str
-    quantity: int
-    totalPriceall: int
-    # คุณอาจใส่ฟิลด์อื่น เช่น date/time, customerID, ฯลฯ
-
-# ---------- 1.9 OrderPriority ----------
-@dataclass
-class OrderPriorityData:
-    orderPriorityID: int
-    Priority: int
-    OrderID: int
-    PageID: Optional[int] = None  # ให้มี default = None
-
-# =======================================================
-# 2) HELPER LOAD & CLEAN FUNCTIONS
-# =======================================================
-
-def rename_keys_if_needed(d: dict, old_key: str, new_key: str):
-    """ถ้าใน d มี old_key ให้ย้ายไป new_key"""
-    if old_key in d:
-        d[new_key] = d[old_key]
-        del d[old_key]
-
-# ---------- load & clean Products ----------
-def load_and_clean_products() -> List[ProductData]:
-    resp = requests.get(URLS["products"])
-    raw_list = resp.json()
-
-    allowed_keys = {
-        "ProductID","brand","size","unit",
-        "status","lowStockLevel","quantityInStock",
-        "pricePerUnit"
-    }
-    cleaned_list = []
-    for r in raw_list:
-        # filter
-        f = {k:r[k] for k in r if k in allowed_keys}
-        # fill defaults
-        if "status" not in f:
-            f["status"] = "ปกติ"
-        if "lowStockLevel" not in f:
-            f["lowStockLevel"] = 0
-        if "quantityInStock" not in f:
-            f["quantityInStock"] = 0
-        if "pricePerUnit" not in f:
-            f["pricePerUnit"] = "0.00"
-        # convert if needed
-        f["lowStockLevel"] = int(f["lowStockLevel"])
-        f["quantityInStock"] = int(f["quantityInStock"])
-        # create dataclass
-        obj = ProductData(**f)
-        cleaned_list.append(obj)
-    return cleaned_list
-
-# ---------- load & clean Materials ----------
-def load_and_clean_materials() -> List[MaterialData]:
-    resp = requests.get(URLS["materials"])
-    raw_list = resp.json()
-
-    allowed_keys = {
-        "MaterialID","name","size","brand","quantityInStock","lowStockLevel",
-        "status","ReorderLevel","unit","pricePerUnit","LastUpdate"
-    }
-    cleaned_list = []
-    for r in raw_list:
-        f = {k:r[k] for k in r if k in allowed_keys}
-
-        # fill default
-        if "status" not in f:
-            f["status"] = "ปกติ"
-        if "lowStockLevel" not in f:
-            f["lowStockLevel"] = 0
-        if "quantityInStock" not in f:
-            f["quantityInStock"] = 0
-        if "ReorderLevel" not in f:
-            f["ReorderLevel"] = 0
-        if "pricePerUnit" not in f:
-            f["pricePerUnit"] = "0.00"
-        if "LastUpdate" not in f:
-            f["LastUpdate"] = "2023-01-01T00:00:00.000Z"
-
-        # cast
-        f["lowStockLevel"] = int(f["lowStockLevel"])
-        f["quantityInStock"] = int(f["quantityInStock"])
-        f["ReorderLevel"] = int(f["ReorderLevel"])
-
-        obj = MaterialData(**f)
-        cleaned_list.append(obj)
-    return cleaned_list
-
-# ---------- load & clean Machines (มี machineDetails -> recipes -> ingredients) ----------
-def load_and_clean_machines() -> List[MachineData]:
-    resp = requests.get(URLS["machines"])
-    raw_list = resp.json()
-
-    # ฟิลด์ของ Machine
-    machine_allowed_keys = {
-        "MachineID","name","type","lastMaintenanceDate","status","notes","machineDetails"
-    }
-
-    # ฟิลด์ของ MachineDetail
-    detail_allowed_keys = {
-        "MachineDetailID","outputRate","changOver","recipes"
-    }
-
-    # ฟิลด์ของ Recipe
-    recipe_allowed_keys = {
-        "recipeID","outputItemID","outputItemType","outputQuantity","ingredients"
-    }
-
-    # ฟิลด์ของ Ingredient
-    ingredient_allowed_keys = {
-        "recipeIngredientID","quantityNeed","material"
-    }
-
-    # ฟิลด์ของ Material ภายใน Ingredient
-    ing_mat_allowed_keys = {
-        "MaterialID","name","size","brand","quantityInStock","lowStockLevel",
-        "status","ReorderLevel","unit","pricePerUnit","LastUpdate"
-    }
-
-    cleaned_machines = []
-    for mc in raw_list:
-        # filter machine level
-        m = {k:mc[k] for k in mc if k in machine_allowed_keys}
-
-        # ถ้าไม่มี machineDetails ให้เป็น []
-        if "machineDetails" not in m or not m["machineDetails"]:
-            m["machineDetails"] = []
-
-        # ตอนนี้ m["machineDetails"] เป็น list
-        new_details = []
-        for md in m["machineDetails"]:
-            # filter detail
-            md_f = {k:md[k] for k in md if k in detail_allowed_keys}
-
-            # fill default
-            if "changOver" not in md_f:
-                md_f["changOver"] = 0.0
-
-            # recipes
-            if "recipes" not in md_f or not md_f["recipes"]:
-                md_f["recipes"] = []
-
-            new_recipes = []
-            for r in md_f["recipes"]:
-                r_f = {k:r[k] for k in r if k in recipe_allowed_keys}
-                # fill default
-                if "ingredients" not in r_f or not r_f["ingredients"]:
-                    r_f["ingredients"] = []
-
-                new_ingredients = []
-                for ing in r_f["ingredients"]:
-                    ing_f = {k:ing[k] for k in ing if k in ingredient_allowed_keys}
-
-                    # material inside ingredient
-                    if "material" in ing_f and ing_f["material"]:
-                        mat_in_ing = ing_f["material"]
-                        mat_filtered = {mk:mat_in_ing[mk] for mk in mat_in_ing if mk in ing_mat_allowed_keys}
-                        # fill default if needed
-                        if "status" not in mat_filtered:
-                            mat_filtered["status"] = "ปกติ"
-                        if "lowStockLevel" not in mat_filtered:
-                            mat_filtered["lowStockLevel"] = 0
-                        if "quantityInStock" not in mat_filtered:
-                            mat_filtered["quantityInStock"] = 0
-                        ing_f["material"] = mat_filtered
-                    else:
-                        ing_f["material"] = {
-                            "MaterialID":0,"name":"Unnamed"
-                        }
-
-                    new_ingredients.append(IngredientData(**ing_f))
-                r_f["ingredients"] = new_ingredients
-
-                new_recipes.append(RecipeData(**r_f))
-            md_f["recipes"] = new_recipes
-
-            new_details.append(MachineDetailData(**md_f))
-        m["machineDetails"] = new_details
-
-        # fill default
-        if "notes" not in m:
-            m["notes"] = None
-        if "lastMaintenanceDate" not in m:
-            m["lastMaintenanceDate"] = None
-
-        # cast if needed
-        obj = MachineData(**m)
-        cleaned_machines.append(obj)
-
-    return cleaned_machines
-
-# ---------- load & clean StockConfigs ----------
-def load_and_clean_stockconfigs() -> List[StockConfigData]:
-    resp = requests.get(URLS["stock_configs"])
-    raw_list = resp.json()
-
-    allowed_keys = {
-        "stockConfigID","itemID","itemType","priorityLevel","targetStockLevel",
-        "status","lastUpdated","page","itemName","itemDetail"
-    }
-    cleaned_list = []
-    for sc in raw_list:
-        f = {k:sc[k] for k in sc if k in allowed_keys}
-
-        # fill default
-        if "stockConfigID" not in f:
-            f["stockConfigID"] = 0
-        if "status" not in f:
-            f["status"] = "Active"
-        if "priorityLevel" not in f:
-            f["priorityLevel"] = 1
-        if "targetStockLevel" not in f:
-            f["targetStockLevel"] = 0
-
-        # cast
-        f["priorityLevel"] = int(f["priorityLevel"])
-        f["targetStockLevel"] = int(f["targetStockLevel"])
-
-        obj = StockConfigData(**f)
-        cleaned_list.append(obj)
-    return cleaned_list
-
-# ---------- load & clean Orders ----------
-def load_and_clean_orders() -> List[OrderData]:
-    resp = requests.get(URLS["orders"])
-    raw_list = resp.json()
-
-    allowed_keys = {
-        "OrderID","status","quantity","totalPriceall"
-    }
-    cleaned_list = []
-    for od in raw_list:
-        f = {k:od[k] for k in od if k in allowed_keys}
-
-        # fill default
-        if "status" not in f:
-            f["status"] = "NEW"
-        if "quantity" not in f:
-            f["quantity"] = 0
-        if "totalPriceall" not in f:
-            f["totalPriceall"] = 0
-
-        obj = OrderData(**f)
-        cleaned_list.append(obj)
-    return cleaned_list
-
-# ---------- load & clean OrderPriorities ----------
-def load_and_clean_order_prio() -> List[OrderPriorityData]:
-    resp = requests.get(URLS["order_prio"])
-    if resp.status_code != 200:
-        # เผื่อกรณีไม่มี API ให้
-        print("No order priorities found or 404 not found")
-        return []
-
-    raw_list = resp.json()
-    allowed_keys = {
-        "orderPriorityID","Priority","OrderID","PageID"
-    }
-    cleaned_list = []
-    for op in raw_list:
-        f = {k:op[k] for k in op if k in allowed_keys}
-        # fill default
-        if "Priority" not in f:
-            f["Priority"] = 999
-        if "OrderID" not in f:
-            f["OrderID"] = 0
-
-        obj = OrderPriorityData(**f)
-        cleaned_list.append(obj)
-    return cleaned_list
-
-
-# =======================================================
-# 3) MAIN DEMO
-# =======================================================
-def main():
-    print("=== Loading & Cleaning Data from NestJS ===")
-
-    products = load_and_clean_products()
-    print(">>> Products:")
-    for p in products:
-        print(p)
-    print("==========================================\n")
-
-    materials = load_and_clean_materials()
-    print(">>> Materials:")
-    for m in materials:
-        print(m)
-    print("==========================================\n")
-
-    machines = load_and_clean_machines()
-    print(">>> Machines:")
-    for mc in machines:
-        print(mc)
-    print("==========================================\n")
-
-    stockconfigs = load_and_clean_stockconfigs()
-    print(">>> StockConfigs:")
-    for sc in stockconfigs:
-        print(sc)
-    print("==========================================\n")
-
-    orders = load_and_clean_orders()
-    print(">>> Orders:")
-    for od in orders:
-        print(od)
-    print("==========================================\n")
-
-    order_prios = load_and_clean_order_prio()
-    print(">>> OrderPriorities:")
-    for op in order_prios:
-        print(op)
-    print("==========================================\n")
-
-    print("All data cleaned successfully! 🎉")
-
-
-if __name__ == "__main__":
-    main()
diff --git a/src/queues/AutoQueue/Log.py b/src/queues/AutoQueue/Log.py
deleted file mode 100644
index 9557e43de51102f71215a2ff5b7d126b187cb704..0000000000000000000000000000000000000000
--- a/src/queues/AutoQueue/Log.py
+++ /dev/null
@@ -1,45 +0,0 @@
-import requests
-import json
-import sys
-import os
-
-# ให้รองรับภาษาไทยและ emoji บน Windows
-if os.name == "nt":
-    sys.stdout.reconfigure(encoding="utf-8")
-
-API_BASE = "http://localhost:4000"
-URLS = {
-    "products": f"{API_BASE}/products",
-    "materials": f"{API_BASE}/materials",
-    "machines": f"{API_BASE}/machines",
-    "stock_configs": f"{API_BASE}/stock-config",
-}
-
-def log_json_from_api(name: str, url: str):
-    print(f"\n📦 ดึงข้อมูลจาก API: {name} -> {url}")
-    try:
-        response = requests.get(url)
-        response.raise_for_status()
-        data = response.json()
-
-        # แสดงจำนวนรายการ
-        print(f"✅ ได้ข้อมูลทั้งหมด: {len(data)} รายการ")
-
-        # แสดงเฉพาะ 1-2 รายการแรก
-        preview_count = min(2, len(data))
-        print(f"\n🔍 แสดงตัวอย่าง {preview_count} รายการแรก:")
-        for i in range(preview_count):
-            print(f"\n🔹 {name} #{i+1}")
-            print(json.dumps(data[i], indent=2, ensure_ascii=False))
-
-    except Exception as e:
-        print(f"❌ เกิดข้อผิดพลาดในการดึง {name}: {e}")
-
-def main():
-    log_json_from_api("Products", URLS["products"])
-    log_json_from_api("Materials", URLS["materials"])
-    log_json_from_api("Machines", URLS["machines"])
-    log_json_from_api("Stock Configs", URLS["stock_configs"])
-
-if __name__ == "__main__":
-    main()
diff --git a/src/queues/AutoQueue/__pycache__/Autoqueue.cpython-310.pyc b/src/queues/AutoQueue/__pycache__/Autoqueue.cpython-310.pyc
deleted file mode 100644
index 890596d9249b96652c7a5c93ae31b40707cb30d9..0000000000000000000000000000000000000000
Binary files a/src/queues/AutoQueue/__pycache__/Autoqueue.cpython-310.pyc and /dev/null differ
diff --git a/src/queues/AutoQueue/__pycache__/Autoqueue.cpython-311.pyc b/src/queues/AutoQueue/__pycache__/Autoqueue.cpython-311.pyc
deleted file mode 100644
index cfbd03aa3caea8a42257690736d8716b154f84e8..0000000000000000000000000000000000000000
Binary files a/src/queues/AutoQueue/__pycache__/Autoqueue.cpython-311.pyc and /dev/null differ
diff --git a/src/queues/AutoQueue/__pycache__/Autoqueue.cpython-313.pyc b/src/queues/AutoQueue/__pycache__/Autoqueue.cpython-313.pyc
deleted file mode 100644
index 7918080c8ceba2fa002c7a2a0f4d7019e9a94089..0000000000000000000000000000000000000000
Binary files a/src/queues/AutoQueue/__pycache__/Autoqueue.cpython-313.pyc and /dev/null differ
diff --git a/src/queues/AutoQueue/cleandata.py b/src/queues/AutoQueue/cleandata.py
deleted file mode 100644
index 34d8c578f99710c9293396ba85b30c466e5b48b7..0000000000000000000000000000000000000000
--- a/src/queues/AutoQueue/cleandata.py
+++ /dev/null
@@ -1,228 +0,0 @@
-import requests
-import sys
-import os
-from dataclasses import dataclass, field
-from typing import List, Optional
-
-# ปรับ encoding สำหรับ Windows ให้รองรับภาษาไทยและ emoji
-if os.name == "nt":
-    sys.stdout.reconfigure(encoding="utf-8")
-
-# กำหนด API endpoints
-API_BASE = "http://localhost:4000"
-URLS = {
-    "products": f"{API_BASE}/products",
-    "materials": f"{API_BASE}/materials",
-    "machines": f"{API_BASE}/machines",
-    "stock_configs": f"{API_BASE}/stock-config",
-}
-
-# ========================
-# Data Model Definitions
-# ========================
-
-@dataclass
-class Product:
-    ProductID: int
-    brand: str
-    size: str
-    unit: str
-    status: str
-    lowStockLevel: int
-    quantityInStock: int
-    pricePerUnit: str  # API ส่งมาเป็น string
-    name: str = field(init=False)
-    
-    def __post_init__(self):
-        self.name = f"{self.brand} {self.size} ({self.unit})"
-
-@dataclass
-class Material:
-    MaterialID: int
-    name: str
-    size: str
-    brand: str
-    quantityInStock: int
-    lowStockLevel: int
-    status: str
-    ReorderLevel: int
-    unit: str
-    pricePerUnit: str  # API ส่งมาเป็น string
-    LastUpdate: str
-    display_name: str = field(init=False)
-    
-    def __post_init__(self):
-        self.display_name = f"{self.name} {self.size} {self.brand} ({self.unit})"
-
-@dataclass
-class Ingredient:
-    recipeIngredientID: int
-    quantityNeed: str  # API ส่งมาเป็น string (เช่น "1.000000")
-    material: Material
-
-@dataclass
-class Recipe:
-    recipeID: int
-    outputItemID: int
-    outputItemType: str  # คาดว่าจะเป็น "PRODUCT" หรือ "MATERIAL"
-    outputQuantity: int
-    ingredients: List[Ingredient]
-
-@dataclass
-class MachineDetail:
-    MachineDetailID: int
-    outputRate: int
-    changOver: Optional[float]
-    recipes: List[Recipe]
-
-@dataclass
-class Machine:
-    MachineID: int
-    name: str
-    type: str
-    lastMaintenanceDate: Optional[str]
-    status: str
-    notes: Optional[str]
-    machineDetails: List[MachineDetail]
-
-@dataclass
-class StockConfig:
-    stockConfigID: int
-    itemID: int
-    itemType: str  # "PRODUCT" หรือ "MATERIAL"
-    targetStockLevel: int
-    status: str
-    lastUpdated: str
-
-@dataclass
-class CleanDataSet:
-    products: List[Product]
-    materials: List[Material]
-    machines: List[Machine]
-    stock_configs: List[StockConfig]
-
-# ========================
-# Loader Functions
-# ========================
-
-def load_products() -> List[Product]:
-    products_data = requests.get(URLS["products"]).json()
-    # JSON ควรมี: ProductID, brand, size, unit, status, lowStockLevel, quantityInStock, pricePerUnit
-    return [Product(**p) for p in products_data]
-
-def load_materials() -> List[Material]:
-    materials_data = requests.get(URLS["materials"]).json()
-    # JSON ควรมี: MaterialID, name, size, brand, quantityInStock, lowStockLevel, status, ReorderLevel, unit, pricePerUnit, LastUpdate
-    return [Material(**m) for m in materials_data]
-
-def load_machines() -> List[Machine]:
-    machines_data = requests.get(URLS["machines"]).json()
-    machines = []
-    for m in machines_data:
-        machine_details = []
-        for md in m.get("machineDetails", []):
-            recipes = []
-            for r in md.get("recipes", []):
-                ingredients = []
-                for ing in r.get("ingredients", []):
-                    # สร้าง Material object จากข้อมูลใน ingredient
-                    mat_obj = Material(**ing["material"])
-                    ingredient_obj = Ingredient(
-                        recipeIngredientID=ing["recipeIngredientID"],
-                        quantityNeed=ing["quantityNeed"],
-                        material=mat_obj
-                    )
-                    ingredients.append(ingredient_obj)
-                recipe_obj = Recipe(
-                    recipeID=r["recipeID"],
-                    outputItemID=r["outputItemID"],
-                    outputItemType=r["outputItemType"],
-                    outputQuantity=r["outputQuantity"],
-                    ingredients=ingredients
-                )
-                recipes.append(recipe_obj)
-            md_obj = MachineDetail(
-                MachineDetailID=md["MachineDetailID"],
-                outputRate=md["outputRate"],
-                changOver=md.get("changOver"),
-                recipes=recipes
-            )
-            machine_details.append(md_obj)
-        machine_obj = Machine(
-            MachineID=m["MachineID"],
-            name=m["name"],
-            type=m["type"],
-            lastMaintenanceDate=m.get("lastMaintenanceDate"),
-            status=m["status"],
-            notes=m.get("notes"),
-            machineDetails=machine_details
-        )
-        machines.append(machine_obj)
-    return machines
-
-def load_stock_configs() -> List[StockConfig]:
-    configs_data = requests.get(URLS["stock_configs"]).json()
-    # JSON ควรมี: stockConfigID, itemID, itemType, targetStockLevel, status, lastUpdated
-    return [StockConfig(**cfg) for cfg in configs_data]
-
-def load_clean_dataset() -> CleanDataSet:
-    products = load_products()
-    materials = load_materials()
-    machines = load_machines()
-    stock_configs = load_stock_configs()
-    return CleanDataSet(
-        products=products,
-        materials=materials,
-        machines=machines,
-        stock_configs=stock_configs
-    )
-
-# ========================
-# ตัวอย่างการใช้งานและแสดงผล (Algorithm Sample)
-# ========================
-
-def main():
-    print("Loading clean dataset...")
-    data = load_clean_dataset()
-
-    # แสดง mapping ของ Products
-    print("\n=== Products Mapping ===")
-    for p in data.products:
-        print(f"ProductID: {p.ProductID} -> {p.name}")
-
-    # แสดง mapping ของ Materials
-    print("\n=== Materials Mapping ===")
-    for m in data.materials:
-        print(f"MaterialID: {m.MaterialID} -> {m.display_name}")
-
-    # แสดงสรุปของ Machine พร้อมรายละเอียด
-    print("\n=== Machines Summary ===")
-    for machine in data.machines:
-        print(f"\nMachineID: {machine.MachineID}, Name: {machine.name}, Type: {machine.type}, Status: {machine.status}")
-        for md in machine.machineDetails:
-            print(f"  MachineDetailID: {md.MachineDetailID}, OutputRate: {md.outputRate}, ChangeOver: {md.changOver}")
-            for r in md.recipes:
-                # Map ชื่อ output item จาก Product หรือ Material ตาม outputItemType
-                if r.outputItemType.upper() == "PRODUCT":
-                    output_name = next((p.name for p in data.products if p.ProductID == r.outputItemID), "Unknown")
-                elif r.outputItemType.upper() == "MATERIAL":
-                    output_name = next((m.display_name for m in data.materials if m.MaterialID == r.outputItemID), "Unknown")
-                else:
-                    output_name = "Unknown"
-                print(f"    RecipeID: {r.recipeID}, Produces: {output_name} ({r.outputItemType}) x {r.outputQuantity}")
-                for ing in r.ingredients:
-                    print(f"      Ingredient: {ing.material.display_name} x {ing.quantityNeed}")
-
-    # แสดงข้อมูล Stock Config ที่ map กับ Product/Material
-    print("\n=== Stock Configurations ===")
-    for sc in data.stock_configs:
-        if sc.itemType.upper() == "PRODUCT":
-            item_name = next((p.name for p in data.products if p.ProductID == sc.itemID), "Unknown")
-        elif sc.itemType.upper() == "MATERIAL":
-            item_name = next((m.display_name for m in data.materials if m.MaterialID == sc.itemID), "Unknown")
-        else:
-            item_name = "Unknown"
-        print(f"ConfigID: {sc.stockConfigID}, Item: {item_name} (ItemID: {sc.itemID}, {sc.itemType}), TargetStock: {sc.targetStockLevel}, Status: {sc.status}, LastUpdated: {sc.lastUpdated}")
-
-if __name__ == "__main__":
-    main()
diff --git a/src/queues/AutoQueue/requirements.txt b/src/queues/AutoQueue/requirements.txt
deleted file mode 100644
index 1af22b69b4ab43e0619cceaf8a751e4088c0947b..0000000000000000000000000000000000000000
--- a/src/queues/AutoQueue/requirements.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-simpy
-pandas
-matplotlib
-numpy
-fastapi
-uvicorn
\ No newline at end of file
diff --git a/src/queues/AutoQueue/testAllapi.py b/src/queues/AutoQueue/testAllapi.py
deleted file mode 100644
index d4d4bc09651c7fc9ff12d3a9de81dfbacb01d164..0000000000000000000000000000000000000000
--- a/src/queues/AutoQueue/testAllapi.py
+++ /dev/null
@@ -1,132 +0,0 @@
-import requests
-import sys
-import os
-
-# ปรับ encoding สำหรับ Windows ให้รองรับภาษาไทยและ emoji
-if os.name == "nt":
-    sys.stdout.reconfigure(encoding="utf-8")
-
-# กำหนด API endpoints
-API_BASE = "http://localhost:4000"
-URLS = {
-    "products": f"{API_BASE}/products",
-    "materials": f"{API_BASE}/materials",
-    "machines": f"{API_BASE}/machines",
-    "stock_configs": f"{API_BASE}/stock-config",
-}
-
-# Dictionary สำหรับเก็บ mapping
-# สำหรับ Products: key คือ ProductID, value คือ ชื่อผลิตภัณฑ์
-product_map = {}
-# สำหรับ Materials: key คือ MaterialID, value คือ ชื่อวัสดุ
-material_map = {}
-
-def preload_items():
-    """โหลดข้อมูล Products และ Materials ก่อน เพื่อใช้ในการ map itemID"""
-    print("📥 กำลังโหลด Products...")
-    try:
-        products = requests.get(URLS["products"]).json()
-        for p in products:
-            # ตัวอย่างชื่อผลิตภัณฑ์: "A 350 ml (ขวด)"
-            name = f"{p['brand']} {p['size']} ({p['unit']})"
-            product_map[p['ProductID']] = name
-    except Exception as e:
-        print("❌ ไม่สามารถโหลด Products ได้:", e)
-    
-    print("📥 กำลังโหลด Materials...")
-    try:
-        materials = requests.get(URLS["materials"]).json()
-        for m in materials:
-            # ตัวอย่างชื่อวัสดุ: "Preform (ขวด) any any (ขวด)"
-            name = f"{m['name']} {m['size']} {m['brand']} ({m['unit']})"
-            material_map[m['MaterialID']] = name
-    except Exception as e:
-        print("❌ ไม่สามารถโหลด Materials ได้:", e)
-
-def log_item_mappings():
-    """แสดงผล mapping ของ Products และ Materials เพื่อตรวจสอบ itemID กับ itemType"""
-    print("\n==== Mapping ของ Products ====")
-    for pid, name in product_map.items():
-        print(f"  - ProductID: {pid} -> {name}")
-        
-    print("\n==== Mapping ของ Materials ====")
-    for mid, name in material_map.items():
-        print(f"  - MaterialID: {mid} -> {name}")
-
-def log_machines():
-    """แสดงข้อมูลของ Machines พร้อมรายละเอียด (machineDetails + recipes)"""
-    try:
-        machines = requests.get(URLS["machines"]).json()
-    except Exception as e:
-        print("❌ ไม่สามารถโหลด Machines ได้:", e)
-        return
-
-    # แสดงข้อมูลสรุปของแต่ละเครื่อง
-    for i, machine in enumerate(machines, 1):
-        print(f"\n🚀 Machine #{i}")
-        print(f" - MachineID: {machine['MachineID']}")
-        print(f" - Name: {machine['name']}")
-        print(f" - Type: {machine['type']}")
-        print(f" - Status: {machine['status']}")
-    
-    # แสดงรายละเอียด machineDetails และ recipes
-    print("\n🔧 รายละเอียดเครื่องจักร (MachineDetails + Recipes):")
-    for machine in machines:
-        for detail in machine.get("machineDetails", []):
-            print(f"\n🛠️ MachineDetailID: {detail['MachineDetailID']}")
-            print(f" - Machine: {machine['name']} (ID {machine['MachineID']})")
-            print(f" - OutputRate: {detail['outputRate']} units/hr")
-            print(f" - ChangeOver: {detail['changOver']} min")
-            for recipe in detail.get("recipes", []):
-                output_id = recipe["outputItemID"]
-                output_type = recipe["outputItemType"]
-                # ตรวจสอบ itemType เพื่อ map ชื่อผลิตภัณฑ์หรือวัสดุ
-                if output_type.upper() == "PRODUCT":
-                    output_name = product_map.get(output_id, "❓ไม่ทราบชื่อ")
-                elif output_type.upper() == "MATERIAL":
-                    output_name = material_map.get(output_id, "❓ไม่ทราบชื่อ")
-                else:
-                    output_name = "ไม่ทราบ"
-                print(f"\n   📦 RecipeID: {recipe['recipeID']}")
-                print(f"    - ผลิต: {output_name} ({output_type})")
-                print(f"    - จำนวนที่ผลิต: {recipe['outputQuantity']}")
-                print("    - วัตถุดิบ:")
-                for ing in recipe.get("ingredients", []):
-                    mat = ing["material"]
-                    # สามารถเพิ่มข้อมูลอื่นๆ ของวัสดุจาก mapping ถ้าต้องการ
-                    print(f"      · {mat['name']} ({mat['size']}, {mat['brand']}) x {ing['quantityNeed']}")
-                    
-def log_stock_configs():
-    """แสดงข้อมูล Stock Config พร้อมแปล itemID และ itemType ให้เข้าใจง่าย"""
-    try:
-        configs = requests.get(URLS["stock_configs"]).json()
-    except Exception as e:
-        print("❌ ไม่สามารถโหลด Stock Configs ได้:", e)
-        return
-
-    print("\n📦 Stock Configuration:")
-    for i, cfg in enumerate(configs, 1):
-        item_id = cfg["itemID"]
-        item_type = cfg["itemType"].upper()
-        # map ตาม itemType ว่าใช้ product_map หรือ material_map
-        if item_type == "PRODUCT":
-            name = product_map.get(item_id, "❓ไม่ทราบชื่อ")
-        elif item_type == "MATERIAL":
-            name = material_map.get(item_id, "❓ไม่ทราบชื่อ")
-        else:
-            name = "ไม่ทราบ"
-        print(f"\n🔧 Config #{i}")
-        print(f" - Item: {name} (ItemID: {item_id}, {item_type})")
-        print(f" - เป้าหมายสต๊อก: {cfg['targetStockLevel']}")
-        print(f" - สถานะ: {cfg['status']}")
-        print(f" - แก้ไขล่าสุด: {cfg['lastUpdated']}")
-
-if __name__ == "__main__":
-    # โหลดข้อมูลสินค้าและวัสดุก่อน
-    preload_items()
-    # แสดงผล mapping เพื่อตรวจสอบ
-    log_item_mappings()
-    # แสดงข้อมูลเครื่องจักรและสูตรการผลิต
-    log_machines()
-    # แสดงข้อมูล Stock Config
-    log_stock_configs()