Skip to content

Chương 5: Vibe Coding 101 — Từ Prompt Đến Code

"Tuấn gõ prompt dài 3 dòng. 30 giây sau, AI tạo ra 200 dòng code hoàn chỉnh. Đức nhìn và nói: 'Nhanh thật, nhưng code có đúng không?' Đó là bài học quan trọng nhất: AI viết code, BẠN review code."


🎯 Mục tiêu

  • Master prompt engineering cho coding
  • Hiểu vòng lặp: Prompt → Generate → Review → Refine
  • Tạo first real features cho TeamFlow bằng AI
  • Biết khi nào TRUST vs VERIFY AI output

Phần 1: Prompt Engineering Fundamentals (25 phút)

The Vibe Coding Loop

    ┌──────────┐
    │  PROMPT  │ ← Bạn mô tả YÊU CẦU
    └────┬─────┘

    ┌────▼─────┐
    │ GENERATE │ ← AI tạo code
    └────┬─────┘

    ┌────▼─────┐
    │  REVIEW  │ ← Bạn ĐỌC và HIỂU code
    └────┬─────┘

    ┌────▼─────┐
    │  REFINE  │ ← Fix issues, iterate
    └────┬─────┘

    ┌────▼─────┐
    │   TEST   │ ← Verify it works
    └────┬─────┘

    ┌────▼─────┐
    │  COMMIT  │ ← Ship it!
    └──────────┘

Prompt Quality Levels

LevelPromptResult
❌ Bad"Make a user API"Vague → garbage output
⚠️ Ok"Create CRUD endpoints for users with Express"Generic → needs editing
✅ Good"Create Express routes for user management: GET /api/users (list, paginate), POST /api/users (validate email+name with Zod), using Supabase client. TypeScript strict mode."Specific → usable output
🌟 GreatGood + "Follow existing pattern in src/routes/health.ts. Error responses match { error: string, code: number } format. Include JSDoc."Context-aware → production-ready

The 5 Elements of a Great Prompt

1. WHAT    → What to build (endpoint, component, function)
2. HOW     → Tech constraints (Supabase, Zod, TypeScript)
3. WHERE   → File location (src/routes/users.ts)
4. PATTERN → Follow existing code (like health.ts)
5. EDGE    → Error handling, validation rules, edge cases

Phần 2: First Real Feature — User Profile (30 phút)

Lab: Build User Profile API

bash
antigravity "Build user profile management for TeamFlow:

File: src/routes/profile.ts
Pattern: Follow src/routes/health.ts structure

Endpoints:
- GET /api/profile — get current user's profile
- PUT /api/profile — update name, avatar_url
- GET /api/users — list all team members (public profiles)

Requirements:
- Supabase client from src/lib/supabase.ts
- Auth middleware (extract user from JWT)
- Zod validation for updates
- Error format: { error: string }
- TypeScript strict mode
- JSDoc for each function"

Review Checklist

Sau khi AI generate code, kiểm tra:

  • [ ] Types correct? — TypeScript strict, no any
  • [ ] Validation present? — Zod schemas for input
  • [ ] Error handling? — try/catch, proper HTTP codes
  • [ ] Security? — Auth middleware on protected routes
  • [ ] Naming consistent? — camelCase, RESTful URLs
  • [ ] Edge cases? — Empty input, not found, unauthorized

Phần 3: The Review Discipline (20 phút)

Trust Scale

NEVER trust blindly:
  Security code (auth, encryption)     → ALWAYS review line-by-line
  Database queries                      → ALWAYS check for injection
  Business logic                        → REVIEW for correctness
  
Moderate trust:
  Boilerplate (routes, middleware)      → Scan structure, spot-check
  Test files                            → Review assertions
  
Higher trust (still verify):
  CSS styling                           → Visual check
  Documentation                         → Read for accuracy
  Config files                          → Verify values

Lab: Find the Problem

AI generated this code. Can you spot the bug?

typescript
// ⚠️ AI-generated code — review carefully
router.delete('/api/projects/:id', async (req, res) => {
  const { id } = req.params
  
  // 🐛 BUG: No check if project exists before delete!
  const { error } = await supabase
    .from('projects')
    .delete()
    .eq('id', id)
  
  if (error) {
    return res.status(500).json({ error: error.message })
  }
  
  res.json({ message: 'Project deleted' })
  // What if id doesn't exist? Returns success anyway!
})

Fix:

typescript
router.delete('/api/projects/:id', async (req, res) => {
  const { id } = req.params
  
  // ✅ Check existence first
  const { data: existing } = await supabase
    .from('projects')
    .select('id')
    .eq('id', id)
    .single()
  
  if (!existing) {
    return res.status(404).json({ error: 'Project not found' })
  }
  
  const { error } = await supabase
    .from('projects')
    .delete()
    .eq('id', id)
  
  if (error) {
    return res.status(500).json({ error: error.message })
  }
  
  res.json({ message: 'Project deleted' })
})

Phần 4: CodyMaster Skill Chaining (15 phút)

Workflow Example

bash
# Step 1: Plan (cm-planning)
antigravity "@cm-planning Plan the project CRUD module for TeamFlow:
- List endpoints needed
- Define data models
- Identify edge cases"

# Step 2: Implement (cm-execution)
antigravity "@cm-execution Implement project CRUD based on the plan above"

# Step 3: Test (cm-tdd)
antigravity "@cm-tdd Write tests for project CRUD:
- Happy path for each endpoint
- Error cases (validation, not found, unauthorized)"

# Step 4: Review (cm-code-review)
antigravity "@cm-code-review Review the project CRUD implementation"

Phần 5: Lab — Build Project Listing (20 phút)

bash
antigravity "Build project listing page for TeamFlow frontend:

File: public/static/js/projects.js

Features:
1. Fetch projects from GET /api/projects
2. Render project cards (name, description, task count, color)
3. 'Create Project' button → modal with form
4. Submit form → POST /api/projects → refresh list
5. Error handling with user-friendly messages

Style: Use existing CSS from public/static/css/style.css
Pattern: Dark mode, glassmorphism cards"

Quiz

Q1: Trong Vibe Coding loop, bước quan trọng nhất là?

  • A) Prompt (input)
  • B) Generate (AI magic)
  • C) Review (human verification) ✅

Q2: Khi AI generate code bảo mật (auth), bạn nên:

  • A) Trust vì AI biết best practices
  • B) Review từng dòng, verify logic ✅
  • C) Copy-paste và ship

Homework

  • [ ] Build profile API với AI
  • [ ] Review AI output, fix 2+ issues
  • [ ] Write at least 1 test cho profile endpoint
  • [ ] Commit to feature branch

Chương tiếp: Authentication — Bảo Mật Từ Ngày Đầu →

Powered by CodyMaster × VitePress