Skip to content

mm.nemo12.com ​

SRC-1006 (chủ dự án, 23.09.2026): một webapp nhỏ, gõ Markdown bên trái, nhận sơ đồ tư duy (markmap) bên phải. Bản nháp đang gõ nằm trong localStorage của máy người dùng, dùng được khi chưa đăng nhập. Editor ẩn/hiện được, và trang nhớ lựa chọn ấy.

SRC-1014 (chủ dự án, cùng ngày): đăng nhập Google rồi lưu tối đa 10 markmap mỗi người vào D1, chọn để mở lại và sửa.

  • Đăng nhập dùng lại đường chung POST /v1/auth/google; cookie phiên đặt cho cả *.nemo12.com, nên ai đã đăng nhập ở learn thì vào mm là có sẵn phiên.
  • Bảng markmaps (migration 0287), API /v1/markmaps (liệt kê, đọc, tạo, sửa), mọi route đòi phiên và lọc theo user_id của phiên: bản của người khác trả 404 như bản không tồn tại.
  • Trần 10 giữ ở SERVER, trong chính câu INSERT ... WHERE (SELECT COUNT(*)) < 10, nên hai lượt lưu cùng lúc không vượt được. Quá trần trả 409.
  • Google chỉ cho nút đăng nhập chạy trên origin đã khai trong OAuth client, nên https://mm.nemo12.com phải có trong Authorized JavaScript origins của client dùng chung.

SRC-1017 (chủ dự án, 24.09.2026), hai chỉ đạo:

  • Toàn bộ giao diện mm nói tiếng Anh, kể cả nút Google và câu lỗi API của /v1/markmaps. Đây là ngoại lệ thứ ba của luật "UI tiếng Việt" trong CLAUDE.md; đừng dịch ngược.
  • Không có tính năng xoá. Không nút, không route DELETE. Đủ 10 bản thì mở một bản cũ và lưu đè lên; test routes.test.ts giữ cho route xoá không quay lại.

SRC-1041 (chủ dự án, 25.09.2026): share public và trang Explore.

  • Chủ markmap bấm "Share public" trên một bản đã lưu; bấm lại là thôi share. Link công khai là mm.nemo12.com/m/<id>: ai cũng xem được, không cần đăng nhập, kéo, phóng to, thu/mở nhánh được, và có nút "Make a copy" chép nội dung sang editor của người xem.
  • mm.nemo12.com/explore liệt kê mọi bản đang share, mới share trước, tìm được theo tiêu đề.
  • Link công khai hiện bản ĐÃ LƯU gần nhất, không phải bản đang gõ dở.
  • API: PUT /v1/markmaps/{id}/visibility (đòi phiên, chỉ chủ), GET /v1/public/markmaps và GET /v1/public/markmaps/{id} (công khai, khai trong bảng PUBLIC của cổng phủ auth). Hai đường công khai không trả gì về người viết: không user_id, không tên, không email, vì người dùng có thể là trẻ em. Thôi share là 404 ngay, giống hệt id không tồn tại. Cột is_public, shared_at thêm ở migration 0295.

SRC-1042 (chủ dự án, 25.09.2026): nút Share on Facebook trên trang xem công khai và cạnh "Copy link" trong editor, mở hộp chia sẻ facebook.com/sharer.

Facebook không chạy JavaScript khi đọc link, nên SPA tĩnh sẽ cho mọi markmap cùng một tiêu đề. apps/mm/worker.ts chạy trước asset CHỈ cho /m/* (run_worker_first), lấy tiêu đề từ API công khai rồi thay <title>, og:title, og:description (các nhánh cấp 2), og:url và canonical. API hỏng hay bản không còn share thì trả trang gốc. Facebook giữ bản xem trước trong cache; đổi tiêu đề rồi muốn Facebook thấy ngay thì dán link vào Sharing Debugger và bấm Scrape Again.

ViệcChỗ
Mã nguồnapps/mm (Vite + React + Tailwind v4 + motion, token DS-001)
API + bảngworkers/api/src/modules/markmaps, migrations/0287_markmaps.sql
Vẽ sơ đồmarkmap-lib/no-plugins + markmap-view
DeployWorker nemo12-mm (static assets), route mm.nemo12.com, qua ci.yml

Dùng bản no-plugins của markmap-lib là cố ý: bản đủ plugin kéo katex và highlight.js, nặng thêm khoảng 380 kB mà trang này không dùng.