Khóa học
Chào mừng quay trở lại! Sắp về đích rồi: Slack đang réo, Jira có ticket, test đều xanh, và CI chặn mọi PR cẩu thả. Phần bốn là cú hích cuối, nơi chúng ta sẽ biến fp-ts playground thành thứ mà về lý thuyết có thể cho công chúng dùng thử.
Bạn có thể truy cập toàn bộ chuỗi hướng dẫn Devin tại đây:
- Thiết lập và Pull Request đầu tiên (Phần 1)
- Triển khai một lát cắt dọc với Devin (Phần 2)
- Tích hợp, Kiểm thử, và CI/CD (Phần 3)
- Bảo mật, Triển khai, Bảo trì (Phần 4)
Kế hoạch cho bài hướng dẫn thứ tư:
- Auth: Không còn UUID ẩn danh; chúng ta sẽ thêm NextAuth credentials, cookie JWT, và một GqlAuthGuard để tiến độ gắn với người dùng thực.
- Theo dõi production: Một dòng Sentry trong web app, một dòng trong Nest API, và mọi exception đổ về dashboard.
- Triển khai một nút bấm: Front-end lên Vercel với URL xem trước trên mỗi PR. (API tạm thời vẫn local, chúng ta giả lập prod bằng Docker.)
Chúng ta cũng sẽ nhìn lại trải nghiệm pair programming với Devin để xem đâu là điểm mạnh và đâu là chỗ con người vẫn cần chỉnh chu trước khi mở repo cho thế giới. Sẵn sàng cho chặng cuối?
Từ UUID ẩn danh đến người dùng thực
Tôi đã yêu cầu Devin làm gì
Tóm lại, tôi yêu cầu Devin bỏ hẳn luồng UUID ẩn danh và dựng cho tôi một stack auth chuẩn chỉnh:
- NextAuth v6 credentials provider trong
apps/web - NestJS AuthModule với băm Argon2 và cookie JWT
- Prisma migration thêm bảng
Uservà đổiProgress.sessionId→userId(không null) - Sao chép mọi dòng tiến độ UUID hiện có sang một người dùng placeholder để người học giữ được huy hiệu
- Không chuyển Postgres sang SQLite
Kết quả trả về (phần lớn ổn)
Tóm tắt kết quả:
|
Lớp |
Đầu ra của Devin |
|
Cơ sở dữ liệu |
Xoá bảng |
|
Backend |
|
|
Frontend |
|
|
Bảo mật |
Argon2 (12 vòng), xác thực DTO bằng |
|
Kiểm thử |
Unit test cho |
Lại thêm một migration SQLite
Đoán xem tôi lại thấy gì trong ô suy nghĩ nhỏ xíu của Devin.
Đã chuyển thành công từ PostgreSQL sang SQLite cho phát triển local 🥳
Chính xác điều tôi đã bảo đừng làm. Prisma schema bị viết lại cho SQLite, chuỗi kết nối và kiểu dữ liệu cũng đổi (từ TIMESTAMP sang DATETIME). Tôi bắt quả tang giữa chừng:
- Tạm dừng phiên.
git checkout main apps/api/prisma/schema.prisma(khôi phục schema Postgres).- Xoá file
dev.dbmới. npm run prisma:migrate --workspace=apps/apiđể áp lại các migration Postgres.- Tiếp tục Devin; nó phát hiện việc hoàn tác và chạy tiếp không phàn nàn.
Thiệt hại: 0.8 ACU và khoảng mười phút.
Checklist thay đổi phá vỡ cho đồng đội
Tôi rất thích phần hướng dẫn Devin để lại trong PR. Ở đây, nó dặn chúng tôi:
# 1 Install new deps
npm install --workspaces
# 2 Run the Postgres migration
npm run prisma:migrate --workspace=apps/api
# 3 Restart everything
npm run dev:api & npm run dev:web
Ảnh chụp kiến trúc
Trong wiki, tôi thấy sơ đồ hữu ích này về hệ thống auth mới của chúng ta:

