# Les 13 — Externe APIs + Cursor agents + Vercel deploy
## Slide Overzicht (Klas A — 3 uur fysiek, demo-driven)

**Lesvorm:** Tim demonstreert klassikaal. Studenten kijken. Zelf bouwen = huiswerk.
**Demo-app:** Nieuwe kleine Pokédex (PokéAPI, geen key, visueel)
**Vervolg op:** Les 12 — Tool Calling
**Aansluit op:** Les 14 — Agents

---

## Slide 1: Title
### Les 13 — Externe APIs + Cursor + Vercel

**Visual:**
- Background: CREAM
- "Les 13" in BLUE
- "Externe APIs + Cursor + Vercel" in BLACK
- Subtitle: "Van localhost naar productie — met Cursor agents en preview deploys"

---

## Slide 2: Terugblik
### Waar staan we?

**Vorige lessen:**
- Les 11: AI SDK basics
- Les 12: Tool Calling
- Les 13: Agents

**Tot nu toe:** alles draaide op `localhost:3000`. Geen wereld eromheen.

**Vandaag:**
- Externe APIs aanroepen (geen LLM nodig, gewoon data ophalen)
- App naar productie met Vercel
- Feature branches met Cursor agents (Composer + Background)
- GitHub Actions CI (lint + build per PR)

**Visual:** localhost icoon → cloud icoon met branches eruit.

---

## Slide 3: Planning
### Vandaag — 180 minuten

| Onderwerp | Duur |
|-----------|------|
| Welkom + Terugblik | 10 min |
| Theorie: Externe APIs in Next.js | 15 min |
| Theorie: Cursor agents — Composer vs Background | 15 min |
| Theorie: Vercel preview deploys + GH Actions | 15 min |
| **Live Demo 1** — Pokédex bouwen met Composer | 30 min |
| **Live Demo 2** — Deploy naar Vercel productie | 15 min |
| **Pauze** | 15 min |
| **Live Demo 3** — Feature branch met Background Agent | 25 min |
| **Live Demo 4** — GitHub Actions CI | 15 min |
| Composer vs Background — wanneer welke? | 10 min |
| Lesopdracht + Huiswerk | 10 min |
| Vragen + Afsluiting | 5 min |

**Format:** Demo-driven, Cursor en browser side-by-side.

---

## Slide 4: Wat is een externe API?
### Data van buiten, in jouw app

**Het idee:**
- Andere mensen / bedrijven hebben data of functionaliteit
- Ze stellen die beschikbaar via HTTP endpoints (REST)
- Jij doet een `fetch()` en krijgt JSON terug

**Voorbeelden:**
- PokéAPI — Pokemon data (geen key)
- Tavily — web search (key nodig)
- Stripe — betalingen (key + secret)
- GitHub API — repos, users, issues
- Open-Meteo — weer (geen key)

**In Next.js — twee plekken om te fetchen:**

| Server-side (RSC / API route) | Client-side (`useEffect`) |
|-------------------------------|---------------------------|
| Snel, key veilig, gecached | Nodig voor user-interactie |
| Voor initiële data | Voor live updates |

**Visual:** Diagram: Next.js → fetch → externe API → JSON terug.

---

## Slide 5: Externe API in Next.js — code
### Server Component met fetch

```typescript
// app/pokemon/[name]/page.tsx
async function getPokemon(name: string) {
  const res = await fetch(
    `https://pokeapi.co/api/v2/pokemon/${name}`,
    { next: { revalidate: 3600 } } // cache 1 uur
  );
  if (!res.ok) throw new Error("Pokemon niet gevonden");
  return res.json();
}

