Bài này là walkthrough thực tế giả lập, không phải log của một app đã deploy. Tôi không claim đã build và đưa production. Mục tiêu là cho bạn thấy cách dùng vibe coding có kiểm soát để dựng một booking app nhỏ mà không biến mỗi prompt thành một đống thay đổi khó review.

App giả định: một studio nhỏ nhận booking tư vấn. User vào landing page, chọn ngày giờ, nhập tên/email/note, nhận confirmation. Admin có màn hình xem booking và export CSV. Không payment, không SMS, không auth phức tạp trong phase đầu. Đây là kiểu app rất dễ bị AI làm quá tay nếu prompt đầu tiên quá rộng.

Brief đầu tiên

Prompt xấu:

Build me a beautiful booking app with admin dashboard.

Prompt này thiếu scope, data model, flow, constraint, và điểm dừng. Agent có thể thêm auth, calendar integration, payment, email, database, chart, role, setting page. Nhìn có vẻ nhiều giá trị, nhưng review rất khó.

Brief tốt hơn:

Build a small booking prototype for a consulting studio.
Audience: visitors who want to request a consultation.
Core flow:
1. Landing section explains the service.
2. Booking form collects name, email, preferred date, preferred time, and note.
3. After submit, show confirmation summary.

Constraints:
- No payment.
- No real email sending.
- No authentication in this slice.
- Use local in-memory state or existing project storage only for prototype.
- Keep the change small and testable.
- Stop after slice 1 and summarize changed files.

Điểm quan trọng: brief nói rõ không làm gì. Vibe coding cần negative constraints vì agent rất hay “giúp thêm”.

Slice 1: landing và booking form

Slice đầu không cần database. Mục tiêu là nhìn được app và click được form. Definition of done:

  • Landing section có headline rõ.
  • Form có các field cần thiết.
  • Submit không reload trang.
  • Confirmation tạm thời hiện data vừa nhập.
  • Mobile không vỡ.

Prompt:

Implement slice 1 only:
- landing section
- booking form
- local confirmation after submit
Do not add backend, auth, payment, email, database, or external dependencies.
After implementation, list files changed and manual test steps.

Sau khi agent làm xong, review không phải chỉ nhìn đẹp. Click test:

  • Mở page desktop.
  • Mở mobile width.
  • Nhập đủ field.
  • Submit.
  • Confirmation có đúng tên, email, ngày, giờ không.
  • Refresh thì data mất cũng được, vì slice này chưa persistence.

Nếu agent thêm package date picker mới, hỏi vì sao. Với slice 1, input date/time native có thể đủ. Nếu agent tự thêm email service, reject. Nó vượt scope.

Feedback sau slice 1

Giả sử form chạy, nhưng mobile bị chật và note textarea che nút submit. Feedback tốt:

Fix only the mobile layout of the booking form.
The issue: on narrow screens, the note textarea pushes the submit button partly below the viewport and spacing feels cramped.
Do not change fields, validation, persistence, or landing copy.
Return changed files and how to verify.

Feedback xấu:

Make it nicer and more professional.

“Nicer” mở cửa cho rewrite. Feedback phải chỉ đúng symptom.

Checkpoint sau slice 1

Khi landing và form chạy, tạo checkpoint hoặc commit. Tên trạng thái:

booking form prototype working

Đây là điểm quay lại. Nếu validation slice làm hỏng layout, bạn quay về đây. Không checkpoint thì mọi prompt sau đều dựa trên trí nhớ.

Slice 2: validation và confirmation

Slice 2 thêm rule:

  • Name required.
  • Email required và có format cơ bản.
  • Date required.
  • Time required.
  • Note optional.
  • Date không được ở quá khứ.
  • Confirmation hiển thị rõ thông tin đã submit.

Prompt:

Add validation to the existing booking form.
Rules:
- name, email, preferred date, preferred time are required
- email must look like an email
- preferred date cannot be in the past
- note is optional

Keep the existing layout and fields.
Do not add backend, auth, payment, email, or dependencies.
Show inline error messages.
After submit succeeds, show a confirmation summary.

Test checklist:

Submit empty form -> errors appear.
Invalid email -> email error.
Past date -> date error.
Valid data -> confirmation appears.
Edit data after error -> error clears or updates.
Mobile -> errors do not overlap controls.

Nếu agent chỉ disable button cho tới khi form valid, vẫn cần error message. Disable-only UX làm user không biết sai gì.

Slice 3: admin view và CSV export

Đây là lúc scope bắt đầu nguy hiểm hơn. Admin view nghe đơn giản nhưng liên quan data access. Vì case study là prototype, ta giữ rõ: admin view local/prototype, không có auth production.

Prompt:

Add a prototype admin view for submitted bookings.
Scope:
- Show bookings created during the current browser session.
- Add CSV export for those bookings.
- Clearly keep this as prototype-only storage.
- Do not add login/auth yet.
- Do not add database.
- Do not send data to external services.
- Do not add dependencies unless absolutely necessary; explain first if needed.

Tại sao chưa auth/database? Vì ta đang chứng minh workflow. Nếu ngay slice này thêm auth, database, CSV, role, deploy, mỗi lỗi sẽ khó tách.

Test:

  • Submit hai booking.
  • Admin list thấy hai dòng.
  • CSV export tải file.
  • CSV có header đúng.
  • Note có dấu phẩy hoặc xuống dòng không làm vỡ format.
  • Refresh page thì booking mất, và UI nói rõ prototype session storage nếu đúng thiết kế.

Nếu muốn persistence thật, làm slice riêng sau:

Before adding persistence, inspect existing storage/API options.
Do not implement yet.
Return recommended approach and risks.

Đừng để agent tự chọn database trong cùng prompt với admin UI.

Những lỗi dễ xảy ra trong walkthrough này

Lỗi 1: agent thêm mock data vào admin list nhưng form submit không đẩy data thật vào list. UI nhìn đúng, flow thật fail. Cách bắt: submit booking mới và kiểm admin list có dòng mới không.

Lỗi 2: agent thêm CSV export nhưng export toàn sample rows. Cách bắt: dùng data bạn vừa nhập, export, mở file.

Lỗi 3: validation chỉ chạy client-side và confirmation vẫn cho data sai nếu gọi handler trực tiếp. Với prototype không sao, nhưng nếu thêm backend sau, server phải validate lại.

Lỗi 4: agent tự thêm auth giả. Ví dụ password hardcoded trong client. Cách xử lý: revert phần auth, ghi rõ admin view prototype-only. Auth thật để slice riêng và cần review.

Lỗi 5: agent dùng local storage rồi quên nói. Nếu prototype dùng local storage, UI hoặc docs phải ghi rõ. Đừng để người demo tưởng dữ liệu đã nằm server.

Feedback loop mẫu

Sau mỗi slice, dùng cùng format:

Observed:
- What I clicked
- What happened
- What I expected

Constraint:
- Keep X unchanged
- Do not modify Y

Request:
- Fix only Z

Ví dụ:

Observed:
- I submitted a booking with note "Need morning slot, if possible".
- CSV puts the note across multiple columns.

Constraint:
- Keep the form and admin layout unchanged.
- Do not add a CSV dependency unless necessary.

Request:
- Fix CSV escaping for commas, quotes, and newlines.

Feedback này đủ cụ thể để agent không rewrite cả export flow.

Handoff checklist sau prototype

Khi ba slice chạy, đừng vội gọi production-ready. Handoff cần nói rõ:

Current state:
- Landing page, booking form, validation, confirmation, prototype admin list, CSV export.

Prototype limitations:
- No real backend.
- No auth.
- No email sending.
- Data may be session-only/local-only.
- No production database migration.

Core tests:
- Empty form validation.
- Valid booking confirmation.
- Admin list receives submitted booking.
- CSV export contains submitted booking.
- Mobile form usable.

Next decisions:
- Choose persistence approach.
- Add server-side validation.
- Add auth for admin.
- Decide email confirmation.
- Decide deployment target.

Đây là ranh giới giữa demo và sản phẩm. Nếu người khác nhận repo, họ biết phần nào là thật, phần nào là tạm.

Khi nào dừng

Sau slice 3, rất dễ tiếp tục:

Add login, database, email, calendar sync, payment, reminder, analytics, admin edit, cancellation.

Đừng gom. Chọn một hướng. Nếu mục tiêu là validate demand, có thể dừng và demo. Nếu mục tiêu là MVP thật, bước tiếp theo không phải prompt thêm feature. Bước tiếp theo là technical review: data model, auth, persistence, deploy, rollback, owner.

Một booking app đơn giản có thể thành sản phẩm nghiêm túc vì nó chạm lịch, thông tin cá nhân, email, và đôi khi payment. Vibe coding giúp dựng hình nhanh. Nó không xoá nhu cầu thiết kế flow và kiểm soát rủi ro.

Chốt lại

Case study này cố tình nhỏ. Chính vì nhỏ nên thấy rõ nguyên tắc: brief có constraint, build theo slice, checkpoint sau mỗi slice, test bằng data vừa nhập, feedback theo symptom, và handoff với limitation rõ.

Vibe coding có kiểm soát không phải là viết prompt hoàn hảo một lần. Nó là chuỗi quyết định nhỏ: việc gì làm bây giờ, việc gì chưa làm, phần nào prototype-only, phần nào cần dev review, khi nào dừng. Nếu giữ được nhịp đó, một booking app nhỏ có thể là nền tốt để đi tiếp. Nếu bỏ nhịp đó, nó sẽ thành demo đẹp nhưng không ai dám maintain.