Skip to content

2way-vtrc-api — Repository Map

บทนี้เป็นแผนที่ไฟล์ของ 2way-vtrc-api (branch: prod, ~158 tracked files) — Express monolith ที่ mount route ทีละไฟล์ ไม่มี NestJS module boundary

ชื่อ package คือ "express" (2way-vtrc-api/package.json:2) — ไม่ตรงกับชื่อ repo


แผนที่โฟลเดอร์ระดับ repo

2way-vtrc-api/                          (branch: prod)
├── app.ts                              # entrypoint เดียว (~286 บรรทัด): Sentry, CORS, ~50 route mounts, socket.io
├── config.ts                           # LINE_CHANNEL_SECRET / LINE_CHANNEL / LINE_AUTH จาก process.env
├── package.json                        # name=express, start=ts-node app.ts
├── Dockerfile                          # node:18-alpine3.15, yarn, EXPOSE 3000 (ไม่ตรง listen 8001)
├── docker-compose.yml                  # ports 8001:8001, volume storage/2way
├── .env / .env.prod / .env.uat / .envdev
├── tsconfig.json / jest.config.js / .eslintrc.json
├── middleware/
│   ├── checkbypasstoken.ts             # checkBypassTokenMiddleWare + checkApiKeyMiddleWare (+ "testnaja")
│   ├── checkByPassTokenLine.ts         # LINE access-token verify (+ "testnaja")
│   ├── checkbypasswhenredirect.ts
│   ├── checkbypaasjwtOTP.ts            # typo ในชื่อไฟล์: bypaas
│   ├── checkbypass.ts
│   ├── jwtpassport.ts                  # passport-jwt — always done(null, true)
│   ├── authologin.ts
│   └── validator/{createIncident,updateincident}.ts
├── model/                              # Sequelize factories (MSSQL)
│   ├── announcement/, autoReply/, faqs/, feedback/, incident/, survey/
│   ├── userLine/{userLine,userProfile}.ts
│   ├── otp/otp.ts, token/token.ts
│   ├── login.ts, post.ts, commentpost.ts
│   └── mongo/chatSchema.ts             # Mongoose schema (chat)
├── util/
│   ├── db.config.ts                    # Sequelize instance + model registry
│   ├── env.ts                          # MSSQL host/user/password hardcode (Prod block active)
│   ├── mongo.config.ts                 # Mongo URI hardcode (connection ปิดใน app.ts)
│   ├── jwt.config.ts                   # SECRET hardcode + jwtExpiration=60 (test values)
│   ├── helper/{empty,jwtdecode,transferData}.ts
│   ├── axiosinterceptors/{cdb,vtrc}.connector.ts
│   ├── emailtemplate/
│   └── line/
├── lib/
│   ├── Socket.func.ts / InsertChat.func.ts / InsertChatBot.func.ts
│   ├── Uploadimage.class.ts / Dateformat.class.ts / Emailsender.class.ts
│   ├── Usermanage.class.ts / Otp.ts / helper.ts / model.ts (syncModelToTable — ปิดใน app.ts)
├── routes/
│   ├── auth/{login,redirectbypass,refreshtoken}.ts
│   ├── secure/post.ts
│   ├── post.ts, commentpost.ts
│   ├── MeetingAPI/{user,index,mock}.ts # mock / JSONPlaceholder-style
│   ├── TwoWayAPI/
│   │   ├── index.ts                    # mock aggregator (~1849 บรรทัด)
│   │   ├── mock.ts
│   │   ├── announcement/ (8 files)
│   │   ├── autoReply/ (4)
│   │   ├── chatCenter/ (3)             # mount ถูก comment ใน app.ts
│   │   ├── faqs/ (6)
│   │   ├── feedback/ (9)
│   │   ├── incident/ (9)
│   │   ├── survey/ (9)
│   │   ├── sso/ (5)
│   │   ├── userLine/ (5)
│   │   ├── userLineCu/ (4)
│   │   └── userLine_bk/                # legacy backup — อย่าลบโดยไม่ตรวจ
│   ├── WebHookApi/                     # LINE OA หลัก (RC)
│   ├── WebHookCuApi/                   # LINE OA ฝั่ง CU
│   └── Feedback/                       # (ถ้ามี)
├── storage/2way/                       # ไฟล์อัปโหลด — serve ที่ /2way/file
├── __test__/ / coverage/ / ut-report/
└── test-report.html

Boot sequence — จาก yarn start ถึง listen

Production / container entry คือ ts-node app.ts (package.json:7). ลำดับใน app.ts:

1. import express, Sentry, Tracing
       │  app.ts:2-4

2. const port = 8001  (hardcode)
       │  app.ts:8

3. // require('./util/mongo.config.ts');   ← Mongo ปิด
       │  app.ts:10

4. app.disable('x-powered-by') / disable('Server')
       │  app.ts:14-15

5. Swagger UI ที่ /docs  (title ยังเป็น JSONPlaceholder)
       │  app.ts:20-51

6. Sentry.init({ dsn: hardcode, tracesSampleRate: 1.0 })
       │  app.ts:53-68

7. dotenv.config({ path: ".env" })
       │  app.ts:70-72

8. Sentry request / tracing / error handlers
       │  app.ts:74-77

9. static /2way/file → storage/2way/
       │  app.ts:80

10. bodyParser json 50mb + urlencoded
       │  app.ts:83-84

11. CORS headers: Origin *, Credentials true
       │  app.ts:87-99

12. Mount ~50 routers (ดูตารางด้านล่าง)
       │  app.ts:101-263

13. // syncModelToTable();   ← schema sync ปิด
       │  app.ts:265

14. app.listen(8001)
       │  app.ts:267

15. socket.io แนบ HTTP server, cors origin:*
       │  app.ts:270-282

16. io.on("connection", chatHandler)
       app.ts:277-282

ข้อควรจำ: ไม่มี global auth guard — แต่ละ route ไฟล์เลือก middleware เอง หรือไม่ใส่เลย


Route registration pattern

app.ts mount router 1 ไฟล์ = 1 endpoint แบบ manual ไม่มี aggregator กลางสำหรับ production routes (ยกเว้น mock ที่ /2way/TwoWayAPI)

