Yêu cầu tính năng · Hạ tầng

Teado.ai đủ bậc học từ tiểu học tới IELTS

Học sinh học trọn một lộ trình từ Starters tới IELTS mà không rời thương hiệu Teado. Đưa exam.flyer.us về teacher.teado.ai/exam và ieltsguru.ai về teacher.teado.ai/ielts, hai tên miền gốc vẫn chạy song song.

Phạm vi
webs-exam · webs-ielts · partner-web · ingress cụm EKS
Căn cứ
Rà mã nguồn + kiểm tra DNS, HTTP và CloudFront thực tế
Ước tính
exam 1,5–2 tuần · IELTS 2–3 tuần
Ngày
29/09/2026
Bản đề xuất — để thảo luận, chưa phải quyết định
Xuất xứ và giới hạn của tài liệu này (Prompt gốc)

Tài liệu trả lời yêu cầu ngày 29/09/2026, nguyên văn:

  • nếu giờ anh muốn host toàn bộ site exam.flyer.us thêm một version nữa ở teacher.teado.ai/exam thì sẽ setup thế nào
  • có cần tốn nhiều effort không? ý anh là product sẽ song song chạy ở exam.flyer.us và teacher.teado.ai/exam nha. access both will work
  • nếu anh muốn cho ieltsguru.ai vào teacher.teado.ai/ielts... luôn có được không? Thì sprint tới sẽ anh cho vào và viết luôn PRD tasks này

Trợ lý AI soạn trong một phiên làm việc. Phần hiện trạng hạ tầng kiểm chứng trực tiếp bằng dig, curl và đọc mã nguồn webs-exam, webs-ielts, partner-web, flyer-rs ngày 29/09/2026. Phần ước tính công và lộ trình là đề xuất, chưa qua thảo luận với đội kỹ thuật. Con số đếm tệp lấy bằng grep nên là cận dưới: nó bắt được đường dẫn viết thẳng, không bắt được đường dẫn ghép chuỗi lúc chạy.

1 · Mục tiêu

Teado.ai trở thành nơi một học sinh đi trọn con đường từ tiểu học tới IELTS, không phải chuyển sang thương hiệu khác giữa chừng.

Mục tiêuThước đo
Học sinh không rời thương hiệuKhông lời mời vào lớp nào từ giáo viên Teado trỏ sang tên miền flyer.us.
Đủ bậc, không đứt đoạnTừ Starters tới IELTS, mọi bậc giao và làm được dưới cùng một tên miền.
Không phá thứ đang chạyexam.flyer.us và ieltsguru.ai hoạt động không đổi.
Đo được nguồnPhân biệt được lượt dùng ở tên miền gốc và ở dưới Teado.

2 · Kho nội dung đã có

Bậc học không phải xây mới. Cơ sở dữ liệu đã có 13 bậc đang mở, phủ trọn từ tiểu học tới IELTS.

Nhóm tuổiBậcSố bàiGhi chú
Tiểu họcSET Primary10.143Nền tảng lớn nhất của kho
Starters2.911
Movers2.841
Flyers1.852
TOEFL Primary896
IOE585
Trung học cơ sởSET Junior2.449Nối tiếp bậc tiểu học
KET1.292
TOEFL Junior40
Trung học phổ thôngPET2.412
Luyện thiIELTS3.974Đang nằm ở một sản phẩm riêng
Dùng chungPractice15.475Luyện tập tự do
Placement Test53Xếp bậc đầu vào
Kho đã dùng chung, không bị chặn theo tên miền Giáo viên Teado đã nhìn thấy và giao được toàn bộ 13 bậc. Việc chặn của bản rút gọn là chặn theo đường dẫn màn hình, không lọc nội dung. Vậy phía giáo viên đã đủ.

3 · Khoảng trống thật nằm ở phía học sinh

Giáo viên Teado giao bài xong thì học sinh bị đẩy sang một thương hiệu khác. Nguyên nhân nằm ở ba hằng số trong partner-web/src/constants.ts, đều chỉ có một giá trị duy nhất, không có nhánh theo tên miền.