export default async function PokemonPage({ params }) {
  const pokemon = await getPokemon(params.name);
  return (
    <div>
      <h1>{pokemon.name}</h1>
      <img src={pokemon.sprites.front_default} alt="" />
    </div>
  );
}
```

**Drie dingen om te weten:**
1. **`async`** Server Component — fetch direct in component
2. **`next: { revalidate }`** — Next.js cache opties
3. **Error handling** — `!res.ok` netjes afvangen

---

## Slide 6: Cursor — twee soorten agents
### Composer vs Background

| | Composer | Background Agent |
|---|----------|------------------|
| Waar draait | Lokaal in je editor | Cursor cloud |
| Mode | Synchroon — jij wacht | Async — runt zonder jou |
| Output | Diffs in editor | Branch + PR op GitHub |
| Goed voor | Pair programming, snelle changes | Welomschreven feature, tijdens andere taak |
| Aanroep | `Cmd+I` (Mac) / `Ctrl+I` | `Cmd+Shift+P` → Background Agent |
| Repo nodig | Lokaal | Verbonden met Cursor cloud |

**Beide kanten:**
- Composer: jij stuurt, snel feedback, niet schaalbaar voor lange taken
- Background: schaalbaar (5 agents tegelijk), maar minder controle in flight

**Visual:** Twee tracks naast elkaar — synchroon (jij + composer) vs asynchroon (background agent + jij elders).

---

## Slide 7: Vercel preview deploys
### Een URL per branch — automatisch

**Hoe het werkt:**
1. Connect je GitHub repo aan Vercel (eenmalig)
2. Push naar `main` → **productie** deploy op `je-app.vercel.app`
3. Push naar elke andere branch → **preview** deploy op `je-app-git-{branch}-{user}.vercel.app`
4. PR krijgt automatisch een comment met preview URL

**Wat krijg je:**
- Stakeholders zien een nieuwe feature voor de merge
- Cursor Background Agent maakt een PR → preview URL → klikbaar
- Reviewer test live in browser, niet alleen code-diff

**Environment scopes:**

| Scope | Wanneer | Voorbeeld var |
|-------|---------|---------------|
| **Production** | Deploys vanaf `main` | Echte API key |
| **Preview** | Alle andere branches | Test API key |
| **Development** | Lokaal (`.env.local`) | Dev API key |

---

## Slide 8: GitHub Actions CI
### Lint + build per PR

**Waarom:**
- Voor merge weet je: code lint clean én build slaagt
- Voorkomt "werkte op mijn laptop"
- Background Agent doet PR → CI draait automatisch → groene check of feedback

**Minimaal `.github/workflows/ci.yml`:**

```yaml
name: CI
on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v3
        with: { version: 9 }
      - uses: actions/setup-node@v4
        with: { node-version: 20, cache: pnpm }
      - run: pnpm install
      - run: pnpm lint
      - run: pnpm build
```

**Tijd per CI-run:** ~1-2 min op een kleine Next.js app.

---

## Slide 9: Wat we vandaag bouwen
### Pokédex — Next.js + PokéAPI

**Doel:** Een mini-Pokédex om de hele pipeline te oefenen.

**Stack:**
- Next.js 16 + TypeScript + Tailwind + Shadcn
- PokéAPI (geen key, gratis, geen rate-limit bij normaal gebruik)
- Cursor (Composer + Background Agent)
- GitHub (repo + Actions)
- Vercel (productie + preview deploys)

**Features die we bouwen vandaag:**

| Feature | Met | Branch |
|---------|-----|--------|
| Pokédex list (eerste 151) | Composer | main |
| Detail page per Pokemon | Composer | main |
| Search met filter | Background Agent | feature/search |
| Type-filter chips | Background Agent | feature/type-filter |

**Visual:** Folder-tree + GitHub branch-diagram + Vercel URLs.

---

## Slide 10: LIVE DEMO 1 — Pokédex met Composer
### ~30 min

**Wat ik laat zien:**
1. `pnpm create next-app pokedex --typescript --tailwind --app`
2. Open in Cursor
3. **Composer (`Cmd+I`)**: "Bouw een lijst-pagina met de eerste 151 Pokémon van PokéAPI, gebruik Tailwind cards"
4. Composer maakt: `app/page.tsx` met fetch + map + cards
5. `pnpm dev` — werkt
6. **Composer**: "Voeg detail-pagina toe op /pokemon/[name] met sprite + types + stats"
7. Composer maakt: `app/pokemon/[name]/page.tsx`
8. Cards op homepage linken naar detail-pages
9. Klein bugje fix-en in chat: "de cards zijn te smal"

**Belangrijk om uit te leggen:**
- Composer is een TAB in Cursor — niet hetzelfde als Chat
- Multi-file edits zichtbaar als diffs — je accepteert per file
- Terminal commands vragen toestemming

**Visual:** Cursor screenshot met Composer panel.

---

## Slide 11: LIVE DEMO 2 — Deploy naar Vercel productie
### ~15 min

**Wat ik laat zien:**
1. **GitHub:** new repo `pokedex` — public
2. **Lokaal:**
   ```bash
   git init
   git add . && git commit -m "Initial Pokédex"
   git branch -M main
   git remote add origin https://github.com/USER/pokedex.git
   git push -u origin main
   ```
3. **Vercel:** Add New → Import Git Repository → kies `pokedex` → Deploy
4. Wachten 60-90s op build
5. Open productie URL — werkt!
6. **Wijziging:** title aanpassen, push naar main → 2e deploy, ~30s

**Wat studenten moeten zien:**
- One-time setup (Vercel verbinden)
- Daarna: push to main = deploy
- Build logs in Vercel dashboard
- Custom domain mogelijk (skipping vandaag)

---

## Slide 12: Pauze
### 15 minuten

---

## Slide 13: LIVE DEMO 3 — Feature branch + Background Agent
### ~25 min

**Wat ik laat zien:**
1. **Cursor:** `Cmd+Shift+P` → "Open Background Agent"
2. **Verbind** repo aan Cursor cloud (eenmalig — accepteren in browser)
3. **Prompt aan Background Agent:**
   > "Maak een nieuwe branch `feature/search`. Voeg een zoekbalk toe bovenaan de homepage. Wanneer iemand typt, filter de Pokémon-lijst op naam. Gebruik client-side state. Push de branch + open een PR met titel 'Add search bar'."
4. **Background Agent gaat aan de slag** — Tim laat zien hoe je 'm volgt in het Cursor panel
5. **~3-5 minuten later:** PR verschijnt op GitHub
6. **Vercel** comment in PR: preview URL → klik → live preview!
7. **Demo:** zoeken werkt op preview URL
8. **Code review** in GitHub UI: wat heeft de agent gedaan?
9. **Merge** → main → productie deploy

**Tweede prompt — parallel:**
> "Maak branch `feature/type-filter`. Voeg chips toe bij elk type (fire, water, ...) om te filteren."

Beide branches kunnen tegelijk draaien.

**Visual:** Cursor Background Agent panel + GitHub PR + Vercel preview URL.

---

## Slide 14: LIVE DEMO 4 — GitHub Actions CI
### ~15 min

**Wat ik laat zien:**
1. **Vraag aan Composer:**
   > "Voeg een GitHub Actions workflow toe: lint + build moeten slagen op PR's naar main."
2. Composer maakt `.github/workflows/ci.yml`
3. Push naar nieuwe branch `chore/add-ci`
4. Open PR → GitHub Actions tab → workflow draait
5. **Demo failing CI:** introduceer typo (`<dvi>`), push, zie rode X
6. Fix met Composer ("repareer de TypeScript build error in de PR"), push, zie groene check
7. **Branch protection:** main beschermen — PR's mogen pas mergen als CI groen is

**Waarom belangrijk:**
- Background Agents kunnen lint-errors maken — CI vangt dit op
- Voor je merge: weet je dat het op een schone runner ook werkt
- Geen "werkt op mijn laptop"-discussies

---

## Slide 15: Composer vs Background Agent
### Wanneer welke?

| Scenario | Tool |
|----------|------|
| Snelle wijziging tijdens coden | Composer |
| Complex refactor over meerdere files | Composer (kun je begeleiden) |
| Onbekend gebied — wil zien wat agent doet | Composer |
| Welomschreven feature, kan op de achtergrond | Background Agent |
| Parallel werken aan 3 features | 3x Background Agent |
| Tijdens vergadering een PR voorbereiden | Background Agent |
| Repo nog niet in Cursor cloud | Composer |

**Mentale model:**
- **Composer = pair programming** — jij + AI samen aan dezelfde plek
- **Background Agent = delegeren** — je geeft taak, gaat iets anders doen, komt terug

**Risico bij Background Agent:**
- Agent kan vastlopen op rare config — debugging is moeilijker
- Verbruikt credits (Cursor Pro of Business)
- Te vage prompts → matige PR's. Specifiek zijn helpt.

---

## Slide 16: Lesopdracht + Huiswerk
### Pokédex zelf bouwen + deploy

**Lesopdracht (in-class, 30 min):**
- Eigen Pokédex repo opzetten (zelfde setup als demo)
- 1 feature met Composer toevoegen
- Push naar GitHub + connect Vercel
- Productie URL openen — werkt

**Huiswerk (voor Les 16):**
- **A:** Feature branch met Background Agent (1 feature, jouw keuze) → preview URL delen
- **B:** GitHub Actions CI (lint + build) in werking
- **C:** Branch protection — main mag pas merge na groene CI
- **D:** `DEPLOY.md` met:
  - Productie URL + 1 preview URL
  - Reflectie: Composer vs Background — wanneer welke werkte beter?
  - 1 voorbeeld waar Background Agent verbluffend goed of slecht was

**Bonus:**
- Eigen externe API integreren (Open-Meteo, GitHub, jouw keuze)
- Vercel environment vars demo (verschillende waarde in preview vs prod)

---

## Slide 17: Volgende les + Afsluiting
### Vragen?

**Vandaag gezien:**
- Externe API integratie in Server Components
- Cursor Composer voor synchrone changes
- Cursor Background Agent voor async features
- Vercel productie + preview per branch
- GitHub Actions CI (lint + build)
- Wanneer welke Cursor-modus

**Volgende les (Les 16): MCP — Model Context Protocol**
- Wat is MCP (Model Context Protocol)
- Bestaande MCP servers gebruiken in Cursor/Claude Desktop
- Eigen MCP server bouwen + laden
- Demo: eigen tools beschikbaar in alle MCP-clients

**Daarna in deze leerlijn:**
- Les 17: Externe APIs in diepte (OAuth, webhooks, paid APIs)
- Les 18: Supabase Auth + RLS — multi-user apps

**Vragen? Feedback?**

---

## Slide Summary

| # | Title | Type |
|---|-------|------|
| 1 | Title | Opening |
| 2 | Terugblik | Recap |
| 3 | Planning | 180-min |
| 4 | Externe APIs | Theorie |
| 5 | Externe API code | Theorie |
| 6 | Cursor — Composer vs Background | Theorie |
| 7 | Vercel preview deploys | Theorie |
| 8 | GitHub Actions CI | Theorie |
| 9 | Wat we bouwen | Intro demo |
| 10 | **LIVE DEMO 1** — Pokédex + Composer | Demo |
| 11 | **LIVE DEMO 2** — Vercel deploy | Demo |
| 12 | Pauze | Break |
| 13 | **LIVE DEMO 3** — Background Agent + preview | Demo |
| 14 | **LIVE DEMO 4** — GitHub Actions CI | Demo |
| 15 | Wanneer welke Cursor-mode | Reflectie |
| 16 | Lesopdracht + Huiswerk | Praktijk |
| 17 | Afsluiting + Les 13 preview | Closing |

---

## Bronnen

- **PokéAPI:** https://pokeapi.co/
- **Next.js fetching:** https://nextjs.org/docs/app/building-your-application/data-fetching
- **Cursor agents:** https://cursor.com/product
- **Vercel preview deployments:** https://vercel.com/docs/deployments/preview-deployments
- **Vercel environment variables:** https://vercel.com/docs/environment-variables
- **GitHub Actions for Next.js:** https://nextjs.org/docs/app/building-your-application/deploying
- **GitHub branch protection:** https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches
