RestaurantOS.
Hệ thống POS cho nhà hàng đa chi nhánh — khách quét QR tại bàn để đặt món, nhân viên nhận và xử lý order realtime, bill in tại quầy khi thanh toán. Toàn bộ luồng vận hành chạy trên một backend duy nhất, phục vụ đồng thời API NestJS, dashboard quản trị và web đặt món của khách — cả hai đều được xây bằng Next.js.
01.Overview
Tổng quanRestaurantOS ra đời từ thực tế của một chuỗi quán nhỏ 3 chi nhánh. Giờ cao điểm buổi trưa, nhân viên ghi order bằng giấy rồi đọc lại cho bếp — mỗi lần đổi món, nhầm bàn, hay khách muốn thêm một dĩa rau là một lần chạy qua chạy lại giữa bàn, bếp và quầy thu ngân. Cuối ngày ngồi đối sổ thì con số luôn lệch, không rõ lệch ở đâu.
Giải pháp là ba app dùng chung một API: web cho khách — quét QR tại bàn để xem menu và đặt món thẳng vào hệ thống, không cần gọi nhân viên; dashboard quản trị cho nhân viên, bếp và quản lý — duyệt order, cập nhật trạng thái từng món, in bill khi thanh toán; và API NestJS đa tenant chạy multi-chi-nhánh với RBAC scope riêng theo từng chi nhánh, audit log chi tiết đến từng order item, và Socket.IO đồng bộ realtime mọi thay đổi xuyên suốt hệ thống.
02.Features
Tính năng- 01Đặt món qua QRGuest scans · no app, no signup
Mỗi bàn được gắn một QR riêng tương ứng với session đang mở. Khách quét bằng camera điện thoại, web khách Next.js mở ra ngay — không cần tải app, không cần đăng nhập. Từ đó khách xem menu theo từng category, thêm món, ghi chú nếu cần, rồi submit. Order đi về backend qua HTTP và được broadcast lập tức tới dashboard quản trị qua Socket.IO — nhân viên và bếp thấy order mới ngay khi khách vừa bấm xác nhận.
- 02Multi-tenant theo chi nhánhOrg → branches · per-branch RBAC
Hệ thống tổ chức theo mô hình
organizations → branches: một công ty quản lý nhiều chi nhánh độc lập. Phân quyền được xử lý qua bảnguser_branch_roles— cùng một tài khoản có thể đóng vai quản lý ở chi nhánh A và thu ngân ở chi nhánh B, với dữ liệu hoàn toàn tách biệt giữa hai nơi. Mỗi người chỉ thấy đúng những gì họ được phép thấy tại chi nhánh họ đang làm việc. - 03Order lifecycle realtimepending → preparing → served · per item
Mỗi order đều có vòng đời
pending → confirmed → preparing → servedhoặc rẽ sangcancellednếu cần. Không chỉ order — mỗiorder_itemcũng mang status riêng, cho phép bếp tick từng món độc lập thay vì phải chờ cả bàn xong mới cập nhật. Mọi lần chuyển trạng thái đều được ghi vàoorder_audit_logsvà push realtime qua Socket.IO room riêng theo từng chi nhánh — quản lý, thu ngân và bếp luôn nhìn thấy cùng một trạng thái tại cùng một thời điểm. - 04Bill + print trackingSnapshot · print count · void with reason
Bill được chốt từ session theo công thức
subtotal − discount + tax = total, ghi lại đầy đủpaymentMethod,paidByvàpaidAttại thời điểm thanh toán. Mỗi lần in được đếm vàoprintCountvà hệ thống tự lưufirstPrintedAt/lastPrintedAt— đủ để truy vết nếu có tranh chấp. Trường hợp huỷ bill bắt buộc phải kèmvoidReason, không cho phép void trống lý do. Front-end xử lý in trực tiếp quareact-to-print, không cần qua driver hay phần mềm trung gian. - 05Menu CMS + drag-dropCategories · items · sort · soft delete
Trang quản trị menu dùng
dnd-kitđể kéo thả sắp xếp thứ tự category và món — không cần nhập số thứ tự thủ công. Mỗi món hỗ trợ upload nhiều ảnh, toggleisAvailableđể ẩn tạm thời khi hết nguyên liệu mà không cần xoá. Thay vì xoá cứng, hệ thống dùng soft delete vớideletedAt— món bị xoá vẫn được giữ lại trong lịch sử order, đảm bảo dữ liệu thanh toán và báo cáo không bị mất theo.
03.Tech stack
Công nghệ sử dụng| API | NestJS 11 · TypeScript · TypeORM (migrations + seeds) · Passport JWT · class-validator · Swagger · Throttler · Terminus health |
| Admin | Next.js 16 · React 19 · TypeScript · Redux Toolkit · TanStack Query + Table · react-hook-form + zod · dnd-kit · recharts · react-to-print · Tailwind 4 |
| Guest | Next.js 16 (cổng 3002) · React 19 · TanStack Query · socket.io-client · Tailwind 4 — không Redux, không form heavy |
| Database | Postgresql (organizations, branches, menus, sessions, qr_codes, orders, order_items, bills, audit_logs) · soft delete · decimal cho giá |
| Realtime | Socket.IO (OrderGateway + GuestGateway) · Redis adapter cho multi-instance · room theo branch / session |
| Infra | Docker · GitHub Actions · QR generation server-side (qrcode) · Excel export (exceljs) |
04.How it works
Kiến trúc tổng thểTrung tâm của hệ thống là table session. Khi nhân viên mở bàn, backend tạo một table_sessions mới (status=open) kèm một qr_codes gắn 1-1 với session đó. QR mã hoá URL chứa token của session — khách quét xong là mở thẳng vào đúng session, mọi order gửi lên đều được validate qua token này. Đóng session → token vô hiệu hoá ngay, không thể quét lại.
Mỗi session có flag order_mode để linh hoạt theo tình huống: false (mặc định) — order của khách vào trạng thái pending, chờ nhân viên duyệt trước khi xuống bếp; true — auto-confirm, dùng cho giờ cao điểm khi quầy không kịp xử lý từng order một. Khi order được tạo hoặc đổi trạng thái, SocketService emit vào room branch:{branchId} để mọi màn hình bếp và quầy trong cùng chi nhánh nhận update <120ms. Mỗi item bị huỷ hay đổi giá đều để lại một dòng trong order_audit_logs — không có thay đổi nào mất dấu.
"Trung tâm của RestaurantOS là tableModule — mỗi bàn không chỉ là một vị trí vật lý, mà là điểm khởi đầu của toàn bộ luồng vận hành. Khi nhân viên mở bàn, tableModule kết nối trực tiếp với sessionModule để tạo một session mới, và ngay lúc đó một mã QR mới được sinh ra gắn 1-1 với session đó. Khách quét QR là bước vào đúng session đang mở của bàn mình — không nhầm lẫn, không xung đột với lượt khách trước."

