Skip to content

Admin area - #42

Merged
nhitt-1337 merged 23 commits into
masterfrom
admin_area
Oct 1, 2026
Merged

nhitt-1337 merged 23 commits into
masterfrom
admin_area

Conversation

@nhitt-1337

Copy link
Copy Markdown
Collaborator

No description provided.

nhitt-1337 and others added 23 commits September 25, 2026 13:10
server.servlet.context-path bao toan bo ung dung nen khu quan tri sap lam
se bi keo vao /api/v1/admin. Thay bang ApiPathConfig: gan tien to /api/v1
cho rieng package demo.tripgo.controller, controller o package khac khong
dinh gi. URL cong khai cua API khong doi mot ky tu nao.

Hai cho phai sua theo, neu quen se hong am tham:
- SecurityConfig: servlet container khong con tach context-path nen moi
  requestMatchers phai gom ca /api/v1.
- RateLimitFilter loc theo path.startsWith("/auth/") -> chong brute-force
  login se tat ma khong bao loi gi.

Swagger UI doi cho: /api/v1/swagger-ui.html -> /swagger-ui.html.
Cac endpoint trong tai lieu van ghi /api/v1/... nhu cu.

Test: bo 210 loi goi .contextPath()/.servletPath() o 10 file.
UnlistedController cua test nam ngoai package controller nen tu khai tien to.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Them SecurityFilterChain rieng cho /admin/**, nguoc hoan toan voi chain API:
co session + BAT CSRF + form login, thay vi stateless + Bearer JWT.
securityMatcher gioi han pham vi nen API khong bi anh huong.

AdminUserDetailsService doc bang users cho form login. Truoc day khong co
bean nay nen Spring Boot tu tao user mac dinh (dong "Using generated
security password" luc khoi dong) - gio het.

Tach hai loai "bi tu choi" thay vi gop lam mot: thieu/sai token CSRF tra 403
(loi ky thuat), con dung nguoi sai quyen thi ve /admin/login?denied. Gop
chung thi loi CSRF hien thanh "khong co quyen", che mat nguyen nhan that.

GlobalExceptionHandler thu hep ve basePackages = demo.tripgo.controller,
neu khong no bat luon exception cua trang quan tri va tra JSON giua man hinh.
Bu lai co AdminExceptionHandler tra trang 404 HTML.

AdminAccountSeeder tao tai khoan admin dau tien tu ADMIN_EMAIL/ADMIN_PASSWORD.
Chi TAO MOI, khong bao gio ghi de tai khoan da co: nguoc lai thi ai doc duoc
bien moi truong cung chiem duoc tai khoan admin.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Them cot deleted_at (null = con song). Du lieu cu tu dong hop le nen khong
can script migration.

Co y KHONG dung @SQLRestriction du no gon hon mot dong: annotation do loc ca
khi nap quan he, nen booking.getTour() cua don cu se nem EntityNotFound -
dung cai ma xoa mem sinh ra de tranh. Thay vao do loc tuong minh:
findActiveById() cho luong cong khai, findById() giu nguyen cho khu quan tri.

Tour da xoa mem gio vo hinh o: danh sach, chi tiet, availability, reviews,
dat tour, them wishlist, dem tour theo diem den. Hang van nam trong DB.

Dieu kien deletedAt cua Tour dat trong ON chu khong phai WHERE o truy van
dem tour: de o WHERE se bien left join thanh inner join va lam rot nhung
diem den chua co tour nao.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
AdminTourController dung lai TourService cua API cong khai thay vi viet
truy van rieng. Nho vay tieu chi "thay doi o giao dien phan anh ngay o API
cong khai" la he qua tu nhien, va tour da xoa mem tu dong khong lot vao
danh sach.

Xoa = xoa mem, co thung rac va khoi phuc. Khong chan xoa tour da co don
(khac diem den): xoa mem chi an tour khoi trang ban, khach da dat van di
binh thuong - chi canh bao so don con hieu luc. Luc xoa thi "tra" slug lai
bang hau to -deleted-<id>, neu khong thi tao tour moi trung ten se bao loi
trung slug trong khi admin nhin danh sach chang thay tour nao ten do.

TourForm tach khoi entity: form khong cham duoc ratingAvg, reviewCount,
deletedAt, createdAt - du lieu he thong tu quan.

Upload anh luu NGOAI classpath (StorageProperties.uploadDir): thu muc
static/ duoc dong goi vao jar luc build nen file ghi vao do luc chay se
khong phuc vu duoc va mat khi build lai. Duoi file suy ra tu content type
chu khong lay tu ten file client gui len - ten file la du lieu client kiem
soat, dung thang la mo duong cho path traversal va cho duoi .jsp/.html.

Lich trinh dong dung AutoPopulatingList: ArrayList thuong se nem
IndexOutOfBounds ngay khi JS them dong moi. JS danh lai ten truong sau khi
xoa dong giua, vi chi so dut quang la cac dong sau bi bo qua khi luu.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bang don co loc theo trang thai (link chu khong phai select+JS, de URL mang
theo bo loc va chia se duoc), phan trang, va nut xac nhan/huy cho don dang cho.

Viec huy don KHONG duoc chep sang service moi. Ham huy hien co chua doan de
sai: phai entityManager.refresh(departure, PESSIMISTIC_WRITE) vi entity dang
nam trong cache se tra gia tri cu - thieu no la mat cap nhat khi hai request
huy cung luc (da co BookingCancelConcurrencyTest canh). Nen tach ra ham dung
chung cancelAndReleaseSeats(): khach huy don cua minh va admin huy don cua
nguoi khac di qua dung mot duong.

Xac nhan don khong dung toi so cho: cho da bi tru ngay luc khach dat.

requirePending() chan o tang service chu khong chi an nut tren giao dien:
nut an khong ngan duoc request gui thang, va hai admin thao tac cung luc
tren mot don la chuyen co that.

Nhan tieng Viet dat ngay tren enum BookingStatus - mot nguon su that cho ca
bang lan bo loc, them trang thai moi khong phai sua rai rac trong template.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Day du them/sua/xoa mem/thung rac/khoi phuc + upload anh, cung mo hinh voi tour.

Khac tour mot cho quan trong: diem den CO chan xoa khi con tour. Xoa mem khong
cat quan he, nen nhung tour do se tro toi mot diem den vo hinh va bo loc theo
diem den o API cong khai ra ket qua ky quac. Nut Xoa bi vo hieu kem tooltip
"Con N tour thuoc diem den nay", va service chan lai lan nua. Tour da xoa mem
khong tinh la "con tour".

So tour lay ngay trong truy van danh sach (AdminDestinationView) thay vi dem
lai cho tung dong - 20 dong se thanh 20 truy van phu.

Truy van nhan san pattern LIKE ('%' khi khong loc) thay vi ":keyword is null
or ...": Postgres khong suy duoc kieu cua tham so null nen bind thanh bytea va
nem "function lower(bytea) does not exist". H2 trong test lai chay binh thuong,
nen loi kieu nay chi lo ra o moi truong that. Pattern co escape \, %, _ de go
"50%" vao o tim kiem khong bien thanh "khop tat ca".

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Tong tour dang ban (khong tinh thung rac), don cho xac nhan, don thang nay,
doanh thu thang.

"Thang nay" tinh tu 00:00 ngay 1 cua thang hien tai, khong phai 30 ngay gan
nhat - do la cach nguoi doc bao cao hieu cum tu nay.

Doanh thu bo qua don da huy, va dung coalesce de thang khong co don nao tra 0
thay vi null (null se lam template no khi format so).

Ba o dau la link sang danh sach da loc san: nhin thay "12 don cho xac nhan"
thi viec tiep theo luon la mo danh sach do ra.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bang danh sach tour truoc gio khong co cot anh nao (wireframe 7.3 khong ve),
nen thumbnail dung den may cung khong thay gi. Them cot Anh, hien dau gach khi
tour chua co anh.

scripts/set-placeholder-images.sql: du lieu mau tro toi https://img/<ten>.jpg -
ten mien khong ton tai nen toan bo 228 anh trong ung dung deu vo. Script tro
chung ve file that trong thu muc uploads. Chi dung nhung dong co link chet nen
chay lai nhieu lan khong hong them gi.

Luu y khi dung script: nhieu ban ghi cung tro toi MOT file. Sua mot tour roi
tai anh moi len se xoa file cu (resolveThumbnail), keo theo cac tour khac mat
anh. Chap nhan duoc voi du lieu demo, khong dung cho du lieu that.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bo test dang chay H2 con production chay Postgres, nen loi phuong ngu SQL
khong bao gio lo ra luc test. Da co mot bug lot qua dung vi chuyen nay: truy
van co tham so null khien Postgres bind thanh bytea roi nem "function
lower(bytea) does not exist", trong khi toan bo test H2 van xanh.

PostgresTestBase dung container postgres:16-alpine - trung phien ban voi
docker-compose.yml de test chay dung thu production dung.

Co y KHONG chuyen ca bo test sang Postgres: container nang hon H2 nhieu ma
phan lon test chi kiem logic nghiep vu. Chi nhung test dung toi truy van viet
tay moi ke thua lop nay.

Ghi chu khi nang cap: Testcontainers 2.x doi ten module (postgresql ->
testcontainers-postgresql), va spring-boot-dependencies khai testcontainers.version
nhung khong import BOM nen phai tu import.

pom cung them san spring-boot-starter-oauth2-client cho commit dang nhap
Facebook phia sau; khong co client registration nao thi dependency nay khong
kich hoat gi.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Hai viec di chung mot commit vi cung sua TourRepository, DestinationRepository
va hai service admin - tach ra thi commit o giua khong build duoc.

1) Tim kiem khong dau: go "da nang" phai ra "Da Nang". Truoc day ra 0 ket qua.
   Dung cot chuan hoa (search_text, search_name) thay vi unaccent() cua Postgres:
   extension do H2 trong test khong co va bat no can quyen superuser.
   SearchTextBackfill dien cot cho du lieu cu luc khoi dong, idempotent.

   Chuan hoa CHI bo dau va ha chu thuong, GIU NGUYEN moi ky tu khac. Ban dau
   dung SlugGenerator (thay ky tu la bang '-') thi "50%" khop luon "50 nights
   Tour" - pha vo dam bao "% la ky tu literal" ma repo da co test canh. Test cu
   bat duoc.

2) ImageCleanupService: dem tham chieu o ca ba bang truoc khi xoa file. Form
   upload sinh ten UUID nen binh thuong moi ban ghi co file rieng va xoa thang
   la dung; nhung du lieu gan bang script co the cho nhieu ban ghi tro chung mot
   file - luc do sua mot tour se xoa mat anh cua tat ca nhung tour con lai.

PostgresQueryDialectTest chay dung nhung truy van viet tay tren Postgres that,
trong do co truy van tung nem loi bytea.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bo trong FACEBOOK_CLIENT_ID thi ca cum khong duoc tao va ung dung chay binh
thuong voi dang nhap email/mat khau.

Chain rieng cho /oauth2/** va /login/oauth2/**: OAuth2 buoc phai giu
authorization request + tham so state giua hai request (di va callback), viec
ma chain STATELESS cua API khong lam duoc. Dat sau chain /admin/** de hai
securityMatcher khong tranh nhau.

Xong bat tay thi doi ngay sang JWT cua TripGo va huy session - client dung
chung mot loai token cho moi endpoint. Co OAUTH2_SUCCESS_REDIRECT_URI thi
redirect ve do kem ?token=, bo trong thi tra JSON { token, user } ngay tai
callback de thu duoc bang trinh duyet khi chua co frontend.

User.password thanh nullable: tai khoan Facebook khong bao gio dat mat khau.
AuthService.login chan trong hop nay voi loi nhan ro rang thay vi so khop mat
khau voi null.

Email trung tai khoan LOCAL thi gan Facebook vao chinh tai khoan do, giu
nguyen wishlist va don hang. Neu email da thuoc mot tai khoan Facebook KHAC
thi dung lai, khong cuop tai khoan cua nguoi ta.

Hai loi do test bat duoc: SocialLoginUserService co hai constructor nen Spring
khong chon duoc (thieu @Autowired), va provider chua dang ky tra 500 thay vi
404 (boc resolver de nuot IllegalArgumentException).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Trieu chung: sau khi them cot provider, khong dang nhap duoc admin nua ma log
khong bao gi ro rang.

Nguyen nhan: ddl-auto=update chi THEM duoc thu moi. No khong them duoc cot
NOT NULL vao bang da co dong (Postgres tu choi vi dong cu mang NULL), va khong
go duoc NOT NULL khoi cot password. Hibernate gap loi DDL chi ghi WARN roi chay
tiep, nen ung dung van khoi dong nhung cot provider khong ton tai -> moi truy
van tren users hong.

Test khong bat duoc vi H2 chay ddl-auto=create-drop, luon dung schema moi tinh.
Day la lop loi chi lo ra tren DB da co du lieu that.

Sua hai phan:
- Cot provider cho phep NULL, hang cu duoc hieu la LOCAL qua User.isLocalAccount().
  UserProviderBackfill dien not luc khoi dong, idempotent.
- scripts/migrate-social-login.sql go NOT NULL khoi password. Cai nay BAT BUOC
  chay tay: khong co cach nao de Hibernate tu noi long rang buoc.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Tang excel dung chung (demo.tripgo.excel): gan @ExcelColumn len field,
ExcelMapper doc bang reflection roi tu sinh file. Them loai du lieu moi chi can
tao mot lop va gan annotation, khong phai viet them dong code doc/ghi nao.

Khop cot theo TIEU DE chu khong theo vi tri, nen nguoi dung dao cot hay chen
them cot ghi chu van nhap duoc.

Xuat theo dung bo loc dang xem chu khong phai xuat tat ca: loc xong roi moi
muon gui file cho ai do la thao tac thuong gap hon nhieu.

Mot truong hop test bat duoc: dong ma nguoi dung go roi xoa de lai o CHUOI RONG
chu khong phai o BLANK, nen isBlank() phai tinh ca hai - file that day nhung
dong "ma" kieu nay o cuoi bang.

Ba lop test cu phai them buoc don don/ngay khoi hanh truoc khi xoa tours: moi
lop test tu viet lai thu tu don theo khoa ngoai, day la lan thu ba vuong. Nen
gom thanh mot helper dung chung.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Nhap file (/admin/tours/import) dung lai tang excel da co: khai
TourImportRow voi @ExcelColumn la xong, khong viet them code doc file.

Ba nguyen tac:
- Nhap duoc dong nao hay dong do. Tu choi ca file chi vi mot o go nham se bien
  viec nhap 200 tour thanh vong lap sua-thu vo tan. So dong bao loi khop dung
  thanh so dong trong Excel.
- Slug trung thi BO QUA chu khong ghi de: chay lai cung mot file khong tao ban
  sao, va khong lang le de len du lieu admin da sua tay.
- Moi dong mot transaction rieng (TourRowImporter, REQUIRES_NEW). De ca file
  trong mot transaction thi mot dong vi pham rang buoc DB se keo do nhung dong
  da luu truoc do.

TourRowImporter phai la bean rieng chu khong phai method private: @transactional
chay qua proxy nen goi tu chinh lop do se khong mo transaction nao ca - loi im
lang, khong co trieu chung cho toi luc du lieu hong.

File mau sinh tu chinh TourImportRow nen cot khong bao gio lech voi cot bo nhap
mong doi; co test tai mau ve roi nhap lai ngay.

skipped tinh bang tong tru di so da nhap, de ba con so tren man hinh cong dung.
Dem rieng thi dong hong dinh dang o khong duoc tinh vao dau ca va admin thay
"5 dong, nhap 2, bo qua 2".

TestDataCleaner: thu tu don du lieu theo khoa ngoai truoc day nam rai rac o
tung lop test va da vo ba lan vi cung mot ly do. Gio chi con o mot cho.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Hai bieu do: doanh thu 6 thang gan nhat, va 5 tour doanh thu cao nhat thang nay.
Du lieu qua GET /admin/reports/charts.

Moi bieu do chi co MOT chuoi so lieu nen dung MOT mau. To moi cot mot mau khi
chung cung y nghia la gan mau theo thu hang chu khong theo du lieu, va lam nguoi
doc tuong mau mang thong tin gi do.

Thang khong co don nao van phai xuat hien voi gia tri 0: bo han cot se lam truc
thoi gian noi doi, nhin nhu thang do khong ton tai.

Truy van dung extract(year/month from ...) cua HQL thay vi date_trunc cua
Postgres, de chay duoc tren ca H2 lan Postgres; co test dialect rieng.

Ba loi chi thay duoc khi CHUP MAN HINH va nhin, test khong bat duoc:
- Nhan truc "10.000.000" dai toi muc Chart.js phai xoay cheo, xoay xong thi cac
  nhan chong len nhau. Rut ve "10 tr" thi nam ngang.
- Duong luoi cat ngang qua cot thay vi lui ve sau (them z: -1).
- Token mau che do toi bi ap theo prefers-color-scheme, trong khi khu quan tri
  chi co giao dien sang (the .chart-card hardcode nen trang) - may nao dat OS
  dark mode se thay bieu do mau toi tren the trang. Da doi sang scope
  data-theme="dark", de san cho luc khu quan tri co che do toi that.

Moi bieu do kem mot bang so lieu: bieu do khong duoc la cach duy nhat doc so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Hai viec don dep:
- Tu huy don PENDING qua 72h (cau hinh duoc) va HOAN CHO lai. Don cho xac nhan
  qua lau dang giu cho ma khong ai di.
- Tinh lai rating_avg / review_count cho tour bi lech. Hai cot nay duoc
  denormalize de loc/sap xep chay thang o DB, nen chi can mot lan cap nhat that
  bai la so lieu troi.

Huy tung don qua BookingService.cancelById (doi ten tu cancelByAdmin, gio ca
admin lan job deu dung) de phan hoan cho co khoa bi quan chi ton tai o MOT noi.
Gom ca me vao mot transaction thi mot don hong se keo do ca me.

ThreadPoolTaskExecutor rieng thay vi executor mac dinh: mac dinh cua Spring Boot
la SimpleAsyncTaskExecutor, tao MOT LUONG MOI cho moi lan goi va khong gioi han.
Hang doi day thi CallerRunsPolicy - cham con hon mat viec.

fixedDelay chu khong fixedRate: dem tu luc lan truoc KET THUC nen job chay lau
khong xep chong len chinh no.

Job TAT trong profile test: no chay xen vao giua test se sua du lieu ngay duoi
chan test va sinh loi chap chon rat kho lan. MaintenanceService goi thang duoc.

TestDataCleaner gio xoa ca categories. Ban dau de lai vi nhieu test dung
find-or-create, nhung test nao tu seed danh muc lai dung loi trung slug - mot
quy tac "xoa sach" de doan hon la mot quy tac co ngoai le ma moi nguoi phai nho.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Admin dang mo trang quan tri nao cung thay the thong bao khi co don moi, don
duoc xac nhan hoac bi huy.

Endpoint dat o /admin/ws, tuc la NAM TRONG khu quan tri nen chain bao mat cua
admin bao ve luon. Dat o ngoai (vd /ws) thi phai mo cong khai, va ai cung nghe
duoc thong tin don hang cua khach.

Co y KHONG bat SockJS: SockJS du phong bang cac transport dung POST, ma POST thi
vuong CSRF cua chain quan tri - phai mo ngoai le CSRF cho ca nhanh do. WebSocket
thuan chi can mot GET Upgrade nen khong dung toi CSRF.

Su kien di qua ApplicationEvent chu khong goi thang messaging tu service:
BookingService khong can biet gi ve WebSocket, va cho nay sau nay cam them JMS
vao rat de.

@TransactionalEventListener(AFTER_COMMIT) chu khong phai @eventlistener thuong:
nghe ngay luc phat thi transaction con chua commit, mot loi sau do lam rollback
se de lai thong bao ve mot don khong he ton tai. Co test canh dung cho nay.

BookingEvent la ban sao du lieu chu khong giu entity: nguoi nhan xu ly o luong
khac va ngoai transaction, noi entity lazy da het dung duoc.

Ghi chu: @MockBean da bi go o Spring Boot 4, ban thay the la @MockitoBean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Mail di qua hang doi tripgo.booking.mail thay vi gui ngay trong request cua
khach. Listener nem loi thi message quay lai hang doi de thu lai - do la ly do
chinh dung hang doi: may chu mail chap chon thi viec khong mat.

MAC DINH TAT (JMS_ENABLED=false). Co ActiveMQ tren classpath ma khong co broker
thi listener thu ket noi lai lien tuc va lam log day loi, trong khi moi truong
dev va test khong can dung broker chi de chay ung dung.

Khi tat, DirectBookingMailDispatcher gui thang tren pool nen. Hai ban cai cung
mot interface nen phan con lai cua ung dung khong can biet co broker hay khong,
va viec gui mail khong lang le bien mat khi ai do quen bat JMS.

Gui dang chuoi JSON tu serialize thay vi dung message converter co san: goi tin
di qua hang doi co the duoc doc lai boi phien ban ung dung khac, nen dinh dang
phai la thu minh kiem soat duoc.

BookingNotifier tach hai try rieng: bao realtime hong thi mail van phai di.

Test chay ca hai nhanh, trong do nhanh JMS dung broker nhung vm:// nen goi tin
di qua hang doi that ma khong can dung ActiveMQ ben ngoai.

Them service mq vao docker-compose (chi can khi JMS_ENABLED=true).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
getTourAvailability(tourSlug, fromDate?) tra ve danh sach ngay khoi hanh kem so
cho con trong. WSDL o /ws/tourAvailability.wsdl.

Contract-first that su: src/main/resources/soap/tripgo.xsd la nguon su that duy
nhat. Spring-WS sinh WSDL tu do, jaxb2-maven-plugin sinh lop Java tu do - WSDL
cong bo cho doi tac va lop xu ly request khong the lech nhau.

Endpoint mo cong khai vi client SOAP khong co phien dang nhap de mang theo. Mo
duoc la vi no CHI DOC va chi tra so lieu cho trong, khong co du lieu khach hang.
Tour da xoa mem khong lo ra (di qua findIdBySlug da loc san).

Slug sai tra SOAP Fault dang CLIENT chu khong phai SERVER: doi tac biet la phai
sua request chu khong phai thu lai.

SOAP chay tren servlet RIENG (MessageDispatcherServlet), khong di qua
DispatcherServlet cua MVC, nen phai dang ky tuong minh.

Test gui SOAP request that qua MockWebServiceClient, di qua dung lop
marshal/unmarshal ma client doi tac se dung.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Class .toast trung ten voi component cua Bootstrap, ma Bootstrap co quy tac
.toast:not(.show){display:none}. The thong bao cua minh khong bao gio duoc gan
class .show nen bi an sach - khong loi, khong canh bao, chi la khong thay gi.

Doi sang tien to tg-notice-*.

Vi sao khong ai phat hien: luc lam WebSocket minh kiem bang client STOMP viet
bang Python, thay goi tin ve dung la cho la xong. Phan hien len man hinh chua
bao gio duoc mo bang trinh duyet that. Lan nay chup man hinh trang quan tri moi
lo ra.

Bai hoc: test xanh + goi tin toi noi van chua co nghia la nguoi dung THAY duoc.
Da ghi chu ngay trong admin.css de sau nay khong ai doi ten lai.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… ngay

Dang nhap Facebook cho admin
- oauth2Login gan vao chain /admin/** (co session), callback rieng
  /admin/login/oauth2/code/facebook. Chi bat khi co FACEBOOK_CLIENT_ID.
- Dung lai SocialLoginUserService (tim/tao user), user moi co role USER.
  Kiem quyen ngay luc xac thuc: khong phai ADMIN/ACTIVE thi ve ?denied va
  khong tao phien nao.
- ClientRegistration cua admin KHONG khai la bean: hai
  ClientRegistrationRepository thi cho nao tu inject cung khong biet chon.

Quan ly nguoi dung (/admin/users)
- Danh sach, tim theo email/ten (giu dau), loc role, doi USER <-> ADMIN.
- Khong tu ha quyen minh, khong ha admin cuoi cung (khoa hang admin bang
  PESSIMISTIC_WRITE truoc khi dem).

Admin tao don ho khach (/admin/bookings/new)
- Chon tour -> ngay khoi hanh sap toi con cho -> chon khach dang hoat dong.
- Don o trang thai Cho xac nhan, uy lai BookingService.createBooking nen
  kiem cho co khoa / tinh tien / mail / bao realtime chi o mot noi.

Dashboard
- Bieu do doanh thu theo ngay dat don, chon thang (khong chon thang tuong
  lai, server cung chan). Bo hai bieu do 6 thang va top tour.
- Sua loi bieu do va nut "Them ngay" khong chay: layout chi nhung <main>
  cua trang con, the <script> dat sau </main> bi bo khi render.

Excel
- @ExcelColumn(format): cot tien hien VND (o van la so), diem danh gia
  lam tron 1 chu so. Icon Bootstrap Icons cho cac nut nhap/xuat.
- Bo chuc nang Xuat doanh thu thang. An nut Thung rac o trang Tour.

Job nen
- BOOKING_EXPIRE_CHECK_INTERVAL / RATING_REFRESH_INTERVAL doi nhip chay
  qua .env. Ghi log moi lan chay ke ca khi khong co gi de xu ly.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Bieu do realtime (WebSocket + Chart.js)
- Don tao/xac nhan/huy, hoac job huy don qua han chay xong co huy don
  -> ChartUpdatePublisher gui tin hieu STOMP toi /topic/chart-updates
  (AFTER_COMMIT de client goi lai API khong doc trung so lieu cu).
- Tin hieu khong mang so lieu: trinh duyet goi lai /admin/reports/chart-data
  (doi ten tu revenue-daily) cho dung thang dang xem, gop tin hieu 0.5s.
- admin-realtime.js: MOT ket noi STOMP dung chung cho thong bao va bieu do.
- Giu WebSocket thuan, khong SockJS: transport du phong cua SockJS dung POST,
  vuong CSRF cua chain /admin/**.
- Sua loi doan dang ky realtime bi chen nham vao trong handler doi thang
  nen bieu do khong bao gio nghe tin hieu. Them ChartRealtimeWebSocketTest
  di tron duong that: dang nhap form -> bat tay /admin/ws -> nhan tin hieu.

Man hinh Job nen (/admin/jobs)
- JobRunTracker (trong bo nho) ghi lan chay cuoi: thoi diem, thoi luong,
  ten luong, ket qua, loi. Bat loi cua luong job, khong cho chay chong.
- Nut "Chay ngay" (@async, POST + CSRF). Lich va nut chay dung chung
  MaintenanceJobs nen hai duong chay khong the lech nhau.

Danh sach tour
- Chi con: Ten tour, Diem den, Gia (gia KM + gia goc gach ngang),
  Thoi luong, Danh gia (chua co luot thi hien "—"), Thao tac.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@nhitt-1337
nhitt-1337 merged commit 1134d77 into master Oct 1, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant