Đang tải…
Đang tải…
Tính năng mới chạy ngon từ lần thử đầu. Ba tuần sau mới lộ ra là nó không có trong sitemap, không có trong tìm kiếm, và nút lưu thì âm thầm hỏng.

Site này có bảy module nội dung. Thêm cái thứ tám nghe như việc dựng một thư mục route mới rồi viết vài trang.
Phần đó mất một buổi chiều. Phần còn lại là mười hai file nằm rải khắp codebase, và không cái nào trong số đó sẽ nhắc bạn.
Đây là danh sách thật, chép từ tài liệu nội bộ của dự án:
1 lib/validations.ts SAVE_MODULES
2 supabase/<module>.sql CHECK constraint và danh sách IN trong toggle_save()
3 lib/tracking-shared.ts moduleFromPath()
4 components/layout/nav-shared SECTION_ICONS + EXPLORE_META
5 components/layout/navbar.tsx routeLinks
6 types/seo.ts SiteSection
7 lib/seo-verdict.ts SECTION_LABEL
8 lib/sitemap-entries.ts route index, route chi tiết, sectionOf()
9 lib/search/collect.ts tài liệu tìm kiếm
10 lib/search/featured.ts MODULE_WEIGHT
11 components/search/command-palette.tsx icon, accent, nhãn
12 services/… + profile/page.tsx giải slug, meta module, kích thước danh mục
Nhìn danh sách này thì thấy ngay một điều: chỉ hai hoặc ba mục liên quan tới việc hiển thị module. Số còn lại là những hệ thống đã tồn tại và ngầm giả định rằng chúng biết hết mọi module trên site.
Đây mới là phần đáng nói, vì dự án dùng TypeScript ở chế độ nghiêm ngặt. Đáng lẽ trình biên dịch phải bắt được chứ?
Nó bắt được vài chỗ. SiteSection là một union, nên thêm nhánh mới vào là mọi switch bao trọn union đó sẽ đỏ lên cho tới khi bạn xử lý nhánh mới. Đó là kiểu dữ liệu làm đúng việc của nó.
Nhưng phần lớn danh sách không có hình dạng đó. MODULE_WEIGHT là một bảng tra: thiếu khoá thì bạn nhận về undefined, và undefined trong một phép so sánh sắp xếp không ném lỗi, nó chỉ xếp sai thứ tự. collect.ts gom tài liệu tìm kiếm bằng cách gọi từng nguồn; quên gọi thêm một nguồn thì kết quả tìm kiếm vẫn trả về bình thường, chỉ là thiếu.
Còn mục số 2 thì nằm ngoài tầm với của TypeScript hoàn toàn. Ràng buộc CHECK trong Postgres là một danh sách chuỗi trong database. Người dùng bấm nút lưu, request đi tới, Postgres từ chối, và thứ họ thấy là một nút không phản hồi.
Phản xạ đầu tiên là gộp mười hai chỗ này về một registry duy nhất. Mình đã thử nghĩ theo hướng đó và thấy nó không đi tới đâu.
Vấn đề là chúng cần những thứ khác nhau về cùng một module. Sitemap cần biết cách liệt kê các route chi tiết. Command palette cần một icon và một màu. Ràng buộc trong database cần một chuỗi, và nó nằm ở một hệ thống khác hẳn, không import được gì từ TypeScript. Nhồi tất cả vào một object thì bạn được một object mà mọi phần của hệ thống đều import, và không ai dám sửa.
Cái thực sự giúp được là chuyện rẻ hơn nhiều: viết danh sách ra thành tài liệu, kèm cột "cái gì hỏng nếu quên".
Một checklist chỉ liệt kê các bước sẽ mục theo thời gian, vì code đổi mà tài liệu thì không. Thứ giữ được giá trị là triệu chứng.
Bảng khắc phục sự cố trong tài liệu của dự án nhìn như thế này:
Nút lưu không có phản ứng → thiếu module trong CHECK constraint (mục 2)
Không tìm thấy trong tìm kiếm → chưa thêm nguồn vào collect.ts (mục 9)
Màu track render ra không có → thiếu class literal, Tailwind không quét thấy
Cột bên trái là thứ bạn thực sự quan sát được lúc 11 giờ đêm. Cột bên phải là thứ bạn không cách nào đoán ra. Ghép hai cột lại là biến ba tiếng mò mẫm thành ba phút.
Và nếu phải rút ra một điều duy nhất: khi thêm thứ gì đó vào một hệ thống đã có, câu hỏi đáng giá không phải "cần viết gì thêm", mà là "chỗ nào trong code này đang ngầm cho rằng nó biết hết danh sách". Chỗ đó thường không nằm gần thứ bạn vừa thêm, và nó gần như chẳng bao giờ báo lỗi.
Chưa có bình luận nào — hãy là người đầu tiên!