Skip to content

2way-meeting-backoffice — Persistence & Integrations

2way-meeting-backoffice (branch: prod) ไม่มีฐานข้อมูลของตัวเอง — เป็น Next.js frontend ล้วน ข้อมูลทั้งหมดมาจาก HTTP/WebSocket ไปยัง backend อื่น ไม่พบ Prisma / TypeORM / Mongoose / DB driver ใน package.json

ค่า APP_CONNECT_DB_* และ APP_CONNECT_SMTP_* ใน .env* ถูก map ใน next.config.js:61-68 แต่ไม่มีโค้ดที่เปิด connection — remnant จาก scaffold reportmonitor


Integration map (ภาพรวม)

Browser (basePath /2way-backoffice)

├──[admin L2]──► 2way-api          (appConnectAPI)
│                  auth / surveys / announces / employee / complaints

├──[admin L2]──► chat-center-api   (appConnectChatCenterAPI + fetchRedCrossAPI/chatCenterPath)
│                  rooms / teamAdmin / tags / appointment / satisfaction
│                  ▲
│                  └── WebSocket wss://... path /chat-center-ws/socket.io

├──[LIFF + FAQ]─► 2way-vtrc-api    (appConnectChatAPI = APP_CONNECT_API_BASIC)
│                  getProfile / register / FAQs

├──[incident]───► incident-management-api  (appConnectIncidentAPI)  [UNVERIFIED repo]

└──[observability]► Sentry (client+server init; webpack plugin commented out)

Integration 1 — 2way-api (NestJS)

Config

Env fileค่า
.env.production:6APP_CONNECT_API=https://vtrcapi.redcross.or.th/2way-api
.env.uat:6https://uat-vtrcapi.redcross.or.th/2way-api
Clientprocess.env.appConnectAPI (next.config.js:53)

ขอบเขตการใช้งาน

  • Auth: login, verifyToken, redirectbypass, Forgot password flows
  • Announces CRUD + types
  • Surveys CRUD + summary + adminApprove/adminReject
  • Employee org tree dropdowns
  • Complaints/Feedback multi-step approval

ยืนยัน alignment กับ backend: path api/v1/surveys/types ตรงกับ 2way-api @Controller('surveys') (ดูเอกสาร volume ของ 2way-api)

ความเสี่ยงข้าม repo

Login ยิง endpoint เดียวกับที่มี backdoor credential ใน 2way-api (SEC-2WAYAPI-01) — ความปลอดภัยของหน้า Login จึงพึ่งพา backend โดยตรง


Integration 2 — chat-center-api (Domain Microservice)

Config สองทางที่ชี้ปลายทางเดียวกัน

กลไกประกอบ URL อย่างไร
appConnectChatCenterAPIabsolute base จาก APP_CONNECT_API_CHAT เช่น https://vtrcapi.../chat-center-api/api/v1 แล้วต่อ /teamAdmin/list
fetchRedCrossAPI + chatCenterPath${APP_PATH} + chat-center-api/api/v1 + /chat/rooms

ทั้งคู่ต้องชี้ host เดียว — production: vtrcapi.redcross.or.th (.env.production:7,10)

REST surface ที่ frontend เรียก (ยืนยันจากโค้ด)

ฟังก์ชัน / call siteMethodPath (หลัง base)
getTeamAdminListGET/teamAdmin/list
teamAdmin create/updatePOST/PUT/teamAdmin, /teamAdmin/{teamId}
listMember searchGET/teamAdmin/listMember?fullName=
listCareTakerGET/POST/teamAdmin/listCareTaker
getTagListGET/tags/list
getChatRoomListGET/chat/rooms
putChatRoomPUT/chat/{id}
putOpenChatRoomPUT/chat/open/{id}
chat historyGET/chat/chatRoomHistory?roomEmpCode=
getChatListNotiGET/chat/listNoti
putChatNotiPUT/chat/Noti/{id}
getChatRoomStatusHistoryGET/chat/roomStatusHistory
postCreateChatHistoryPOST/createChatHistory
appointmentGET/POST/PUT/appointment, /appointment/{id}
satisfaction reportGET/satisfactedurvey/reportServey
satisfaction public/genPOST/satisfactedurvey/public, /genSurvey

แหล่ง: utils/chatCenterApi.tsx ทั้งไฟล์ + ChatCenter/index.tsx + NotificationListForm.tsx + teamAdminModal/*

WebSocket

tsx
io.connect(`${process.env.appConnectWebSocket}`, {
  transports: ["websocket"],
  path: "/chat-center-ws/socket.io",
});

(ChatCenter/index.tsx:173-176)

  • Production WS host: wss://vtrcapi.redcross.or.th (.env.production:11)
  • Path แยกจาก REST prefix — reverse proxy ต้อง route /chat-center-ws/ ไป chat-center service

Cross-group coupling

chat-center-api อยู่ในกลุ่ม Domain Microservices ตาม workspace map — repo นี้ในกลุ่ม 2way Platform เรียกข้ามกลุ่มโดยตรง ควรบันทึกใน canonical truths

Hardcoded room ใน services/chat-center.tsx

tsx
`${process.env.appConnectChatCenterAPI}/chat/chatRoomHistory?roomEmpCode=${"U4bc7f4b3936c4eebf2e1aabf72e1caab"}`

(services/chat-center.tsx:6) — ค่าทดสอบค้าง; หน้า ChatCenter จริงใช้ chatRoom?.empCode แทน (index.tsx:109)


Integration 3 — 2way-vtrc-api (Express legacy) ผ่าน appConnectChatAPI

Config

ShellAPP_CONNECT_API_BASIC=https://vtrcapi.redcross.or.th/2way (.env.production:9)
ClientappConnectChatAPI (next.config.js:57)
ชื่อที่ทำให้สับสนมีคำว่า "Chat" แต่ไม่ใช่ chat-center

Endpoints ที่ยืนยันจาก call sites

Pathใช้ที่
/getProfileAnnounce, Survey, Complaint, Incident (LIFF)
/verifyUserLine, /verifyOTPUserLine, /createUserLineRegister RC
/verifyUserLine/cu, /verifyOTPUserLine/cu, /createUserLine/cuRegisterCu
/getListFAQs, /createQuestion , /sendMessageLineFAQsStepYesProblem LIFF
/getListFAQs, /addNewFAQs, /updateFAQs, /updateStatusFAQsQuestion backoffice
/appointmentNotificationListForm.tsx:77 (POST ไป appConnectChatAPI — คนละ base กับ chat-center appointment)
/dropdownDivision, /dropdownDepartment, /getUserByConditionemployee picker ใน Announce (อ้างจากเอกสารเดิม + Form paths)

ข้อสรุป canonical: backend หลักของหน้าฝั่งพนักงานคือ 2way-vtrc-api ไม่ใช่ NestJS 2way-api


Integration 4 — LINE LIFF (@line/liff)

  • Dynamic import ใน _app.tsx:90-93 เมื่อ path เป็น line / line-cu
  • liff.init({ liffId }) แล้วบังคับ liff.login ถ้ายังไม่ login (:97-99)
  • LIFF ID แยก RC/CU และ prod/non-prod (ตารางใน 02-core-pipeline)
  • ใช้ระบุตัวผู้ใช้ LINE แทน username/password ของ backoffice
  • มีไฟล์ backup _app.tsx.bk ใน pages — legacy backup ตามกฎ workspace

Integration 5 — incident-management-api (UNVERIFIED)

Config

APP_CONNECT_API_INCIDENT → production https://vtrcapi.redcross.or.th/incident-management-api (.env.production:8)

Call sites

ไฟล์Path
services/line/incidents.tsx:6/master/list/003
services/line/incidents.tsx:14+/incidents/list/empCode/{empCode}, /incidents/{id}
ChatCenter/index.tsx:146/incidents/chat-center/list/{empCode}

Repo incident-management-api ไม่มีใน workspace ณ เวลาเขียนเอกสาร — โครงสร้าง auth/schema ฝั่ง server ยืนยันไม่ได้ → ระบุ UNVERIFIED


Integration 6 — Sentry (@sentry/nextjs)

ไฟล์ที่เกี่ยวข้อง

ไฟล์บทบาท
sentry.client.config.jsSentry.init ฝั่ง browser
sentry.server.config.jsSentry.init ฝั่ง Node (SSR / API routes ของ Next)
src/pages/_error.tsxSentry.captureException + flush(2000)
next.config.js:11-23,79-80withSentryConfig ถูก comment ออก — export moduleExports ตรง ๆ

Init options

js
Sentry.init({
  dsn: SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN
       || 'https://…@o1092051.ingest.sentry.io/6113872',  // hardcoded fallback
  tracesSampleRate: 1.0,
});

(sentry.client.config.js:7-12, sentry.server.config.js:7-12)

ข้อสังเกต:

  1. DSN fallback ถูก commit ใน repo — ถ้า env ไม่ตั้ง DSN ก็ยังส่ง event ไป org ที่ hardcode
  2. tracesSampleRate: 1.0 = ส่งทุก transaction (ต้นทุน/噪声 สูงใน production)
  3. Webpack plugin สำหรับ upload source map ไม่ได้เปิด เพราะ withSentryConfig comment ออก (next.config.js:79-80) — stack trace ใน Sentry อาจไม่มี source map จาก build นี้
  4. _error.tsx จับ error ของ Next pages และเรียก Sentry.captureException ทั้ง client workaround และ getInitialProps (_error.tsx:18,52,65-67)

สิ่งที่ Sentry ไม่ครอบ

  • Axios error ที่ถูก resolve(error) ใน wrapper — ไม่ throw → ไม่ถึง Error Boundary / _error โดยอัตโนมัติ
  • console.log ของ production ถูก mute ใน _app แต่ไม่ใช่ Sentry breadcrumb pipeline

Integration 7 — i18n และ static public assets

  • next-i18next: locales th, en; defaultLocale: 'th'; localeDetection: false (next-i18next.config.js:2-6)
  • ไฟล์แปลอยู่ที่ public/locales/{th,en,de}/ — มี de ในโฟลเดอร์แต่ config ไม่ใส่ de ใน locales array
  • Navbar / menu มาจาก JSON ใต้ public/mockDatas/ ไม่ใช่จาก API

Group / Approver admin — สรุปตำแหน่งในระบบนี้

คำว่า "approver admin" ในบริบท repo นี้แตกเป็นหลายกลไก (ไม่ใช่ meeting approver):

กลไกที่อยู่Backend
Chat Center teamAdmin (ทีม + สมาชิก + tags)ChatCenter/adminchat-center-api /teamAdmin/*
Survey adminApprove / adminRejectservices/surveys.tsx2way-api
Complaint adminAssign / secretary / superAdmin*Feedback/Edit/Form.tsx2way-api /api/v1/complaints/*
Announce contentAssigns (ผู้รับประกาศ)Announce/*/Form.tsx + employee.tsx2way-api announces
profile.level === 1isSuperAdminutils/auth.tsx:71ใช้ใน UI เงื่อนไขสิทธิ์

Embedded / build artifacts

Artifactสร้างจากDeploy ใช้จริง?
.next/yarn buildใช่ — Docker copy เข้า runner (Dockerfile:31)
out/yarn out / yarn export (package.json:9,14)Script มี; pipeline หลักใช้ next start ไม่ใช่ static host จาก out/
Docker imagebitbucket-pipelines.yml build-docker-imagePush GCP registry พร้อม tag commit
.env.production ใน imageDockerfile:27ฝังใน image — เปลี่ยน API host ต้อง rebuild

ไม่มีโฟลเดอร์ build/ แบบ CRA — เป็น Next .next ล้วน


สิ่งที่ไม่มี (อย่าสมมติ)

  • ไม่เชื่อม meeting-vtrc-api / meeting-backoffice / meeting-backoffice-new
  • ไม่เชื่อม GraphQL ของ vtrc-api / Apollo
  • ไม่มี Redis / queue client ฝั่ง frontend
  • ไม่มี Prisma schema / migration ใน repo นี้