Duyệt đầu ra Claude Code theo hợp đồng tác vụ
Kiểm tra bản sửa API qua kiểu lúc chạy, quyền theo tenant, trạng thái lưu và lỗi công khai với mô hình cùng assertion có thể chạy lại.

Khi duyệt đầu ra Claude Code, hãy đối chiếu bản sửa với hợp đồng endpoint và các ranh giới tin cậy xung quanh. Bộ kiểm tra mới có thể từ chối dữ liệu sai nhưng vô tình cho phép sửa hồ sơ của người khác. Kiểm thử qua chỉ có ích khi thực thi đúng hành vi thay đổi và những giới hạn cần giữ. Bài viết dành cho lập trình viên đọc được hàm JavaScript và lần theo yêu cầu từ route đến bản ghi được lưu.
Tổng quan Claude Code, được đọc ngày 21 tháng 9 năm 2026, mô tả khả năng đọc và sửa mã. Quy trình này là đề xuất duyệt mã, không phải benchmark công cụ hoặc sự cố cụ thể trong công việc của Minh.
Bắt đầu từ hợp đồng API có giới hạn
Giả sử endpoint hồ sơ nhận tên hiển thị. Tác vụ yêu cầu từ chối tên trống sau khi cắt khoảng trắng và giữ nguyên hồ sơ nếu dữ liệu sai. Người gọi chỉ được sửa hồ sơ của mình trong tenant hiện tại. Ví dụ cho phép từ một đến tám mươi Unicode code point sau khi cắt và chỉ nhận khóa displayName. Đây là lựa chọn sản phẩm rõ ràng, không phải quy tắc chung cho mọi tên người. Endpoint cần trả mã lỗi đã định nghĩa để client hiển thị gần trường nhập.
Một bản sửa trông hợp lý thêm bước sau:
function trimOnly(body) {
const displayName = body.displayName.trim();
return displayName.length === 0
? { code: "display_name_required" }
: { displayName };
}
Đoạn này mô tả ý định kiểm tra nhưng chưa phải handler an toàn hoàn chỉnh. Nếu displayName vắng mặt hoặc không phải chuỗi, gọi trim có thể ném ngoại lệ. Phần còn lại còn phải lấy hồ sơ đích từ ngữ cảnh đã xác thực hoặc kiểm tra quyền với định danh được cung cấp.
Người duyệt cần tìm nơi kiểm tra kiểu lúc chạy, nơi kiểm tra quyền và thời điểm ghi dữ liệu. Cả hai điều kiện phải được đáp ứng trước khi ghi. Việc đoạn sửa ngắn, dễ đọc chưa đủ để chấp nhận.
Hình tách kiểm tra dữ liệu khỏi kiểm tra quyền trước bước lưu. Thứ tự có thể phụ thuộc chính sách tiết lộ thông tin của ứng dụng, nhưng không được bỏ một điều kiện chỉ vì tác vụ đang tập trung vào điều kiện kia.
Lần theo ranh giới yêu cầu thật
Đọc đăng ký route và middleware, không chỉ hàm vừa thay đổi. Middleware schema có thể đã bảo đảm trường là chuỗi; khi đó kiểm tra kiểu lặp lại trong handler có thể không cần. Nếu chưa có ranh giới ấy, phải định nghĩa phản hồi cho giá trị sai kiểu.
Xem định danh đã xác thực đi vào câu lệnh cập nhật thế nào. Trường profileId trong body là đầu vào không đáng tin. Khi đơn giản hóa mã, bản sửa không được thay định danh từ phiên bằng giá trị do client gửi. Hồi quy phân quyền có thể ẩn trong một phép refactor nhìn khá hợp lý.
Sau đó xem tác dụng lưu trữ. Dữ liệu sai phải giữ nguyên hồ sơ. Ghi trước rồi kiểm tra sau vẫn có thể trả đúng mã lỗi trong khi dữ liệu đã đổi. Assertion chỉ nhìn phản hồi sẽ bỏ sót lỗi này.
Đối chiếu kiểm thử với yêu cầu độc lập
Hướng dẫn thực hành Claude Code nhấn mạnh cung cấp cách xác minh. Người duyệt cần xem phép kiểm tra có ý nghĩa không. Kiểm thử được sinh có thể bám sát triển khai đến mức giữ nguyên cùng giả định sai.
Với tác vụ này, cần tên chỉ có khoảng trắng, trường bị thiếu, trường kiểu số và tên hợp lệ cần cắt hai đầu. Sau mỗi yêu cầu thất bại, kiểm tra bản ghi đã lưu. Thêm trường hợp cố trỏ tới hồ sơ khác và xác nhận ranh giới truy cập theo chính sách lỗi công khai.
Dùng dữ liệu ban đầu khiến thay đổi ngoài ý muốn dễ thấy. Nếu tên ban đầu luôn rỗng, một cập nhật sai vô tình xóa tên có thể không bị phát hiện. Bắt đầu bằng tên có nội dung và xác nhận nó không đổi sau khi từ chối.
Thực thi tác dụng lưu trữ trong mô hình nhỏ
Với người đọc được JavaScript, mô hình sau làm các câu hỏi trở nên cụ thể. Principal là đầu vào thử nghiệm đã được tin cậy; chưa có đăng nhập, xác minh token hoặc middleware HTTP. Các hàng là mảng trong bộ nhớ được tin cậy, với cặp tenant/user duy nhất. Body là JSON đã phân tích; getter tùy chỉnh, proxy và đối tượng tạo từ class nằm ngoài hợp đồng đầu vào này. Hàm mô hình hóa chính sách chỉ chủ sở hữu được sửa và trả đối tượng status/code mà route thật phải ánh xạ có chủ ý.
function updateProfile(rows, principal, body) {
if (!principal || typeof principal.tenantId !== "string" ||
principal.tenantId === "" || typeof principal.userId !== "string" ||
principal.userId === "") {
return { status: 401, code: "authentication_required" };
}
if (body === null || typeof body !== "object" || Array.isArray(body) ||
Object.keys(body).length !== 1 ||
!Object.hasOwn(body, "displayName") ||
typeof body.displayName !== "string") {
return { status: 422, code: "invalid_profile_input" };
}
const displayName = body.displayName.trim();
const length = Array.from(displayName).length;
if (length < 1 || length > 80) {
return { status: 422, code: "invalid_display_name" };
}
const row = rows.find(item =>
item.tenantId === principal.tenantId && item.userId === principal.userId
);
if (!row) return { status: 404, code: "profile_not_found" };
row.displayName = displayName;
return { status: 200, displayName };
}
Đặt khối assertion sau ngay sau hàm trong một Node ES module. Tenant khác được đặt ở hàng đầu, cố ý dùng cùng userId. Nhờ vậy, bỏ điều kiện tenant sẽ gây lỗi quan sát được thay vì bị thứ tự mảng che mất. Mỗi yêu cầu sai bắt đầu từ tên có nội dung và phải giữ nguyên cả mảng.
import assert from "node:assert/strict";
const initial = [
{ tenantId: "t2", userId: "u1", displayName: "Other tenant" },
{ tenantId: "t1", userId: "u1", displayName: "Mai" },
{ tenantId: "t1", userId: "u2", displayName: "Binh" }
];
const principal = { tenantId: "t1", userId: "u1" };
for (const body of [null, [], {}, {displayName: 4}, {displayName: " "},
{displayName: "x".repeat(81)},
{displayName: "Ada", userId: "u2"}]) {
const rows = structuredClone(initial);
assert.equal(updateProfile(rows, principal, body).status, 422);
assert.deepEqual(rows, initial);
}
const rows = structuredClone(initial);
assert.deepEqual(updateProfile(rows, principal, {displayName: " Nguyễn An "}),
{status: 200, displayName: "Nguyễn An"});
assert.deepEqual(rows, initial.map((row, index) =>
index === 1 ? {...row, displayName: "Nguyễn An"} : row));
Khối mã chính xác này chạy qua trên Node 22.23.2. Trong bộ thử duyệt mã, cố ý xóa điều kiện tenant khiến assertion cuối về trạng thái lưu thất bại: hàng đầu thuộc tenant khác bị sửa. Bản tham chiếu được viết thủ công để giảng giải; không có phiên Claude hoặc API production nào được thực thi.
Mô hình trong bộ nhớ chạy qua không chứng minh câu SQL có cùng điều kiện, giao dịch nguyên tử hoặc principal không thể bị giả mạo ở ranh giới thật. Cần kiểm tra các lớp ấy trong hệ thống triển khai tương ứng.
OWASP API1:2023 yêu cầu kiểm tra quyền ở mức đối tượng đối với hành động và bản ghi đang được truy cập. Chỉ có userId khớp không phải cơ chế phân quyền tổng quát. Ví dụ chỉ triển khai chính sách chủ sở hữu cùng tenant đã nêu; quyền được ủy nhiệm, hồ sơ dùng chung và tác vụ quản trị cần chính sách riêng. Khi ghi dữ liệu, đưa điều kiện quyền thật vào phép ghi, không coi mô hình này là giấy chứng nhận an toàn.
Kiểm tra biên bổ sung phải theo đúng cách biểu diễn đã chọn. Bộ thử nhận tám mươi emoji code point và từ chối tám mươi mốt. Chuỗi ký tự kết hợp có thể chiếm nhiều code point dù người nhìn thấy một ký tự. Hàm không giới hạn theo grapheme, không chuẩn hóa Unicode và không xác nhận mọi loại tên người có thể có. Principal sai và hàng không tồn tại trả mã đã nêu, đồng thời giữ nguyên mọi bản ghi. Những phân biệt ấy ngăn việc sửa kiểm tra dữ liệu âm thầm trở thành thay đổi chính sách tên ngoài phạm vi.
Đọc toàn bộ diff để nhận ra phạm vi thay đổi
Bản sửa có thể chạm schema dùng chung, kiểu client được sinh và bộ ánh xạ lỗi. Các thay đổi ấy có thể cần thiết, nhưng mỗi phần phải gắn với hành vi yêu cầu. Xem riêng dependency mới và cấu hình thay đổi vì chúng có thể tác động vượt xa endpoint hồ sơ.
Đừng bỏ qua định dạng lan rộng chỉ vì các dòng chức năng đúng. Nó tăng chi phí đọc và có thể che sửa nhầm. Nếu kho mã có formatter chuẩn, điều chỉnh định dạng có giới hạn có thể hợp lý, nhưng diff cuối vẫn cần được giải thích như một tác vụ thống nhất.
Giữ thay đổi có sẵn và xác định commit nền. Nếu người khác sửa cùng schema trong lúc agent chạy, cần duyệt lại hợp đồng tổng hợp. Kiểm thử thành công ở trạng thái trước không tự xác nhận kết quả merge sau.
Kiểm tra đường lỗi mà người dùng nhìn thấy
Mã lỗi ổn định giúp client chọn thông báo trường mà không phải phân tích câu văn. Xác nhận status và cấu trúc lỗi theo quy ước endpoint hiện có. Phản hồi ngoại lệ thô mới có thể làm hỏng client dù bộ kiểm tra nhận đúng dữ liệu sai.
Cẩn thận với chuẩn hóa. Cắt khoảng trắng xung quanh là hành vi đã yêu cầu. Đổi hoa thường, xóa khoảng trắng bên trong hoặc giới hạn Unicode sẽ thêm quy tắc sản phẩm khác. Tên quốc tế là lý do cần giữ kiểm tra gắn với hợp đồng thay vì giả định hẹp về tên ở một địa phương.
Chạy kiểm tra liên quan sau khi diff cuối đã ổn định và lưu kết quả hoàn tất thật. Nếu integration test cần hạ tầng chưa có, ghi rõ giới hạn và dùng bằng chứng cục bộ tốt nhất hiện có, không tuyên bố đã bao phủ tích hợp đầy đủ.
Quyết định chấp nhận phải lần theo đường yêu cầu: dữ liệu sai nhận phản hồi đã định nghĩa, đích không được phép vẫn không thể bị sửa, dữ liệu đúng được lưu đúng và yêu cầu thất bại giữ nguyên bản ghi cũ. Bản sửa sẵn sàng khi những phát biểu ấy có bằng chứng và các phần diff còn lại đều có mục đích rõ.