EXAM_URL = 'https://exam.flyer.us' ← học sinh làm bài IELTS_URL = 'https://ielts.flyer.us' ← lớp IELTS STUDY_URL = 'https://study.flyer.us' ← tự học
Việc của học sinhHiện đi đâuVấn đề
Nhận lời mời vào lớpexam.flyer.usGiáo viên gắn nhãn Teado, học sinh nhận link FLYER. Phụ huynh thấy hai thương hiệu cho một khoá học.
Làm bài được giaoexam.flyer.usToàn bộ trải nghiệm học nằm ngoài Teado.
Lớp IELTSielts.flyer.usCòn đi qua một lần chuyển hướng không mã hoá sang ieltsguru.ai.
Xem kết quảexam.flyer.usLiên kết kết quả gửi cho phụ huynh mang tên miền khác.
Đây mới là lý do làm dự án này Không phải để giáo viên có thêm nội dung — họ đã có đủ. Mà để học sinh và phụ huynh không nhìn thấy hai thương hiệu trong cùng một khoá học. Nếu bỏ qua phần học sinh mà chỉ đưa exam vào đường dẫn con, dự án không giải quyết được gì.

4 · Yêu cầu chức năng

#Yêu cầuMô tả
FR1Đủ bậc trong kho của TeadoGiáo viên Teado thấy và giao được cả 13 bậc đang mở. Đã đạt, chỉ cần xác nhận lại khi phát hành.
FR2Lời mời vào lớp mang tên miền TeadoGiáo viên đăng nhập ở Teado thì mã lớp sinh ra link teacher.teado.ai/exam/..., không phải exam.flyer.us.
FR3Học sinh làm bài dưới TeadoTrọn vòng: vào lớp, nhận bài, làm, nộp từng phần, kết thúc, xem kết quả — tất cả dưới teacher.teado.ai/exam.
FR4Lớp IELTS dưới TeadoTương tự FR3 với teacher.teado.ai/ielts, thay cho chuyển hướng sang ieltsguru.ai.
FR5Xếp bậc đầu vàoPlacement Test chạy được dưới Teado, để học sinh mới được xếp đúng bậc trước khi bắt đầu.
FR6Chuyển bậc liền mạchHọc sinh lên bậc từ Starters tới IELTS không phải đổi tài khoản, không phải đổi tên miền. Đây là yêu cầu phân biệt Teado với việc ghép hai sản phẩm rời.
FR7Liên kết kết quả và báo cáoMọi liên kết gửi cho phụ huynh sinh ra từ tài khoản Teado đều mang tên miền Teado.
FR8Hai tên miền gốc chạy song songexam.flyer.us và ieltsguru.ai hoạt động y như trước. Đây là ràng buộc, không phải mục tiêu phụ.
FR9Chuyển tiếp êm cho link cũLink exam.flyer.us đã phát cho học sinh trước đó vẫn mở được, không hỏng.
FR10Đo được theo bề mặtMỗi sự kiện mang thuộc tính phân biệt tên miền, theo quy ước của bộ sự kiện đo lường.
FR2 tới FR7 đều phụ thuộc một thay đổi chung Ba hằng số EXAM_URL, IELTS_URL, STUDY_URL phải chuyển từ giá trị cố định sang hàm suy theo tên miền đang phục vụ. Làm chỗ này một lần thì cả sáu yêu cầu cùng được giải; bỏ sót thì mỗi màn hình lại tự sinh link sai một kiểu.

5 · Yêu cầu phi chức năng

#Yêu cầuNgưỡng
NFR1Đăng nhập dùng chungĐăng nhập một lần ở Teado thì vào được cả phần làm bài, không đăng nhập lại. Đã sẵn sàng: máy chủ suy miền cookie từ Host.
NFR2Tốc độ không kém bản gốcThời gian hiện nội dung đầu tiên dưới đường dẫn con không chậm hơn bản gốc quá 10%.
NFR3Không trùng lặp với công cụ tìm kiếmBản dưới Teado đặt canonical trỏ về bản gốc.
NFR4Phát hành cùng ngàyHai bản dựng từ cùng một commit, chênh nhau tối đa một ngày.
NFR5Không chặng không mã hoáMọi chuyển hướng dùng https. Hiện ielts.flyer.us đang vi phạm.

6 · Ngoài phạm vi

ViệcLý do
Xây nội dung mới13 bậc đã đủ phủ tiểu học tới IELTS. Thiếu hụt nội dung là việc riêng của đội học thuật.
Tách nhận diện thương hiệuHiện hai tên miền dùng chung logo và tiêu đề. Đáng làm nhưng là dự án riêng.
Đưa Study vào TeadoSTUDY_URL cũng cố định, nhưng tự học chưa phải trọng tâm của lộ trình này.
Ứng dụng di độngLiên kết sâu của ứng dụng chỉ khai cho flyer.us. Chấp nhận giai đoạn đầu.

7 · Hiện trạng hạ tầng

Bốn điều kiểm chứng trực tiếp, không suy đoán.