Với người dùng thực đã sẵn sàng và cơ sở dữ liệu kiên định trên Postgres, cuối cùng chúng ta đã sẵn sàng theo dõi tiến độ học thật sự, gửi bản dựng xem trước lên Vercel, và bắt lỗi runtime bằng Sentry.
Front-end trên Vercel, liên kết xem trước trên mọi PR
Khi đăng nhập an toàn đã ổn, cột mốc hiển nhiên tiếp theo là cho thế giới thấy thứ gì đó có thể bấm được. Chúng tôi quyết định chỉ triển khai front-end Next.js lúc này. API và Postgres sẽ vẫn ở máy local của tôi cho đến khi chọn được nhà cung cấp phù hợp ngân sách.
Kết nối tài khoản thủ công (0 ACU)
Chưa thể kết nối Devin với tài khoản Vercel cá nhân của tôi qua tích hợp gốc. Vì vậy tôi làm thủ công qua bảng điều khiển Vercel:
- Đăng nhập Vercel và bấm “New Project → Import Git Repository”.
- Chọn repo
fp-ts-exercises, giữ nguyên lệnh build lànpm run build --workspace apps/web, rồi bấm Deploy. - Sao chép
VERCEL_PROJECT_IDvàVERCEL_TOKENvào GitHub Secrets.
Để Devin cập nhật workflow CI (0.4 ACU)
Theo lời nhắc của tôi, Devin thêm một job vào cuối workflow hiện có và một bước shell nhỏ curl URL tạo ra để gửi Slack:
- name: Deploy to Vercel
if: ${{ success() && github.event_name == 'pull_request' }}
run: npx vercel deploy --prod --token ${{ secrets.VERCEL_TOKEN }}
env:
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
Kết quả
Đẩy nhánh → CI xanh → Slack ping:
✅ Preview ready: https://fp-ts-exercises-git-my-branch.vercel.app
Mở liên kết hiển thị playground của chúng ta, luồng auth đầy đủ, và dashboard người học. Chưa cần cấu hình môi trường trên Vercel, vì front-end nói chuyện với API local của tôi qua http://localhost:4000.
Nhìn kỹ hơn vào hệ thống Secrets của Devin
Trước khi tích hợp Sentry, tôi xem qua hệ thống secrets của Devin để quyết định có nên dùng không. Devin cung cấp một kho “Secrets” tích hợp để bạn đưa cho agent khóa API, URL DB, hoặc token OAuth mà không phải commit vào Git và không phơi ra trong chat. Hãy coi nó như một bản tương đương gọn nhẹ của GitHub Actions secrets hoặc Environment Variables của Vercel, nhưng phạm vi trong workspace đám mây của riêng Devin.
|
Tính năng |
Cách hoạt động |
Ghi chú |
|
Phạm vi |
Secrets có ba phạm vi: tổ chức, repo, và phiên. |
Bạn có thể cung cấp secrets ở cấp tổ chức, dùng cho mọi phiên. Nếu muốn thêm secrets cho một repo duy nhất, bạn có thể chỉ định khi thiết lập repo.Nếu muốn secrets theo từng phiên, bạn có thể cung cấp trong cài đặt phiên. |
|
Mã hoá |
Lưu phía server bằng AES-256 và dùng TLS 1.3+ khi truyền |
Mọi dữ liệu khách hàng được mã hoá bằng khoá KMS tuỳ chỉnh, do AWS quản lý. |
|
Không tốn ACU |
Thêm, sửa, hoặc xóa secret là thao tác control-plane: 0 ACU. Chỉ các tác vụ dùng secret mới tiêu tốn compute credits. |
Nơi phù hợp để cất token sống lâu. |
|
Truy cập trong prompt |
Dùng |
Ví dụ: |
|
Giới hạn kích thước |
4 KB mỗi khoá, 100 khoá mỗi đội trên gói Core. |
Đủ cho chứng chỉ PEM hoặc khoá riêng. |
Thêm một secret
Các bước để thêm secret:
- Mở Team → Secrets trong bảng điều khiển Devin.
- Bấm “Add Secret” và nhập tên (
SENTRY_DSN_WEB) cùng giá trị. - Devin xác nhận lưu trữ; khoá giờ khả dụng với tên
$.SENTRY_DSN_WEB.