พบ comment เลขนับ endpoint ค้างอยู่ (//7, //14, //23, //32, //39, //43, //48, app.ts:132,147,167,197,212,221,232) — หลักฐานว่าทีมเพิ่ม endpoint ทีละตัวต่อเนื่องโดยไม่มี refactor เป็น controller group

Pattern ในแต่ละไฟล์ route โดยทั่วไป:

typescript
const route = express.Router();
route.post("/", checkBypassTokenMiddleWare, async (req, res) => { ... });
module.exports = route;

แล้ว mount ใน app.ts เป็น app.use('/2way/somePath', require('./routes/...'))


Endpoint catalog — production mounts ใน app.ts

ตารางนี้รวบรวม path ที่ app.use จริงใน app.ts (branch: prod) พร้อมประเภท auth ที่ route handler ใช้

Legacy / scaffold / mock

Mount pathไฟล์Auth ที่ handler ใช้
/2way/postroutes/post.tsไม่ใช้ bypass middleware หลัก
/2way/secure/postroutes/secure/post.tscheckBypassTokenMiddleWare บน /checkauth
/2way/loginroutes/auth/login.tsผสม — บาง path มี bypass, บาง path ไม่มี
/2way/commentpostroutes/commentpost.tsบาง mutation มี bypass; GET หลายตัวไม่มี
/2way/MeetingAPIroutes/MeetingAPI/user.tsmock — ไม่ query DB จริง
/2way/TwoWayAPIroutes/TwoWayAPI/index.tsmock — ตอบข้อมูลปลอม
/2way/WebHookApiroutes/WebHookApi/index.tsLINE webhook (ไม่มี Bearer bypass)
/2way/cu/webHookApiroutes/WebHookCuApi/index.tsLINE webhook CU

Incident (7 + 2 Line variants)

Mount pathไฟล์Auth
/2way/getListIncidentincident/getListIncident.tscheckBypassTokenMiddleWare
/2way/addNewIncidentincident/createIncident.tscheckBypassTokenMiddleWare + validator
/2way/dropdownIncidentTypeincident/dropdownIncidentType.tscheckBypassTokenMiddleWare
/2way/dropdownIncidentProgressStatusincident/dropdownIncidentProgressStatus.tscheckBypassTokenMiddleWare
/2way/getAllAndCountProgressStatusincident/getAllAndCountProgressStatus.tscheckBypassTokenMiddleWare
/2way/updateIncidentincident/updateIncident.tsไม่มี auth middleware — มีแค่ validatorUpdateIncident (updateIncident.ts:23)
/2way/getListIncidentByUserIDincident/getListIncidentByUserID.tscheckBypassTokenMiddleWare
/2way/addNewIncidentLineincident/createIncidentLine.tscheckBypassTokenLineMiddleWare
/2way/dropdownIncidentTypeLineincident/dropdownIncidentTypeLine.tscheckBypassTokenLineMiddleWare

Feedback (7 + 2 Line)

Mount pathไฟล์Auth
/2way/getListFeedbackfeedback/getListFeedback.tsbypass token
/2way/dropdownFeedbackTypefeedback/dropdownFeedbackType.tsbypass token
/2way/addNewFeedbackfeedback/createFeedback.tsbypass token
/2way/updateIsNewFeedbackfeedback/updateIsNewFeedback.tsbypass token
/2way/updateCallbackStatusFeedbackfeedback/updateCallbackStatusFeedback.tsbypass token
/2way/getAllAndCountCallbackStatusfeedback/getAllAndCountCallbackStatus.tsbypass token
/2way/dropdownCallbackStatusfeedback/dropdownCallbackStatus.tsbypass token
/2way/dropdownFeedbackTypeLinefeedback/dropdownFeedbackTypeLine.tsLINE bypass
/2way/addNewFeedbackLinefeedback/createFeedbackLine.tsLINE bypass

Survey (9)

Mount pathAuth
/2way/getListSurveybypass token
/2way/addNewSurveybypass token
/2way/getUserByConditionbypass token
/2way/dropdownOrg / dropdownDivision / dropdownDepartmentbypass token
/2way/updateSurveybypass token
/2way/updateIsReadedSurveyLINE bypass
/2way/getListSurveyByUserIDLINE bypass

UserLine RC + CU

Mount pathไฟล์Auth
/2way/verifyUserLineuserLine/verifyUserLine.tsไม่มี middleware บน route.post (import bypass แต่ไม่ได้ใส่ใน chain — verifyUserLine.ts:28)
/2way/verifyOTPUserLineuserLine/verifyOTPUserLine.tsไม่มี
/2way/createUserLineuserLine/createUserLine.tscheckBypassJWTMiddleWare
/2way/verifyUserLine/cuuserLineCu/verifyUserLine.tsไม่มีบน chain
/2way/verifyOTPUserLine/cuuserLineCu/verifyOTPUserLine.tsไม่มี
/2way/createUserLine/cuuserLineCu/createUserLine.tscheckBypassJWTMiddleWare
/2way/getProfileuserLine/getProfile.tsไม่มี (auth comment ปิด)
/2way/getProfile/cuuserLineCu/getProfile.tsไม่มี (auth comment ปิด)
/2way/verifyTokenuserLine/verifyToken.tscheckBypassMiddleWare

FAQs / Announcement / AutoReply / SSO

กลุ่มMount prefix ตัวอย่างAuth หลัก
FAQs/2way/getListFAQs, addNewFAQs, updateFAQs, updateStatusFAQs, sendMessageLineFAQsStepYes, createQuestionbypass token
Announcement/2way/getListAnnouncement, addNewAnnouncement, …, getListAnnouncementByUserID, updateCountReadedAnnouncement, updateIsAcceptAnnouncementadmin = bypass token; user-facing = LINE bypass
AutoReply/2way/getListAutoReply, addNewAutoReply, updateAutoReply, updateStatusAutoReplybypass token
SSO/2way/loginSSO, changePasswordSSO, verifyUserNonEmp, verifyOTPNonEmp, changePasswordNonEmpForgetไม่มี auth middleware บน route.post("/")
Misc/2way/redirectbypasscheckBypassWhenRedirectMiddleWare
Test/2way/getListAnnouncementForTestbypass token

Commented-out mounts (มีไฟล์ แต่ไม่ live)

Path ที่เคยตั้งใจไฟล์สถานะใน app.ts
/2way/getListChatchatCenter/getListChat.tscomment ปิด (app.ts:245-250)
/2way/getChatMessageByIDchatCenter/getChildListChat.tscomment ปิด
/2way/updateReadedMessagechatCenter/updateReadedMessage.tscomment ปิด
/2way/getUserEveryObjectsurveycomment ปิด (app.ts:234-235)

แม้ HTTP chat routes จะปิด socket.io ยัง bind chatHandler ที่ app.ts:277-282


Sequelize models ↔ โมดูลธุรกิจ

Registry ใน util/db.config.ts:29-40:

db1 keyไฟล์ modelใช้โดย
postmodel/post.tsroutes/post.ts, secure post
loginmodel/login.tsroutes/auth/login.ts
incidentmodel/incident/incident.tsTwoWayAPI/incident/*
feedbackmodel/feedback/feedback.tsTwoWayAPI/feedback/*
surveymodel/survey/survey.tsTwoWayAPI/survey/*
userLinemodel/userLine/userLine.tsregistration / profile
userLineProfilemodel/userLine/userProfile.tsCU profile variants
faqsmodel/faqs/faqs.tsFAQs
announcementmodel/announcement/announcement.tsannouncement
autoReplymodel/autoReply/autoReply.tsauto-reply
otpmodel/otp/otp.tsOTP SSO / LINE register
tokenmodel/token/token.tscheckBypassTokenMiddleWareToken.findOne

Incident model exports

model/incident/incident.ts คืน object:

typescript
return { IncidentType, IncidentRunning, IncidentEdit, Attachment, AttachType, Incident, ProgressStatus, Remark };

แหล่ง: 2way-vtrc-api/model/incident/incident.ts:336

Associations ที่ define ไว้ (ตัวอย่าง): Incident.belongsTo(IncidentType), Incident.hasMany(Attachment), Remark.belongsTo(Incident) (incident.ts:312-328)

UserLine fields

ตาราง userLine มี userID, identityCard, birthDate, lineID, userType (default 'RC'), richMenuID, isActive (model/userLine/userLine.ts:11-33)

Token fields

ตาราง token มี tokenTwoWay, profileKey, loginType, createDate (model/token/token.ts:11-23) — ใช้เทียบ Bearer กับแถวใน DB

Mongo chat schema

model/mongo/chatSchema.ts define collection "conversation" ด้วย channel, countNotRead, replyToken, updateDate, chat[] (chatSchema.ts:22-43)


Middleware inventory

ไฟล์Export หลักพฤติกรรมสั้น ๆ
checkbypasstoken.tscheckBypassTokenMiddleWare, checkApiKeyMiddleWareBearer → decode JWT ด้วย SECRET_JWT_TWOWAYToken.findOne; หรือ token == "testnaja"; API key เทียบ process.env.API_KEY
checkByPassTokenLine.tscheckBypassTokenLineMiddleWareverify LINE access token → get profile → หา UserLine; หรือ "testnaja"
jwtpassport.tsrequireJWTAuthStrategy เรียก done(null, true) ทันที — ไม่เช็ค payload จริง (jwtpassport.ts:9-12)
validator/createIncident.tsvalidatorCreateIncidentexpress-validator ก่อน insert
validator/updateincident.tsvalidatorUpdateIncidentexpress-validator ก่อน update

โค้ดตัวอย่าง / mock ที่ยัง mount ใน production path

/2way/TwoWayAPIroutes/TwoWayAPI/index.ts (~1849 บรรทัด)

Mount ที่ app.ts:112-113. Endpoints ตัวอย่าง:

MethodSub-pathพฤติกรรม
POST/RegisterLineUserตรวจ isEmpty(body) แล้วตอบ Success — ไม่เขียน DB (index.ts:196-259)
POST/NewIncidentmock
POST/GetSurveyListByUser, /CreateSurvey, …mock จาก ./mock
POST/NewFeedback, /FeedbackListmock
POST/NewAnnouncement, /AnnouncementList, …mock
GET/debugsentrydebug Sentry (index.ts:1825)

Swagger comment ในไฟล์ยังอ้าง "Retrieve a list of JSONPlaceholder users" (index.ts:217-218)

/2way/MeetingAPIroutes/MeetingAPI/user.ts

Mount ที่ app.ts:110-111. ชื่อ path มีคำว่า Meeting แต่ ไม่เกี่ยวกับ Meeting Platform group (meeting-vtrc-api / meeting-backoffice) — เป็นโค้ดตัวอย่างที่ตั้งชื่อ path ไว้


Lib helpers ที่ route พึ่งพา

ไฟล์บทบาท
lib/Uploadimage.class.tsอัปโหลด base64 → storage/2way/
lib/Dateformat.class.tsformat วันที่
lib/Emailsender.class.tsnodemailer (login/register flows)
lib/Otp.tsOTP generation/verify
lib/Socket.func.tssocket event sendMessage → Mongo Chat + LINE push
lib/InsertChat.func.ts / InsertChatBot.func.tsเขียน chat message
lib/model.tssyncModelToTable() — ปิดการเรียกใน app.ts:265

Tests / tooling

  • jest + ts-jest (package.json:10,64,68)
  • __test__/test.spec.ts มีอยู่
  • coverage/ และ test-report.html commit ค้างใน repo
  • ไม่มี Bitbucket/GitHub Actions pipeline ใน root ของ repo นี้ (ไม่มี bitbucket-pipelines.yml ในรายการไฟล์ที่ตรวจ)

สิ่งที่อยู่นอกขอบเขตบทนี้