7.1 · Ba tên miền đã dùng chung một CloudFront

exam.flyer.us → deoempogczwja.cloudfront.net teacher.flyer.us → deoempogczwja.cloudfront.net teacher.teado.ai → deoempogczwja.cloudfront.net

Định tuyến theo Host xảy ra ở ingress HAProxy trong cụm EKS, không phải ở CloudFront. Thêm một ứng dụng dưới đường dẫn con là thêm một luật ingress, không phải dựng hạ tầng mới.

7.2 · Đường dẫn /exam đang bị chiếm

teacher.teado.ai/exam hiện trả về 200, do partner-web phục vụ — cùng buildId với trang chủ. Đây là trang bắt-tất của partner-web. Luật mới phải đứng trước partner-web trong thứ tự khớp của ingress.

7.3 · Cookie tự chạy đúng

flyer-rs/api/src/http/cookie.rs suy ra thuộc tính Domain của cookie từ Host của request. Request tới teacher.teado.ai/exam nhận cookie .teado.ai — đúng cái Teado đang dùng. Không phải dựng lại cơ chế chuyển phiên qua hash URL như giữa flyer.us và teado.ai.

7.4 · exam đã từng chuẩn bị cho việc này

apps/exam/next.config.mjs dòng 25 và 32 có sẵn basePath = '/exam', đang bị chú thích từ 2022. Trong phần rewrite còn luật /exam/:locale → /:locale. Có người đã đi đường này rồi, nên phần khung đã có.

8 · Ràng buộc: hai bản dựng

basePath nung vào lúc build Tài liệu Next ghi rõ: "This value must be set at build time and cannot be changed without re-building as the value is inlined in the client-side bundles." Không có biến môi trường nào đổi được lúc chạy.

Hệ quả trực tiếp cho yêu cầu chạy song song:

Nơi phục vụbasePathBản dựng
exam.flyer.us/rỗngBản A, giữ nguyên như hiện nay
teacher.teado.ai/exam/examBản B, dựng riêng từ cùng mã nguồn

Hai bản dựng nghĩa là: một mã nguồn, hai ảnh Docker, hai deployment, hai bộ biến môi trường. Một lần phát hành phải dựng và kiểm hai lần.