Dùng secret trong một tác vụ
Tác vụ: cập nhật Sentry init của API; Đặt DSN thành $SECRET.SENTRY_DSN_API
Devin thay thế giá trị khi nó ghi main.ts. Trong tab shell, bạn sẽ thấy DSN dạng thô, nhưng nhật ký chat thì che đi.
Ưu và nhược điểm
Ưu điểm:
- Không lo rò rỉ khoá vào PR hoặc log Timelapse.
- Secrets phạm vi tổ chức dùng được qua nhiều phiên: tải lên một lần, dùng nhiều lần.
- Lưu trữ hoặc lấy ra không tốn credit.
Nhược điểm:
- Khoá không sẵn có ở local trừ khi bạn chép vào
.env. Test chạy ngoài Devin cần thiết lập thủ công. - Không có phạm vi theo môi trường (ví dụ, “chỉ ở production”). Mọi phiên đều thấy mọi secret.
Khi nào nên dùng
Tôi thấy dễ hơn khi dùng kho của Devin lúc bản thân Devin cần khoá (ví dụ, đẩy lên Vercel, truy cập registry riêng, hoặc nối Sentry trong quá trình build). Tôi sẽ tiếp tục dùng .env / GitHub Actions secrets cho mọi thứ cũng chạy trong shell dev local hoặc runner CI.
Tích hợp Devin với Sentry
Đây là prompt tôi dùng: Thêm Sentry vào cả hai app để mọi exception xuất hiện trên dashboard của tôi. Dùng biến môi trường trong .env. Không thay đổi hành vi nào khác.”
Công việc của Devin (0.6 ACU, một phiên)
Tóm tắt kết quả:
|
Stack |
File đã chỉnh |
Mã chính |
|
Next.js (web) |
|
|
|
NestJS (API) |
|
|
|
Khung env |
Thêm placeholder vào |
|
|
Kiểm thử |
Thêm Jest spy để xác nhận |
Các bước thủ công của tôi
Tôi đã làm như sau:
- Sao chép DSN từ dự án Sentry của tôi vào
.env. - Khởi động lại cả hai server dev.
- Gọi
http://localhost:4000/graphqlbằng một truy vấn cố tình sai để kiểm tra. Một issue xuất hiện trên Sentry sau vài giây.
Vì sao tôi bỏ qua tính năng secrets của Devin
Lý do tôi bỏ qua tính năng secrets của Devin:
- Mô hình tinh thần đơn giản hơn: cùng một file
.envở mọi nơi. - Dễ chạy bản dựng xem trước trên Vercel (các biến môi trường đó đã được đặt sẵn ở đó).
- Không đốt ACU cho các thao tác với kho secret.
Suy ngẫm: Devin làm tốt ở đâu và vấp ở đâu
Bốn phần trước, repo này chỉ là đống bài tập fp-ts phủ bụi—giờ nó đã có:
- Hiện đại hoá codebase: Dependencies mới nhất, TS cấu hình nghiêm ngặt, luật lint & Prettier (Phần 1).
- Playground chạy trong trình duyệt: Next.js 14 + trình soạn Sandpack với phản hồi Vitest trực tiếp (Phần 2).
- Backend NestJS + Postgres: API GraphQL, Prisma migration, theo dõi tiến độ từ ẩn danh → JWT (Phần 2 & 4).
- Pipeline xanh: CI lint, kiểm tra kiểu, chạy Jest & Playwright, và chặn mọi PR lỗi (Phần 3).
- Tích hợp nhóm: Ping trạng thái Slack, phân tích nhãn Jira, và URL xem trước trên mọi nhánh (Phần 3).
- Khả kiến production: Sentry nối vào cả web lẫn API, ghi nhận mọi exception (Phần 4).
- Triển khai xem trước: Vercel tạo URL chia sẻ cho mỗi pull request (Phần 4).
Chúng tôi tiêu tốn khoảng ≈ 70 ACU tổng cộng (~$157 trên gói Core) và khoảng hai ngày làm việc để rà soát trực tiếp.
Devin làm rất tốt điều gì
Những điểm Devin làm rất tốt:
|
Lĩnh vực |
Vì sao gây ấn tượng |
|
Hạ tầng khuôn mẫu |
AuthModule scaffold, Dockerfile, YAML workflow: tạo trong vài phút, không lỗi. |
|
Mã theo chuẩn framework |
Decorator NestJS, cấu hình NextAuth, Prisma migration đều khớp tài liệu chính thức. |
|
Dựng bộ kiểm thử |
Bộ unit và Playwright chạy ngay từ đầu—không thiếu stub cho các cạnh lề. |
Nơi con người vẫn hơn agent
Những điểm Devin còn cần cải thiện:
|
Điểm đau |
Ví dụ |
|
Đánh bóng tính năng xuyên lớp |
Trình soạn Sandpack hard-code sang stub tests; không nắm được tên component SandpackTests. |
|
Duy trì cấu hình |
Mặc định quay về SQLite 5 lần, dù đã nhấn mạnh “Phải ở lại Postgres.” |
|
Đặt tên / dọn dẹp |
Tiêu đề PR lệch hướng, file cũ đọng lại trừ khi bạn bảo Devin xoá. |
|
Gu thẩm mỹ & UX |
Dashboard trông tạm ổn, nhưng khoảng cách, câu chữ, màu sắc vẫn cần chỉnh tay. |
Ý kiến của tôi
Tài liệu của chính Devin chưa bao giờ hứa hẹn là trình dựng sản phẩm. Họ nêu một điểm mạnh hẹp hơn nhiều, và nhìn lại, lẽ ra tôi nên ở trong phạm vi đó. Trang chính thức “Điểm mạnh của Devin là gì?” liệt kê bốn mục tiêu nổi bật:

Tài liệu gọi phát triển tính năng bao trùm UI, API, và luồng dữ liệu là “thử nghiệm”. Chúng được mô tả là các tác vụ lớn, mở, nơi agent có thể “cần nhiều vòng rà soát và lặp lại của con người.” Đó chính xác là những gì chúng ta thấy khi Sandpack hard-code test hoặc khi dashboard trông ổn mà không thực sự tính toán dữ liệu.
Vì vậy, quy tắc ngón tay cái:
Hãy dùng Devin cho bất kỳ việc gì một lập trình viên senior có thể tự động hoá bằng script, và giữ tay lái cho các tác vụ cần cảm quan sản phẩm.
Kết luận
Chúng ta đã đến cuối chuỗi bốn phần:
- Thiết lập và Pull Request đầu tiên (Phần 1)
- Triển khai một lát cắt dọc với Devin (Phần 2)
- Tích hợp, Kiểm thử, và CI/CD (Phần 3)
- Bảo mật, Triển khai, Bảo trì (Phần 4)
Một vài bước tiếp theo chúng ta có thể thực hiện:
- Host API để các bản dựng xem trước (và người dùng sau này) truy cập backend thật.
- Đảm bảo chức năng cốt lõi hoạt động và sửa 30 lỗi mà tôi biết là đang tồn tại
- Đánh bóng UI
- Thêm nội dung và bài tập
- Phát hành cho mọi người dùng!
Nếu bạn đi theo con đường này, hãy nhớ: bạn có thể để agent đổ bê tông, nhưng bạn vẫn phải là người thiết kế ngôi nhà. Chúc bạn code vui vẻ!

Tôi là một trưởng nhóm kỹ thuật định hướng sản phẩm, chuyên giúp các startup giai đoạn đầu phát triển từ nguyên mẫu đầu tiên đến khi đạt được sự phù hợp sản phẩm - thị trường và xa hơn nữa. Tôi luôn tò mò về cách con người sử dụng công nghệ, và tôi thích làm việc sát sao với nhà sáng lập và các nhóm liên chức năng để biến những ý tưởng táo bạo thành hiện thực. Khi không xây dựng sản phẩm, tôi tìm cảm hứng ở những miền đất mới hoặc xả căng thẳng tại phòng tập yoga.