Hotel Management là phần mềm quản trị khách sạn nội bộ, xây cho đội ngũ lễ tân và quản lý vận hành hàng ngày. Toàn bộ luồng cốt lõi được xử lý trong một hệ thống: nhận đặt phòng walk-in tại quầy hoặc từ kênh online, check-in và check-out, ghi nhận dịch vụ phát sinh trong quá trình lưu trú, và xuất hoá đơn tự động khi khách trả phòng. Phân quyền chi tiết đến từng thao tác — nhân viên lễ tân, thu ngân và quản lý có màn hình và quyền hạn khác nhau. Mọi thay đổi trên hệ thống đều được ghi vào audit log đầy đủ, đủ để truy vết khi cần.
BankNotify biến một chiếc điện thoại Android cũ thành cổng thanh toán DIY cho merchant nhỏ. App Flutter + Kotlin chạy nền trên điện thoại, đọc thông báo biến động số dư từ app ngân hàng và forward ngay về backend qua HTTP. Backend nhận thông báo, match với đơn hàng đang pending, rồi gọi callback để hoàn thành thanh toán — tất cả xảy ra trong vài giây, không cần tích hợp cổng thanh toán chính thức, không cần phí hàng tháng.
API NestJS tự đăng nhập ChatGPT bằng puppeteer-real-browser (bypass Cloudflare anti-bot), hỗ trợ OTP qua email, lưu session để dùng lại cho route /ask để promt, và cron job mỗi giờ kiểm tra session — gửi cảnh báo qua Telegram khi hết hạn. Điều này giúp tôi promt và nhận câu trả lời trực tiếp từ api mà không cần mở trình duyệt.

TradingSignals là công cụ phân tích tín hiệu mua/bán cá nhân cho crypto và chứng khoán — không phải bot copy trade đại trà, mà là hệ thống được xây riêng để phục vụ đúng một người, với dữ liệu kiểm chứng thực tế 2–5 năm trở lại. NestJS scan đồng thời trên nhiều khung thời gian từ 15 phút đến 1 tháng, chạy song song qua 4 engine độc lập: candlestick pattern, indicator, price action và volume analysis. Tín hiệu chỉ được ghi nhận khi nhiều khung đồng thuận — loại bỏ nhiễu, chỉ giữ lại những điểm vào lệnh thực sự đáng chú ý. Sau 10 ngày, hệ thống tự nhìn lại từng tín hiệu — đúng hay sai — tích lũy dần độ chính xác theo thời gian sử dụng. Kết quả được đẩy thẳng về Telegram cá nhân ngay khi có tín hiệu, pattern hiển thị realtime trên TradingView tích hợp trong Next.js.
05.Bình luận
Ý kiến của bạnChưa có bình luận nào.