Vì sao không dùng ingress cắt tiền tố thay cho basePath Có thể để ingress bóc /exam rồi chuyển tiếp xuống bản dựng gốc. Nhưng khi đó Next vẫn phát tài nguyên ở /_next/* và sinh liên kết trỏ về /vi/.... Trên teacher.teado.ai hai đường này thuộc về partner-web, nên khách chọn một liên kết là rơi sang ứng dụng khác, còn tài nguyên thì tranh nhau. Cách này hỏng, không phải chỉ kém.

9 · Khối lượng đo được

basePath tự sửa liên kết đi qua next/link và next/router. Nó không sửa đường dẫn viết cứng, window.location, và thuộc tính src của next/image. Đó là phần phải rà tay.

Hạng mụcexamIELTSGhi chú
Số route9151Mỗi route cần thử lại dưới tiền tố
Tệp nguồn1.029631
URL tuyệt đối viết cứng2565Phải đổi sang đường dẫn tương đối
router.push('/…')5329basePath tự xử lý, chỉ cần thử lại
window.location.href =2510Không được tự xử lý, phải sửa tay
src="/…"17—Ảnh cần thêm tiền tố
Con số này là cận dưới Đếm bằng grep nên chỉ bắt được đường dẫn viết thẳng. Đường dẫn ghép chuỗi lúc chạy không hiện ra. Dự phòng thêm khoảng 30% cho phần này.
Giai đoạnexamIELTS
Bật basePath, sửa đường dẫn cứng3–4 ngày4–5 ngày
Bản dựng thứ hai trong CI1–2 ngày1–2 ngày
Luật ingress và kiểm chứng1 ngày2–3 ngày
Thử lại toàn bộ route2–3 ngày2 ngày
Tổng1,5–2 tuần2–3 tuần

10 · Ba phương án

#Cách làmĐánh giá
AIngress theo đường dẫn
+ basePath
Đề xuất. Thêm luật host=teacher.teado.ai, path=/exam trỏ vào bản dựng B. Đúng tầng, không thêm chặng mạng, hai bản độc lập nhau.
BRewrite trong partner-webpartner-web thành máy chủ proxy cho ứng dụng khác. Thêm một chặng mạng, vẫn cần basePath, và mọi sự cố của exam kéo theo partner-web.
CTên miền con riêng
exam.teado.ai
Rẻ hơn hẳn: không cần basePath, không cần bản dựng thứ hai. Chỉ thêm DNS và một luật host. Nhưng không đạt mục tiêu một cửa vào duy nhất.
Nếu mục tiêu chỉ là giữ khách trong thương hiệu Teado Phương án C đạt gần hết giá trị với khoảng một phần năm công sức, và tránh toàn bộ rủi ro đường dẫn. Chỉ nên chọn A khi lý do là một tên miền duy nhất, chẳng hạn để dùng chung phiên đăng nhập trong cùng một tab hoặc để gom tín hiệu SEO. Đây là câu cần chốt trước khi mở sprint.

11 · Riêng IELTS nặng hơn exam

IELTS không nằm sẵn trong hạ tầng chung như exam, nên có ba việc phát sinh.

Điểm khácHiện trạng
CloudFront khácieltsguru.ai nằm ở một distribution riêng, không phải deoempogczwja như ba tên miền kia.
Có cả Cloudflarewww.ieltsguru.ai trỏ Cloudflare, còn tên miền gốc trỏ CloudFront. Hai lớp biên khác nhau cho cùng một trang.
Tên miền cũ chỉ chuyển hướngielts.flyer.us trả 302 sang http://ieltsguru.ai/, và trỏ thẳng vào ELB của HAProxy, không qua CloudFront.
Chưa có basePathKhác exam, webs-ielts chưa có sẵn phần khung đã chuẩn bị.
Dùng chung máy chủThuận lợi. Vẫn gọi api.flyer.us nên cookie hoạt động y như exam.
Chuyển hướng 302 đang dùng http ielts.flyer.us chuyển sang http://ieltsguru.ai/ chứ không phải https. Khách đi qua một chặng không mã hoá trước khi được nâng lên https. Đây là lỗi độc lập với tài liệu này, nên sửa sớm dù có làm hay không.

12 · Danh sách task

Chốt trước khi mở sprint Chọn phương án A hay C ở mục 5. Toàn bộ danh sách dưới đây viết cho phương án A; chọn C thì chỉ còn task 0, 8 và 9.
#TaskKhoNội dung
0Chốt phương án và mục tiêu—Một tên miền duy nhất, hay chỉ cần giữ thương hiệu Teado. Quyết định này đổi khối lượng gấp năm lần.
1Bật basePath cho examwebs-examBỏ chú thích dòng 25 và 32 của apps/exam/next.config.mjs, đọc từ biến môi trường để một mã nguồn dựng được cả hai bản.
2Rà đường dẫn cứng trong examwebs-exam25 URL tuyệt đối, 25 chỗ window.location.href, 17 chỗ src="/". Đổi sang đường dẫn tương đối hoặc thêm tiền tố.
3Bản dựng thứ hai trong CIwebs-examThêm nhánh dựng ảnh với basePath=/exam, gắn thẻ ảnh riêng, deployment riêng trong namespace production.
4Luật ingress cho /examhạ tầngHost teacher.teado.ai, path /exam, trỏ service exam bản B. Phải khớp trước luật bắt-tất của partner-web.
5Bật basePath cho IELTSwebs-ieltsThêm mới, chưa có sẵn như exam.
6Rà đường dẫn cứng trong IELTSwebs-ielts65 URL tuyệt đối, 10 chỗ window.location.href. Nhiều hơn exam vì trang đang tự trỏ về ieltsguru.ai.
7Luật ingress cho /ieltshạ tầngKèm việc đưa IELTS về cùng CloudFront với ba tên miền kia, hoặc giữ riêng và chấp nhận hai lớp biên.
7bBa hằng số URL suy theo tên miềnpartner-webTask quan trọng nhất. EXAM_URL, IELTS_URL, STUDY_URL trong src/constants.ts chuyển từ giá trị cố định sang hàm đọc Host. Giải một lần cho FR2 tới FR7.
7cRà mọi nơi sinh link cho học sinhpartner-webMã lớp, liên kết kết quả, liên kết báo cáo gửi phụ huynh. Kiểm bằng cách đăng nhập ở Teado rồi soát mọi link sinh ra.
7dPlacement Test dưới Teadowebs-examFR5. Xếp bậc đầu vào phải chạy được trước khi học sinh bắt đầu lộ trình.
8Thẻ canonical và sitemapcả haiBản dưới teado trỏ canonical về bản gốc, để không chia nhỏ tín hiệu SEO. Xem ca biên 1.
9Sửa 302 của ielts.flyer.ushạ tầngĐang trả http://, đổi sang https://. Làm được ngay, không phụ thuộc task nào.
10Gắn surface vào sự kiệncả haiPhân biệt lượt dùng ở tên miền gốc và ở dưới teado. Theo quy ước của bộ sự kiện đo lường.

13 · Ca biên

#Tình huốngXử lý
1Trùng lặp nội dung với GoogleCùng một trang ở hai địa chỉ. Bản dưới teado đặt canonical trỏ về bản gốc, giống cách landing đang làm. Không dùng noindex vì mất luôn cơ hội xếp hạng nếu sau này đổi ý.
2Khách đăng nhập ở teado rồi mở link exam.flyer.usHai cookie khác miền nên phải đăng nhập lại. Chấp nhận, hoặc dùng cơ chế token qua hash URL đã có sẵn trong partner-web.
3Liên kết chia sẻ sinh ra từ bản dưới teadoPhải mang tiền tố /exam. Nếu sinh thiếu, khách nhận link rơi vào trang bắt-tất của partner-web.
4Ứng dụng di động mở liên kết sâuapple-app-site-association và assetlinks.json hiện chỉ khai cho flyer.us. Thêm teado.ai hoặc chấp nhận liên kết sâu chỉ chạy ở tên miền gốc.
5Tiền tố ngôn ngữ chồng lên tiền tố đường dẫnĐường thành /exam/vi/.... Luật rewrite /exam/:locale có sẵn trong config được viết cho tình huống này, cần kiểm lại nó còn đúng.
6Khách gõ teacher.teado.ai/exam khi bản B chưa lênHiện trả 200 rỗng của partner-web. Trong lúc chuyển tiếp nên cho chuyển hướng sang exam.flyer.us thay vì để trang trắng.
7Phát hành lệch giữa hai bảnHai bản dựng từ cùng commit nhưng có thể lên không cùng lúc. Chốt quy tắc: bản gốc lên trước, bản dưới teado lên sau trong cùng ngày.
8Tài nguyên tĩnh dùng chung CDNassetPrefix đang đọc NEXT_PUBLIC_CDN_URL. Hai bản phải trỏ hai tiền tố khác nhau, nếu không bản này nạp gói của bản kia.

14 · Nghiệm thu

#Tiêu chí
1exam.flyer.us hoạt động không khác gì trước khi phát hành, kiểm bằng ảnh chụp đối chiếu.
2Cả 91 route của exam mở được dưới teacher.teado.ai/exam, không route nào trả về trang bắt-tất của partner-web.
3Đăng nhập ở teacher.teado.ai rồi vào /exam thì không phải đăng nhập lại.
4Không lời gọi tài nguyên nào rơi vào /_next/ ở gốc tên miền teado.
5Làm trọn một bài thi dưới đường dẫn con: bắt đầu, nộp từng phần, kết thúc, xem kết quả.
6Mọi liên kết chia sẻ sinh ra dưới teado đều mang tiền tố đúng.
7Canonical của bản dưới teado trỏ về bản gốc.
8Lặp lại tiêu chí 1 tới 7 cho IELTS với 51 route.
9Không một link nào sinh ra từ tài khoản Teado trỏ sang flyer.us. Soát mã lớp, liên kết kết quả, liên kết báo cáo.
10Một học sinh đi trọn lộ trình thử: làm Placement, được xếp bậc, làm một bài Starters, một bài PET, một bài IELTS — cùng một tài khoản, cùng một tên miền.
11Link exam.flyer.us phát trước đó vẫn mở được bình thường.

15 · Rủi ro

Rủi roCách giảm
Chi phí bảo trì nhân đôi vĩnh viễnĐây là rủi ro lớn nhất, và nó không mất đi sau khi làm xong. Mỗi lần phát hành exam từ nay phải dựng và kiểm hai bản. Cân nhắc phương án C nếu mục tiêu chỉ là thương hiệu.
Đường dẫn cứng sót lạiHỏng âm thầm: khách chọn một nút rồi rơi sang ứng dụng khác mà không có lỗi nào được ghi. Bắt bằng cách duyệt tự động toàn bộ route và chặn mọi điều hướng ra ngoài tiền tố.
Thứ tự luật ingresspartner-web có luật bắt-tất trên cùng host. Đặt sai thứ tự là /exam vẫn rơi vào partner-web. Kiểm chứng số 2 tồn tại vì điều này.
IELTS nằm ngoài hạ tầng chungĐưa về cùng CloudFront là việc riêng, nên tách thành task độc lập và làm trước, không gộp vào việc bật basePath.