fix: implement lessons feedback

This commit is contained in:
Tim Rijkse
2026-01-30 11:56:39 +01:00
parent 04f32babd3
commit 1e324e2f0e
18 changed files with 3828 additions and 3199 deletions

View File

@@ -72,7 +72,13 @@ Introductie tot standalone AI coding tools. OpenCode als eerste hands-on ervarin
## Huiswerk (2 uur)
**Component Library Bouwen:**
### React Opfrissen (30 min)
**BELANGRIJK:** Voordat je verder gaat, fris je React kennis op via EdHub.
- Bekijk de React basics modules
- Focus op: components, props, state, hooks
- Dit is essentieel voor de rest van de cursus!
### Component Library Bouwen (1.5 uur)
Bouw een volledige landing page component library met OpenCode:
- Hero section
- Features section (3 cards met icons)

View File

@@ -20,6 +20,9 @@ Cruciale kennis over veilig en ethisch werken met AI, gecombineerd met professio
## Te Behandelen
### Groepsdiscussie (15 min)
Bespreek klassikaal de blog posts uit Les 2 - wat waren de ervaringen met AI-assisted coding? Welke limitations ontdekte je?
### Deel 1: Ethics, Privacy & Security (1 uur)
**Privacy Risico's - Wat NOOIT te delen:**

View File

@@ -11,7 +11,7 @@
---
## Hoofdstuk
**Hoofdstuk 2: Intermediate** (Les 4-9)
**Deel 1: AI Foundations** (Les 1-4)
## Beschrijving
Geavanceerde prompt engineering technieken en introductie tot Skills.sh voor herbruikbare AI best practices.
@@ -20,6 +20,9 @@ Geavanceerde prompt engineering technieken en introductie tot Skills.sh voor her
## Te Behandelen
### Groepsdiscussie (15 min)
Bespreek klassikaal de security/privacy bevindingen uit Les 3 - welke issues vonden jullie in AI-gegenereerde code? Hoe zien jullie AI Safety Checklists eruit?
### Geavanceerde Prompt Engineering
- Zero-shot vs few-shot prompting
- Chain-of-thought reasoning

View File

@@ -1,307 +1,393 @@
# Les 5: AI Tool Selection & Workflows
# Les 5: TypeScript Basics
---
## Hoofdstuk
**Hoofdstuk 2: Intermediate** (Les 4-9)
**Deel 2: Technical Foundations** (Les 5-9)
## Beschrijving
Leer de sterke en zwakke punten van elke AI tool kennen. Ontwikkel een framework om de juiste tool te kiezen voor de juiste taak en bouw je eigen workflow.
Introductie tot TypeScript voor React developers. Leer waarom TypeScript waardevol is, hoe je types schrijft, en hoe je het combineert met React.
---
## Te Behandelen
### Waarom Tool Selection Belangrijk Is
### Waarom TypeScript?
Je kent nu meerdere AI tools:
- ChatGPT (brainstormen, planning, uitleg)
- Claude (lange context, nuance, analyse)
- v0.dev (UI prototyping)
- OpenCode (code schrijven met project context)
**Het probleem:** Elke tool heeft sterke en zwakke punten. De juiste tool kiezen bespaart tijd en levert betere resultaten.
---
### Tool Vergelijking
| Tool | Sterk in | Minder sterk in | Kosten |
|------|----------|-----------------|--------|
| **ChatGPT** | Brainstormen, uitleg, planning, algemene kennis | Grote codebases, lange context | Gratis / Pro €20/maand |
| **Claude** | Lange documenten, nuance, analyse, veiligheid | Soms te voorzichtig, geen images genereren | Gratis / Pro $20/maand |
| **v0.dev** | UI components, snel prototypen, Tailwind | Complexe logica, backend | Gratis tier |
| **OpenCode** | Code schrijven, project context, terminal | Geen web access, geen images | Gratis |
---
### Tool Selection Framework
**Stap 1: Identificeer de taak**
- Wat wil je bereiken?
- Hoe complex is het?
- Hoeveel context is nodig?
**Stap 2: Kies de juiste tool**
**Het probleem met JavaScript:**
```javascript
function greet(name) {
return "Hello, " + name.toUpperCase();
}
greet(42); // Runtime error! 42.toUpperCase is not a function
```
Als je wilt... Gebruik...
─────────────────────────────────────────────────
Brainstormen over een idee → ChatGPT
Een lange codebase analyseren → Claude
Snel een UI component maken → v0.dev
Code schrijven met project context → OpenCode
Een complex document begrijpen → Claude
Uitleg krijgen over een concept → ChatGPT
React component met styling → v0.dev
Feature implementeren in project → OpenCode
**De oplossing met TypeScript:**
```typescript
function greet(name: string): string {
return "Hello, " + name.toUpperCase();
}
greet(42); // Compile error! Argument of type 'number' is not assignable to type 'string'
```
**Voordelen:**
- Fouten vinden VOORDAT je code runt
- Betere autocomplete in je editor
- Code is zelf-documenterend
- AI tools begrijpen je code beter
---
### Basic Types
```typescript
// Primitives
let name: string = "Tim";
let age: number = 25;
let isStudent: boolean = true;
// Arrays
let numbers: number[] = [1, 2, 3];
let names: string[] = ["Tim", "Anna"];
// Alternative array syntax
let scores: Array<number> = [90, 85, 88];
// Objects
let user: { name: string; age: number } = {
name: "Tim",
age: 25
};
```
---
### Workflow Patterns
### Type Inference
**Pattern 1: Planning → Prototyping → Implementation**
```
1. ChatGPT: Brainstorm features, maak planning
2. v0.dev: Genereer UI prototypes
3. OpenCode: Implementeer met project context
TypeScript raadt types vaak zelf:
```typescript
// TypeScript weet dat dit een string is
let message = "Hello"; // type: string
// TypeScript weet dat dit een number is
let count = 42; // type: number
// TypeScript weet wat de functie returned
function double(x: number) {
return x * 2; // return type: number (inferred)
}
```
**Pattern 2: Research → Design → Build**
```
1. ChatGPT/Claude: Research beste aanpak
2. v0.dev: Design components
3. OpenCode: Bouw en integreer
```
**Regel:** Je hoeft niet altijd types te schrijven. Laat TypeScript inferren waar mogelijk.
**Pattern 3: Quick Iteration**
```
1. v0.dev: Snel component genereren
2. OpenCode: Aanpassen en integreren
3. Repeat
---
### Interfaces
Voor het beschrijven van object shapes:
```typescript
interface User {
id: number;
name: string;
email: string;
isActive: boolean;
}
const user: User = {
id: 1,
name: "Tim",
email: "tim@example.com",
isActive: true
};
// Optional properties met ?
interface Product {
id: number;
name: string;
price: number;
description?: string; // optioneel
}
```
---
### Praktijk: Dezelfde Taak, Drie Tools
### Type Aliases
**Opdracht:** Bouw een Contact Form component
Alternatief voor interfaces, meer flexibel:
**Met ChatGPT:**
```
Prompt: Ik wil een contact form maken met React en Tailwind.
Velden: naam, email, bericht. Validatie nodig.
Geef me de code en leg uit hoe het werkt.
```
→ Krijg: Uitleg + code, maar zonder project context
```typescript
// Type alias voor object
type User = {
id: number;
name: string;
};
**Met v0.dev:**
```
Prompt: Modern contact form with name, email, message fields.
Tailwind styling, validation, responsive design.
```
→ Krijg: Visueel prototype, direct te gebruiken
// Type alias voor union types
type Status = "pending" | "approved" | "rejected";
**Met OpenCode:**
// Type alias voor functie
type GreetFunction = (name: string) => string;
```
Prompt: Maak een ContactForm component in src/components/
met naam, email en bericht velden. Gebruik onze bestaande
Input en Button components. Voeg Zod validatie toe.
```
→ Krijg: Geïntegreerde code die past in je project
**Interface vs Type:**
- Interface: voor objecten, kan extended worden
- Type: voor alles, meer flexibel
---
### Wanneer Combineer Je Tools?
### TypeScript met React
**Scenario 1: Nieuwe feature bouwen**
1. ChatGPT: "Hoe zou je een dark mode toggle implementeren in React?"
2. v0.dev: "Dark mode toggle component with smooth transition"
3. OpenCode: "Integreer deze toggle in onze navbar, sla preference op in localStorage"
**Props typen:**
**Scenario 2: Bug oplossen**
1. OpenCode: Vraag om bug te identificeren
2. Claude: Als de foutmelding complex is, vraag om uitleg
3. OpenCode: Implementeer de fix
```typescript
// Interface voor props
interface ButtonProps {
label: string;
onClick: () => void;
disabled?: boolean;
}
**Scenario 3: Nieuwe technologie leren**
1. ChatGPT: "Leg uit hoe React Server Components werken"
2. v0.dev: "Example of React Server Component with data fetching"
3. OpenCode: "Help me dit toe te passen in mijn Next.js project"
// Component met typed props
function Button({ label, onClick, disabled = false }: ButtonProps) {
return (
<button onClick={onClick} disabled={disabled}>
{label}
</button>
);
}
// Gebruik
<Button label="Click me" onClick={() => console.log("Clicked!")} />
```
---
### Anti-Patterns (Wat Niet Te Doen)
### useState met Types
**❌ Verkeerde tool voor de taak:**
- ChatGPT vragen om een hele app te bouwen → te weinig context
- v0.dev vragen om complexe backend logica → niet zijn sterke punt
- OpenCode vragen om design inspiratie → kan geen images maken
```typescript
import { useState } from 'react';
**❌ Heen en weer kopiëren zonder begrip:**
- Kopieer niet blind code van ChatGPT naar je project
- Begrijp eerst WAT de code doet
// Type inference werkt vaak
const [count, setCount] = useState(0); // number
**❌ Dezelfde prompt in elke tool:**
- Pas je prompt aan per tool
- v0.dev wil visuele beschrijvingen
- OpenCode wil project-specifieke context
// Explicit type voor complexe data
interface User {
id: number;
name: string;
}
const [user, setUser] = useState<User | null>(null);
// Array van objecten
const [users, setUsers] = useState<User[]>([]);
```
---
### Je Eigen Workflow Documenteren
### Generics Basics
Maak een `docs/WORKFLOW.md` in je project:
Generics maken code herbruikbaar:
```markdown
# Mijn AI Workflow
```typescript
// Array is een generic type
const numbers: Array<number> = [1, 2, 3];
const names: Array<string> = ["Tim", "Anna"];
## Planning Fase
- Tool: ChatGPT
- Wat: Feature breakdown, technische beslissingen
- Template prompt: "Ik wil [feature]. Wat zijn de stappen?"
// Promise is een generic type
async function fetchUser(): Promise<User> {
const response = await fetch('/api/user');
return response.json();
}
## UI Design Fase
- Tool: v0.dev
- Wat: Component prototypes
- Template prompt: "Modern [component] with [requirements]"
// Je kunt ook eigen generics maken
function firstElement<T>(arr: T[]): T | undefined {
return arr[0];
}
## Implementation Fase
- Tool: OpenCode
- Wat: Code schrijven en integreren
- Template prompt: "Maak [component] in [locatie] met [requirements]"
const first = firstElement([1, 2, 3]); // type: number | undefined
```
## Debugging
- Tool: OpenCode (eerst), Claude (als het complex is)
- Wat: Errors oplossen
- Template prompt: "Ik krijg deze error: [error]. Dit is mijn code: [code]"
---
### Veelvoorkomende Errors
**Error 1: Type 'X' is not assignable to type 'Y'**
```typescript
let name: string = 42; // Error!
// Fix: gebruik correct type
let name: string = "Tim";
```
**Error 2: Property 'X' does not exist on type 'Y'**
```typescript
interface User { name: string; }
const user: User = { name: "Tim" };
console.log(user.age); // Error! 'age' bestaat niet
// Fix: voeg property toe aan interface
```
**Error 3: Object is possibly 'undefined'**
```typescript
const users: User[] = [];
console.log(users[0].name); // Error! users[0] kan undefined zijn
// Fix: check eerst
if (users[0]) {
console.log(users[0].name);
}
```
---
### JS naar TS Omzetten
**Stap 1:** Rename `.js` naar `.tsx` (voor React) of `.ts`
**Stap 2:** Fix de rode errors - meestal:
- Voeg types toe aan function parameters
- Maak interfaces voor objecten
- Handle nullable values
**Voorbeeld:**
```javascript
// Voorheen (JavaScript)
function UserCard({ user }) {
return <div>{user.name}</div>;
}
```
```typescript
// Nu (TypeScript)
interface User {
id: number;
name: string;
}
interface UserCardProps {
user: User;
}
function UserCard({ user }: UserCardProps) {
return <div>{user.name}</div>;
}
```
---
## Tools
- ChatGPT
- Claude
- v0.dev
- OpenCode/WebStorm
- TypeScript (via Next.js)
- React
---
## Lesopdracht (2 uur)
### Tool Comparison Challenge
### TypeScript Hands-on
**Deel 1: Dezelfde Taak, Drie Tools (1 uur)**
**Deel 1: JS naar TS Omzetten (45 min)**
Bouw een "Contact Form" component met alle drie de tools:
Gegeven JavaScript component:
1. **ChatGPT (20 min)**
- Vraag om code + uitleg
- Noteer: hoe lang duurde het, kwaliteit output, wat miste?
```javascript
function ProductCard({ product, onAddToCart }) {
return (
<div className="p-4 border rounded">
<h2>{product.name}</h2>
<p>${product.price}</p>
{product.description && <p>{product.description}</p>}
<button onClick={() => onAddToCart(product.id)}>
Add to Cart
</button>
</div>
);
}
```
2. **v0.dev (20 min)**
- Genereer visueel prototype
- Noteer: hoe snel, hoe mooi, hoe aanpasbaar?
Zet dit om naar TypeScript:
1. Maak `Product` interface
2. Maak `ProductCardProps` interface
3. Type de component
4. Fix alle TypeScript errors
3. **OpenCode (20 min)**
- Integreer in bestaand project
- Noteer: hoe goed past het, hoeveel aanpassing nodig?
**Deel 2: Interfaces Schrijven (30 min)**
**Deel 2: Analyse (30 min)**
Maak interfaces voor:
Vul dit schema in:
1. **User** met: id, name, email, avatar (optioneel), createdAt
2. **Product** met: id, name, price, description (optioneel), inStock, category
3. **Order** met: id, userId, products (array), total, status (pending/shipped/delivered)
| Aspect | ChatGPT | v0.dev | OpenCode |
|--------|---------|--------|----------|
| Tijd tot werkend component | | | |
| Kwaliteit code | | | |
| Visueel design | | | |
| Past in project | | | |
| Hoeveel aanpassing nodig | | | |
| Totaalscore (1-10) | | | |
**Deel 3: React Component met Types (45 min)**
**Deel 3: Workflow Documentatie (30 min)**
Bouw een `UserList` component:
- Props: users array, onSelectUser callback
- State: selectedUserId (number of null)
- Toon lijst van users, highlight geselecteerde
- Maak `docs/WORKFLOW.md` in je project
- Documenteer je ideale workflow per taaktype
- Inclusief template prompts voor elke tool
Alle types moeten correct zijn. Geen `any` gebruiken!
### Deliverable
- Screenshot van alle 3 contact forms
- Ingevuld vergelijkingsschema
- `docs/WORKFLOW.md` bestand
- ProductCard.tsx met correcte types
- types.ts met alle interfaces
- UserList.tsx volledig getypt
---
## Huiswerk (2 uur)
### Bouw Je Tool Selection Cheat Sheet
### TypeScript Verdieping
**Deel 1: Cheat Sheet Maken (1 uur)**
**Deel 1: Drie Components Bouwen (1 uur)**
Maak een persoonlijke "Tool Selection Cheat Sheet" (1 pagina):
Bouw volledig in TypeScript:
```markdown
# Mijn AI Tool Cheat Sheet
1. **SearchInput** component
- Props: value, onChange, placeholder (optioneel)
- Volledig getypt
## Wanneer gebruik ik wat?
2. **DataTable** component
- Generic: werkt met elk type data
- Props: data array, columns config
- Type-safe rendering
### ChatGPT
- ✅ Gebruik voor: [jouw ervaring]
- ❌ Niet voor: [jouw ervaring]
- 💡 Beste prompt tip: [jouw tip]
3. **Modal** component
- Props: isOpen, onClose, title, children
- Correct gebruik van React.ReactNode
### Claude
- ✅ Gebruik voor: [jouw ervaring]
- ❌ Niet voor: [jouw ervaring]
- 💡 Beste prompt tip: [jouw tip]
**Deel 2: Eindproject Interfaces (30 min)**
### v0.dev
- ✅ Gebruik voor: [jouw ervaring]
- ❌ Niet voor: [jouw ervaring]
- 💡 Beste prompt tip: [jouw tip]
Bedenk de data structuur voor je eindproject:
- Welke entiteiten heb je? (users, posts, products, etc.)
- Maak interface voor elke entiteit
- Documenteer relaties tussen entiteiten
### OpenCode
- ✅ Gebruik voor: [jouw ervaring]
- ❌ Niet voor: [jouw ervaring]
- 💡 Beste prompt tip: [jouw tip]
**Deel 3: Cheat Sheet (30 min)**
## Mijn Favoriete Combinaties
1. [Workflow 1]
2. [Workflow 2]
```
**Deel 2: Testen op Nieuwe Taken (45 min)**
Test je cheat sheet op 2 nieuwe taken:
1. Bouw een "Testimonial Card" component
2. Voeg een "Dark Mode Toggle" toe
Per taak:
- Kies tools op basis van je cheat sheet
- Voer uit en noteer resultaat
- Update cheat sheet indien nodig
**Deel 3: Reflectie (15 min)**
Schrijf korte reflectie (400 woorden):
- Welke tool is jouw favoriet en waarom?
- Wanneer combineer je tools?
- Wat ga je anders doen na deze les?
Maak persoonlijke TypeScript cheat sheet:
- Meest gebruikte types
- Interface vs Type wanneer
- Common patterns met React
- Hoe je errors oplost
### Deliverable
- Tool Selection Cheat Sheet (1 pagina)
- 2 gebouwde components (Testimonial Card, Dark Mode Toggle)
- Reflectie (400 woorden)
- 3 TypeScript components
- types/index.ts met eindproject interfaces
- TypeScript cheat sheet (1 pagina)
---
## Leerdoelen
Na deze les kan de student:
- De sterke en zwakke punten van elke AI tool benoemen
- De juiste tool kiezen voor een specifieke taak
- Meerdere tools combineren in een effectieve workflow
- Een persoonlijke workflow documenteren
- Template prompts schrijven per tool
- Kritisch evalueren welke tool wanneer het beste werkt
- Uitleggen waarom TypeScript waardevol is
- Basic types gebruiken (string, number, boolean, arrays)
- Interfaces en type aliases schrijven
- React components typen met props
- useState met types gebruiken
- Generics op basisniveau begrijpen
- JavaScript code omzetten naar TypeScript
- TypeScript errors lezen en oplossen

View File

@@ -1,288 +1,365 @@
# Les 6: Hands-on: Van Idee naar Prototype
# Les 6: Next.js Fundamentals 1 - SSR & Routing
---
## Hoofdstuk
**Hoofdstuk 2: Intermediate** (Les 4-9)
**Deel 2: Technical Foundations** (Les 5-9)
## Beschrijving
Pas alles wat je hebt geleerd toe in een hands-on sessie. Ga van een vaag idee naar een werkend prototype met behulp van je AI workflow.
Introductie tot Next.js voor React developers. Leer wat Server-Side Rendering is, hoe de App Router werkt, en bouw je eerste Next.js applicatie met meerdere pagina's.
---
## Te Behandelen
### Van Idee naar Feature Breakdown
### Wat is Next.js?
**Het probleem:** Je hebt een idee, maar waar begin je?
**React met superpowers:**
- React = library voor UI components
- Next.js = framework dat React complete maakt
**Stap 1: Beschrijf je idee in 1-2 zinnen**
```
"Ik wil een app waar je kunt bijhouden welke planten water nodig hebben."
```
**Stap 2: Vraag AI om feature breakdown**
```
Prompt: Ik wil een plant watering tracker app bouwen.
Wat zijn de minimale features voor een werkend prototype?
Denk aan: wat moet een gebruiker kunnen doen?
```
**Stap 3: Prioriteer (MVP denken)**
- Wat is essentieel? → In prototype
- Wat is nice-to-have? → Later
**Next.js voegt toe:**
- Routing (geen extra library nodig)
- Server-Side Rendering (SEO, performance)
- API routes (backend in je frontend project)
- Optimalisaties (images, fonts, bundling)
---
### Component Thinking
### Server-Side Rendering (SSR) vs Client-Side Rendering (CSR)
**Vraag jezelf af:**
- Welke "blokken" zie ik op het scherm?
- Welke blokken worden herhaald?
- Welke blokken komen op meerdere pagina's?
**Voorbeeld: Plant Tracker**
**Client-Side Rendering (gewone React):**
```
Herhaalde componenten:
- PlantCard (naam, foto, laatste water datum)
- WaterButton (markeer als water gegeven)
1. Browser vraagt pagina
2. Server stuurt lege HTML + JavaScript
3. JavaScript laadt in browser
4. JavaScript rendert de pagina
5. Gebruiker ziet content
```
**Probleem:** Lege pagina tot JS klaar is. Google ziet ook lege pagina.
Pagina componenten:
- PlantList (toont alle PlantCards)
- AddPlantForm (nieuw plant toevoegen)
**Server-Side Rendering (Next.js):**
```
1. Browser vraagt pagina
2. Server rendert HTML met content
3. Browser toont direct de content
4. JavaScript laadt (hydration)
5. Pagina wordt interactief
```
**Voordeel:** Direct content zichtbaar, beter voor SEO.
---
### De App Router
Next.js 13+ gebruikt de "App Router" met file-based routing:
```
app/
├── page.tsx → /
├── about/
│ └── page.tsx → /about
├── products/
│ ├── page.tsx → /products
│ └── [id]/
│ └── page.tsx → /products/123
└── layout.tsx → Wrapper voor alle pagina's
```
**De regel:** Elke `page.tsx` wordt een route!
---
### Project Aanmaken
```bash
npx create-next-app@latest mijn-app
# Antwoorden:
# ✔ TypeScript? → Yes
# ✔ ESLint? → Yes
# ✔ Tailwind CSS? → Yes
# ✔ `src/` directory? → Yes
# ✔ App Router? → Yes
# ✔ Customize import alias? → No
cd mijn-app
npm run dev
```
Open `http://localhost:3000` - je app draait!
---
### Pagina's Maken
**Simpele pagina (`app/about/page.tsx`):**
```tsx
export default function AboutPage() {
return (
<div className="p-8">
<h1 className="text-3xl font-bold">Over Ons</h1>
<p>Welkom op de about pagina!</p>
</div>
)
}
```
Dat is alles! Ga naar `/about` en je ziet je pagina.
---
### Layouts
Layouts wrappen pagina's en blijven behouden tijdens navigatie.
**Root Layout (`app/layout.tsx`):**
```tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="nl">
<body>
<header className="p-4 bg-blue-500 text-white">
<nav>Mijn App</nav>
</header>
<main>{children}</main>
<footer className="p-4 bg-gray-200">
© 2024
</footer>
</body>
</html>
)
}
```
---
### MVP (Minimum Viable Product) Denken
### Nested Layouts
**Wat is MVP?**
De simpelste versie van je app die nog steeds waarde levert.
**❌ Niet MVP:**
- Alle features tegelijk
- Perfect design
- Edge cases afhandelen
- Login systeem
**✅ Wel MVP:**
- Core functionaliteit werkt
- Basis styling
- Happy path werkt
- Hardcoded data is oké
---
### De Prototype Workflow
Je kunt layouts nesten voor secties:
```
1. IDEE (1-2 zinnen)
2. FEATURES (AI breakdown)
3. PRIORITEER (wat is MVP?)
4. COMPONENTS (welke blokken?)
5. BOUWEN (tool per stap)
6. ITEREREN (feedback → aanpassen)
app/
├── layout.tsx → Root layout
├── page.tsx → Homepage
└── dashboard/
├── layout.tsx → Dashboard layout (sidebar)
└── page.tsx → Dashboard pagina
```
**Dashboard Layout (`app/dashboard/layout.tsx`):**
```tsx
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<div className="flex">
<aside className="w-64 bg-gray-100 p-4">
<nav>Sidebar hier</nav>
</aside>
<div className="flex-1">{children}</div>
</div>
)
}
```
---
### Voorbeeld: Weer Widget Prototype
### Dynamic Routes
**Stap 1: Idee**
"Simpele weer widget met 3-daagse forecast"
Voor pagina's met parameters zoals `/products/123`:
**Stap 2: AI Feature Breakdown**
**Folder structuur:**
```
Vraag aan ChatGPT:
"Wat zijn de minimale features voor een weer widget met 3-daagse forecast?"
Antwoord:
- Huidige temperatuur tonen
- Weer icoon (zon, regen, etc.)
- 3-daagse forecast (dag + temp + icoon)
- Locatie tonen
app/products/[id]/page.tsx
```
**Stap 3: MVP Selectie**
- ✅ Huidige temperatuur
- ✅ Weer icoon
- ✅ 3 dagen forecast
- ❌ Locatie selectie (later)
- ❌ Animated icons (later)
**De pagina:**
```tsx
interface Props {
params: { id: string }
}
**Stap 4: Components**
```
WeatherWidget/
├── CurrentWeather (temp + icoon)
├── ForecastDay (dag + temp + icoon)
└── ForecastList (3x ForecastDay)
export default function ProductPage({ params }: Props) {
return (
<div>
<h1>Product {params.id}</h1>
</div>
)
}
```
**Stap 5: Bouwen**
1. v0.dev: "Weather widget with current temp and 3 day forecast, minimal design"
2. OpenCode: "Integreer dit in mijn project, maak components in src/components/weather/"
**Stap 6: Itereren**
- Wat werkt niet?
- Wat kan beter?
- Vraag AI om verbeteringen
Nu werkt `/products/1`, `/products/abc`, etc.
---
### Mini-Project Ideeën
### Link Component
Kies een van deze voor je lesopdracht:
Gebruik `Link` voor client-side navigatie (snel, geen page reload):
| Project | Core Feature | Complexiteit |
|---------|-------------|--------------|
| **Weer Widget** | 3-daagse forecast | ⭐ |
| **Quiz App** | 3 vragen + score | ⭐ |
| **Recipe Card** | Ingrediënten toggle | ⭐ |
| **Pomodoro Timer** | Start/stop + countdown | ⭐⭐ |
| **Expense Tracker** | Lijst + totaal | ⭐⭐ |
```tsx
import Link from 'next/link'
export default function Navigation() {
return (
<nav className="flex gap-4">
<Link href="/">Home</Link>
<Link href="/about">About</Link>
<Link href="/products">Products</Link>
<Link href="/products/123">Product 123</Link>
</nav>
)
}
```
**Niet doen:**
```tsx
// ❌ Dit werkt maar is langzamer
<a href="/about">About</a>
```
---
### Documenteer Je Proces
### Special Files
Maak aantekeningen tijdens het bouwen:
Next.js heeft speciale bestanden:
```markdown
# Mijn Prototype: [naam]
| File | Doel |
|------|------|
| `page.tsx` | De pagina content |
| `layout.tsx` | Wrapper, blijft behouden |
| `loading.tsx` | Loading state |
| `error.tsx` | Error boundary |
| `not-found.tsx` | 404 pagina |
## Idee
[1-2 zinnen]
## Feature Breakdown
1. [feature 1]
2. [feature 2]
3. [feature 3]
## MVP Selectie
- ✅ [wat wel]
- ❌ [wat niet (nog)]
## Components
- [Component 1]
- [Component 2]
## Prompts die Werkten
**Loading state (`app/products/loading.tsx`):**
```tsx
export default function Loading() {
return <div>Laden...</div>
}
```
[prompt]
```
→ [wat leverde het op]
## Wat Ging Fout
- [probleem 1] → [hoe opgelost]
---
## Lessons Learned
- [les 1]
- [les 2]
### Metadata (SEO)
Voeg metadata toe per pagina:
```tsx
import type { Metadata } from 'next'
export const metadata: Metadata = {
title: 'Over Ons | Mijn App',
description: 'Lees meer over ons bedrijf',
}
export default function AboutPage() {
return <h1>Over Ons</h1>
}
```
---
## Tools
- ChatGPT (voor planning)
- v0.dev (voor prototypes)
- OpenCode/WebStorm (voor implementation)
- Next.js 14
- TypeScript
- Tailwind CSS
- OpenCode/WebStorm
- Vercel
---
## Lesopdracht (2 uur)
### Bouw Je Mini-Prototype
### Bouw Multi-Page Next.js App
**Deel 1: Planning (30 min)**
**Deel 1: Project Setup (20 min)**
1. Kies een project uit de lijst (of bedenk eigen simpel idee)
2. Schrijf je idee in 1-2 zinnen
3. Vraag ChatGPT om feature breakdown
4. Selecteer MVP features (max 3)
5. Schets de components op papier
1. `npx create-next-app@latest my-shop` (TypeScript + Tailwind + App Router)
2. Open in editor
3. `npm run dev`
4. Verifieer: `localhost:3000` werkt
**Deel 2: Bouwen (1 uur)**
**Deel 2: Pagina's Maken (40 min)**
1. Genereer UI in v0.dev
2. Open project in OpenCode
3. Integreer en pas aan
4. Zorg dat het werkt (happy path)
Maak deze pagina's:
1. `/` - Homepage met welkomstbericht
2. `/about` - Over ons pagina
3. `/products` - Producten overzicht
4. `/contact` - Contact pagina
**Focus op WORKFLOW, niet perfectie!**
Elke pagina moet unieke content hebben.
**Deel 3: Documentatie (30 min)**
**Deel 3: Layout met Navigatie (30 min)**
Maak `docs/PROTOTYPE-LOG.md`:
- Je idee
- Feature breakdown
- MVP keuzes
- Prompts die werkten
- Wat ging fout en hoe opgelost
- Lessons learned
1. Maak Header component met navigatie (gebruik Link)
2. Maak Footer component
3. Voeg beide toe aan root layout
4. Test: navigatie werkt zonder page reload
**Deel 4: Dynamic Route (30 min)**
1. Maak `/products/[id]` route
2. Toon product ID op de pagina
3. Maak links naar `/products/1`, `/products/2`, `/products/3`
4. Test: alle links werken
**Bonus:** Voeg `loading.tsx` toe aan products folder
### Deliverable
- Werkend prototype (kan simpel zijn)
- `docs/PROTOTYPE-LOG.md` met je proces
- Screenshot van werkend prototype
- Werkende Next.js app met 4+ pagina's
- Navigatie met Link component
- Dynamic route die werkt
- Deploy naar Vercel
---
## Huiswerk (2 uur)
### Verbeter en Reflecteer
### Uitbreiden en Verdiepen
**Deel 1: Prototype Verbeteren (1 uur)**
**Deel 1: Nested Layout (45 min)**
1. Fix eventuele bugs
2. Voeg 1 extra feature toe
3. Verbeter styling
4. Handle 1 edge case
1. Maak `/dashboard` section met eigen layout
2. Dashboard layout heeft sidebar
3. Maak `/dashboard/settings` en `/dashboard/profile` pagina's
4. Test: sidebar blijft bij navigatie binnen dashboard
**Deel 2: Peer Review (30 min)**
**Deel 2: Special Files (45 min)**
- Deel je prototype met een klasgenoot
- Krijg feedback
- Geef feedback op hun prototype
1. Maak `loading.tsx` voor products (toon "Laden...")
2. Maak `error.tsx` voor products (toon error message)
3. Maak `not-found.tsx` in app root (custom 404)
4. Test elk van deze states
**Deel 3: Reflectie (30 min)**
**Deel 3: Metadata (30 min)**
Schrijf "Lessons Learned" document (300 woorden):
- Wat ging goed in je workflow?
- Waar liep je vast?
- Welke tool was het meest nuttig?
- Wat doe je volgende keer anders?
- Hoe voelde het om met AI te bouwen vs alleen?
1. Voeg metadata toe aan elke pagina (title, description)
2. Bekijk in browser: `<head>` toont juiste meta tags
3. Test met Lighthouse: SEO score
### Deliverable
- Verbeterd prototype
- Peer review feedback (gegeven en ontvangen)
- Lessons Learned document (300 woorden)
---
## Voorbereiding Les 7
In Les 7 gaan we echt bouwen met Next.js. Zorg dat je klaar bent:
- Node.js geïnstalleerd (versie 18+)
- Git geconfigureerd
- GitHub account aangemaakt
- OpenCode/WebStorm werkt
Test: run `node --version` in je terminal. Je zou v18 of hoger moeten zien.
- App met nested layouts
- Special files (loading, error, not-found)
- Metadata op elke pagina
- Screenshot van Lighthouse SEO score
---
## Leerdoelen
Na deze les kan de student:
- Van een vaag idee naar concrete features gaan
- AI gebruiken voor feature breakdown
- MVP denken toepassen (essentieel vs nice-to-have)
- Een app opdelen in components
- De complete workflow doorlopen (idee → prototype)
- Het bouwproces documenteren
- Reflecteren op wat werkt en wat niet
- Uitleggen wat Next.js toevoegt aan React
- Het verschil tussen SSR en CSR beschrijven
- Een Next.js project opzetten met App Router
- Pagina's maken met file-based routing
- Layouts gebruiken voor herhalende elementen
- Dynamic routes maken met parameters
- Link component gebruiken voor navigatie
- Special files toepassen (loading, error, not-found)
- Metadata toevoegen voor SEO

View File

@@ -1,349 +1,412 @@
# Les 7: Backend Basics met Supabase
> 📋 **Lesmateriaal nog niet uitgewerkt**
>
> De volgende bestanden worden gegenereerd wanneer deze les wordt uitgewerkt:
> - Les07-Slide-Overzicht.md
> - Les07-Lesplan.md
> - Les07-Bijlage-A-Lesopdracht.md
> - Les07-Bijlage-B-Huiswerkopdracht.md
# Les 7: Next.js Fundamentals 2 - API Routes & Data Fetching
---
## Hoofdstuk
**Hoofdstuk 2: Intermediate** (Les 4-9)
**Deel 2: Technical Foundations** (Les 5-9)
## Beschrijving
Zet je eerste "echte" Next.js project op en koppel het aan Supabase voor database en authenticatie. Je leert de complete flow van lokaal ontwikkelen tot productie deployment.
Leer data fetching in Next.js: Server Components, Client Components, API routes en React Query. Bouw een volledig werkende app met data.
---
## Te Behandelen
### Stap 1: Next.js Project Aanmaken
### Server Components vs Client Components
Dit is de eerste keer dat je een volledig Next.js project opzet.
**Server Components (default in Next.js):**
- Renderen op de server
- Geen JavaScript naar de browser
- Kunnen direct data fetchen (async/await)
- Kunnen NIET: useState, useEffect, event handlers
```bash
# Maak nieuw project
npx create-next-app@latest todo-app
**Client Components:**
- Renderen in de browser
- JavaScript naar de browser
- Kunnen interactief zijn
- Markeer met `'use client'` bovenaan
# Beantwoord de vragen:
# ✔ Would you like to use TypeScript? → Yes
# ✔ Would you like to use ESLint? → Yes
# ✔ Would you like to use Tailwind CSS? → Yes
# ✔ Would you like to use `src/` directory? → Yes
# ✔ Would you like to use App Router? → Yes
# ✔ Would you like to customize the default import alias? → No
---
# Ga naar project folder
cd todo-app
# Open in je editor
code . # of: cursor .
```
### Stap 2: Project Structuur Begrijpen
### Wanneer Wat?
```
todo-app/
├── src/
│ └── app/
│ ├── layout.tsx # Root layout (header, footer)
│ ├── page.tsx # Homepage (/)
│ └── globals.css # Global styles + Tailwind
├── public/ # Static files (images, etc.)
├── .env.local # Environment variables (maak zelf aan)
├── next.config.js # Next.js configuratie
├── tailwind.config.ts # Tailwind configuratie
├── package.json # Dependencies
└── tsconfig.json # TypeScript configuratie
Server Component → Data tonen, geen interactie
Client Component → Interactie nodig (forms, buttons, state)
```
### Stap 3: Lokaal Draaien
```bash
# Start development server
npm run dev
# Open browser: http://localhost:3000
```
### Stap 4: Supabase Project Aanmaken
**Op supabase.com:**
1. Ga naar [supabase.com](https://supabase.com) en maak account (gratis)
2. Klik "New Project"
3. Kies een naam (bijv. `todo-app`)
4. Kies een database wachtwoord (bewaar deze!)
5. Kies region: `West EU (Frankfurt)` (dichtst bij NL)
6. Wacht ~2 minuten tot project klaar is
**Credentials ophalen:**
1. Ga naar Settings → API
2. Kopieer:
- `Project URL` → dit wordt `NEXT_PUBLIC_SUPABASE_URL`
- `anon public` key → dit wordt `NEXT_PUBLIC_SUPABASE_ANON_KEY`
### Stap 5: Environment Variables (Lokaal)
Maak `.env.local` in je project root:
```bash
# .env.local (NOOIT committen naar Git!)
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx
```
Maak ook `.env.example` (deze WEL committen):
```bash
# .env.example (template voor anderen)
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
```
**Check .gitignore:**
```
# .gitignore moet bevatten:
.env*.local
```
### Stap 6: Supabase SDK Installeren
```bash
npm install @supabase/supabase-js
```
### Stap 7: Supabase Client Maken
Maak `src/lib/supabase.ts`:
```typescript
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
```
### Stap 8: Database Tabel Maken (via UI)
**In Supabase Dashboard:**
1. Ga naar Table Editor
2. Klik "New Table"
3. Naam: `todos`
4. Kolommen:
| Name | Type | Default | Primary |
|------|------|---------|---------|
| id | int8 | - | ✓ (auto) |
| title | text | - | |
| completed | bool | false | |
| created_at | timestamptz | now() | |
| user_id | uuid | auth.uid() | |
5. Klik "Save"
### Stap 9: CRUD Operaties
```typescript
// CREATE - nieuwe todo toevoegen
const { data, error } = await supabase
.from('todos')
.insert({ title: 'Nieuwe taak' })
// READ - todos ophalen
const { data, error } = await supabase
.from('todos')
.select('*')
.order('created_at', { ascending: false })
// UPDATE - todo afvinken
const { data, error } = await supabase
.from('todos')
.update({ completed: true })
.eq('id', todoId)
// DELETE - todo verwijderen
const { error } = await supabase
.from('todos')
.delete()
.eq('id', todoId)
```
### Stap 10: Authenticatie Setup
```bash
npm install @supabase/auth-ui-react @supabase/auth-ui-shared
```
**Login component:**
**Voorbeeld:**
```tsx
import { Auth } from '@supabase/auth-ui-react'
import { ThemeSupa } from '@supabase/auth-ui-shared'
import { supabase } from '@/lib/supabase'
// Server Component - data ophalen
async function ProductList() {
const products = await fetchProducts() // Direct fetchen!
return <ul>{products.map(p => <li>{p.name}</li>)}</ul>
}
// Client Component - interactie
'use client'
function AddToCartButton({ productId }) {
const [added, setAdded] = useState(false)
return <button onClick={() => setAdded(true)}>Add</button>
}
```
---
### Data Fetching in Server Components
Simpelweg `async/await` gebruiken:
```tsx
// app/products/page.tsx
interface Product {
id: number
name: string
price: number
}
async function getProducts(): Promise<Product[]> {
const res = await fetch('https://api.example.com/products')
return res.json()
}
export default async function ProductsPage() {
const products = await getProducts()
export function LoginForm() {
return (
<Auth
supabaseClient={supabase}
appearance={{ theme: ThemeSupa }}
providers={[]}
magicLink={true}
/>
<div>
<h1>Producten</h1>
<ul>
{products.map(product => (
<li key={product.id}>
{product.name} - {product.price}
</li>
))}
</ul>
</div>
)
}
```
**Session checken:**
```typescript
const { data: { user } } = await supabase.auth.getUser()
---
if (user) {
// User is ingelogd
} else {
// Redirect naar login
### API Routes (Route Handlers)
Bouw je eigen API in Next.js:
**Folder structuur:**
```
app/
└── api/
└── products/
└── route.ts → /api/products
```
**GET request (`app/api/products/route.ts`):**
```typescript
import { NextResponse } from 'next/server'
const products = [
{ id: 1, name: 'Laptop', price: 999 },
{ id: 2, name: 'Phone', price: 699 },
]
export async function GET() {
return NextResponse.json(products)
}
```
**POST request:**
```typescript
export async function POST(request: Request) {
const body = await request.json()
const newProduct = {
id: Date.now(),
name: body.name,
price: body.price,
}
products.push(newProduct)
return NextResponse.json(newProduct, { status: 201 })
}
```
---
## Deployment naar Vercel (Productie)
### 'use client' Directive
### Stap 1: GitHub Repository
Wanneer je interactie nodig hebt:
```bash
# In je project folder
git init
git add .
git commit -m "Initial commit"
```tsx
'use client' // MOET bovenaan!
# Maak repo op GitHub, dan:
git remote add origin https://github.com/jouw-username/todo-app.git
git push -u origin main
import { useState } from 'react'
export function Counter() {
const [count, setCount] = useState(0)
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
)
}
```
### Stap 2: Vercel Deployment
1. Ga naar [vercel.com](https://vercel.com)
2. "Add New Project"
3. Import je GitHub repository
4. **BELANGRIJK:** Voeg Environment Variables toe:
- `NEXT_PUBLIC_SUPABASE_URL` → je Supabase URL
- `NEXT_PUBLIC_SUPABASE_ANON_KEY` → je anon key
5. Klik "Deploy"
### Stap 3: Supabase URL Toestaan
In Supabase Dashboard:
1. Ga naar Authentication → URL Configuration
2. Voeg je Vercel URL toe aan "Redirect URLs":
- `https://jouw-app.vercel.app/**`
---
## Overzicht: Lokaal vs Productie
### React Query (TanStack Query)
| Aspect | Lokaal | Productie |
|--------|--------|-----------|
| URL | `localhost:3000` | `jouw-app.vercel.app` |
| Env vars | `.env.local` | Vercel Dashboard |
| Database | Supabase (zelfde) | Supabase (zelfde) |
| Command | `npm run dev` | Automatisch via Vercel |
**Waarom React Query?**
- Automatische caching
- Loading en error states
- Refetching (focus, interval)
- Optimistic updates
**Let op:** Je gebruikt dezelfde Supabase database voor lokaal en productie. Voor een echt project zou je aparte databases hebben, maar voor deze cursus is dat niet nodig.
**Installatie:**
```bash
npm install @tanstack/react-query
```
**Setup Provider (`app/providers.tsx`):**
```tsx
'use client'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { useState } from 'react'
export function Providers({ children }: { children: React.ReactNode }) {
const [queryClient] = useState(() => new QueryClient())
return (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
)
}
```
**In Layout:**
```tsx
import { Providers } from './providers'
export default function RootLayout({ children }) {
return (
<html>
<body>
<Providers>{children}</Providers>
</body>
</html>
)
}
```
---
### useQuery - Data Ophalen
```tsx
'use client'
import { useQuery } from '@tanstack/react-query'
interface Product {
id: number
name: string
price: number
}
async function fetchProducts(): Promise<Product[]> {
const res = await fetch('/api/products')
return res.json()
}
export function ProductList() {
const { data, isLoading, error } = useQuery({
queryKey: ['products'],
queryFn: fetchProducts,
})
if (isLoading) return <div>Laden...</div>
if (error) return <div>Error: {error.message}</div>
return (
<ul>
{data?.map(product => (
<li key={product.id}>{product.name}</li>
))}
</ul>
)
}
```
---
### useMutation - Data Wijzigen
```tsx
'use client'
import { useMutation, useQueryClient } from '@tanstack/react-query'
interface NewProduct {
name: string
price: number
}
async function createProduct(product: NewProduct) {
const res = await fetch('/api/products', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(product),
})
return res.json()
}
export function AddProductForm() {
const queryClient = useQueryClient()
const mutation = useMutation({
mutationFn: createProduct,
onSuccess: () => {
// Invalidate and refetch
queryClient.invalidateQueries({ queryKey: ['products'] })
},
})
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
mutation.mutate({ name: 'New Product', price: 99 })
}
return (
<form onSubmit={handleSubmit}>
<button type="submit" disabled={mutation.isPending}>
{mutation.isPending ? 'Toevoegen...' : 'Voeg toe'}
</button>
</form>
)
}
```
---
### Combineren: Server + Client
```tsx
// app/products/page.tsx (Server Component)
import { ProductList } from './product-list'
import { AddProductForm } from './add-product-form'
export default function ProductsPage() {
return (
<div>
<h1>Producten</h1>
<AddProductForm /> {/* Client Component */}
<ProductList /> {/* Client Component */}
</div>
)
}
```
---
## Tools
- Next.js
- Supabase (gratis tier)
- Vercel (gratis tier)
- Cursor/OpenCode
- Next.js 14
- React Query (TanStack Query)
- TypeScript
- OpenCode/WebStorm
---
## Lesopdracht (2 uur)
### Bouw een Todo App met Supabase
### Bouw CRUD App met API Routes
**Deel 1: Project Setup (30 min)**
- Run `npx create-next-app@latest todo-app` met juiste opties
- Maak Supabase account en project aan
- Configureer `.env.local` met credentials
- Installeer `@supabase/supabase-js`
- Maak `src/lib/supabase.ts`
- Test: `npm run dev` werkt zonder errors
**Deel 1: API Routes (40 min)**
**Deel 2: Database (20 min)**
- Maak `todos` tabel via Supabase Table Editor
- Voeg 3 test todos toe via de UI
- Test: data is zichtbaar in Table Editor
1. Maak `app/api/products/route.ts`
2. Implementeer GET (alle producten)
3. Implementeer POST (product toevoegen)
4. Test met browser/Postman: `/api/products`
**Deel 3: CRUD Interface (50 min)**
- Bouw UI om todos te tonen (lijst)
- Voeg form toe om nieuwe todo te maken
- Voeg checkbox toe om todo af te vinken
- Voeg delete button toe
- Test: alle CRUD operaties werken
**Deel 2: React Query Setup (20 min)**
**Deel 4: Authenticatie (20 min)**
- Installeer auth packages
- Maak login pagina met Auth UI
- Toon alleen todos voor ingelogde user
- Test: login met magic link werkt
1. Installeer `@tanstack/react-query`
2. Maak `app/providers.tsx`
3. Wrap app in `QueryClientProvider`
**Deel 3: Data Tonen met useQuery (30 min)**
1. Maak `ProductList` Client Component
2. Gebruik `useQuery` om data te fetchen
3. Toon loading state
4. Toon error state
5. Render product lijst
**Deel 4: Data Toevoegen met useMutation (30 min)**
1. Maak `AddProductForm` Client Component
2. Gebruik `useMutation` voor POST
3. Invalidate query na success
4. Toon "Adding..." state
### Deliverable
- Werkende Todo app lokaal
- GitHub repository met code
- Screenshot van werkende app
- Werkende API routes (GET, POST)
- ProductList met useQuery
- AddProductForm met useMutation
- Loading en error states
---
## Huiswerk (2 uur)
### Deploy naar Productie + Uitbreiden
### Volledige CRUD Interface
**Deel 1: Deployment (30 min)**
- Push code naar GitHub
- Deploy naar Vercel
- Configureer environment variables in Vercel
- Voeg Vercel URL toe aan Supabase Redirect URLs
- Test: app werkt op productie URL
**Deel 1: PUT en DELETE Routes (45 min)**
**Deel 2: Features Uitbreiden (1 uur)**
- Filter buttons: Alle / Actief / Voltooid
- Sorteer op datum (nieuwste eerst)
- Toon alleen todos van ingelogde user (filter op `user_id`)
- Loading state tijdens data ophalen
- Error state bij problemen
- Empty state: "Geen todos gevonden"
1. Maak `app/api/products/[id]/route.ts`
2. Implementeer PUT (update product)
3. Implementeer DELETE (verwijder product)
4. Test beide endpoints
**Deel 3: Polish (30 min)**
- Styling verbeteren met Tailwind
- Responsive design (mobile friendly)
- Kleine animaties (fade in/out)
**Deel 2: Update Functionaliteit (45 min)**
1. Maak edit form in ProductList
2. Gebruik useMutation voor PUT
3. Inline editing OF modal
4. Invalidate query na success
**Deel 3: Delete Functionaliteit (30 min)**
1. Voeg delete button toe per product
2. Gebruik useMutation voor DELETE
3. Voeg confirmation dialog toe
4. Invalidate query na success
**Bonus:** Optimistic Updates
- Product direct uit UI verwijderen
- Rollback als server faalt
### Deliverable
- Deployed app op Vercel (werkende URL)
- Alle features werken in productie
- Screenshot van productie app
- Complete CRUD API (GET, POST, PUT, DELETE)
- UI voor alle operaties
- Error handling
- Optimistic updates (bonus)
---
## Leerdoelen
Na deze les kan de student:
- Een Next.js project opzetten met `npx create-next-app`
- De project structuur begrijpen en navigeren
- Een Supabase project aanmaken en configureren
- Environment variables correct beheren (lokaal en productie)
- De Supabase client installeren en configureren
- Tabellen maken via de Supabase UI
- CRUD operaties uitvoeren met de Supabase SDK
- Authenticatie implementeren met Auth UI
- Deployen naar Vercel met environment variables
- Het verschil tussen lokale en productie omgeving begrijpen
- Uitleggen wanneer Server vs Client Components
- De 'use client' directive correct gebruiken
- Data fetchen in Server Components met async/await
- API routes maken met Route Handlers
- GET en POST requests implementeren
- React Query installeren en configureren
- useQuery gebruiken voor data fetching
- useMutation gebruiken voor data mutations
- Loading en error states afhandelen
- Query invalidation toepassen

View File

@@ -1,320 +1,372 @@
# Les 8: Supabase Basics
# Les 8: Database Principles
---
## Hoofdstuk
**Hoofdstuk 2: Intermediate** (Les 4-9)
**Deel 2: Technical Foundations** (Les 5-9)
## Beschrijving
Leer werken met Supabase: een complete backend-as-a-service met database en authenticatie. Je bouwt je eerste full-stack app met data die persistent is.
Leer de basisprincipes van relationele databases voordat we Supabase gaan gebruiken. Begrijp tabellen, relaties, keys en normalisatie - essentiële kennis voor elke developer.
---
## Te Behandelen
### Wat is Supabase?
### Wat is een Relationele Database?
**Supabase = Database + Auth in één**
- PostgreSQL database (gratis tier: 500MB)
- Ingebouwde authenticatie
- Real-time subscriptions
- File storage
- Auto-generated API
**Een database is:** Een georganiseerde verzameling van data.
**Waarom Supabase voor beginners:**
- Geen eigen server nodig
- Visuele Table Editor (geen SQL kennis nodig)
- Simpele JavaScript SDK
- Gratis tier is ruim voldoende
**Relationeel betekent:** Data is opgeslagen in tabellen die aan elkaar gerelateerd zijn.
**Vergelijk het met Excel:**
- Database = Excel workbook
- Tabel = Excel sheet
- Kolom = Excel kolom (field)
- Rij = Excel rij (record)
---
### Supabase Project Aanmaken
### Tabellen, Kolommen en Rijen
**Stap 1:** Ga naar [supabase.com](https://supabase.com) en maak account
**Voorbeeld: Users tabel**
**Stap 2:** Klik "New Project"
- Naam: `todo-app`
- Database Password: (bewaar deze!)
- Region: `West EU (Frankfurt)` (dichtst bij NL)
| id | name | email | created_at |
|----|------|-------|------------|
| 1 | Tim | tim@email.com | 2024-01-15 |
| 2 | Anna | anna@email.com | 2024-01-16 |
| 3 | Jan | jan@email.com | 2024-01-17 |
**Stap 3:** Wacht ~2 minuten tot project klaar is
**Stap 4:** Ga naar Settings → API en kopieer:
- `Project URL`
- `anon public` key
**Terminologie:**
- **Tabel:** users
- **Kolommen:** id, name, email, created_at
- **Rijen:** 3 records (Tim, Anna, Jan)
- **Cell:** Eén specifieke waarde (bijv. "tim@email.com")
---
### Tabel Maken via Table Editor
### Data Types
**In Supabase Dashboard:**
Elke kolom heeft een type:
1. Ga naar "Table Editor"
2. Klik "New Table"
3. Naam: `todos`
4. Kolommen:
| Type | Beschrijving | Voorbeeld |
|------|--------------|-----------|
| `text` / `varchar` | Tekst | "Tim", "Hello world" |
| `integer` / `int` | Hele getallen | 1, 42, -5 |
| `decimal` / `numeric` | Decimalen | 19.99, 3.14 |
| `boolean` | True/False | true, false |
| `timestamp` | Datum + tijd | 2024-01-15 14:30:00 |
| `uuid` | Unieke identifier | a1b2c3d4-e5f6-... |
| Name | Type | Default | Primary |
|------|------|---------|---------|
| id | int8 | - | ✓ (auto) |
| title | text | - | |
| completed | bool | false | |
| created_at | timestamptz | now() | |
5. Klik "Save"
**Test:** Voeg een paar rijen toe via de UI om te zien dat het werkt.
**Kies het juiste type:**
- Prijs? → `decimal` (niet `integer`, want centen)
- Is actief? → `boolean`
- Naam? → `text`
- Aantal? → `integer`
---
### Environment Variables
### Primary Keys
**Wat zijn environment variables?**
- Configuratie die NIET in je code hoort
- API keys, database URLs, secrets
- Verschillend per omgeving (lokaal vs productie)
**Wat:** Een kolom die elke rij UNIEK identificeert.
**Maak `.env.local` in je project root:**
```bash
# .env.local - NOOIT committen naar Git!
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx
**Regels:**
- Moet uniek zijn per rij
- Mag nooit NULL zijn
- Verandert nooit
**Voorbeeld:**
```
users
------
id (PRIMARY KEY) | name | email
1 | Tim | tim@email.com
2 | Anna | anna@email.com
```
**Maak ook `.env.example` (WEL committen):**
```bash
# .env.example - template voor anderen
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
**Waarom niet `email` als primary key?**
- Emails kunnen veranderen
- `id` is stabiel en snel
---
### Foreign Keys
**Wat:** Een kolom die verwijst naar de primary key van een andere tabel.
**Voorbeeld: Posts tabel**
```
posts
------
id | title | user_id (FOREIGN KEY → users.id)
1 | "Mijn blog" | 1
2 | "Hello world" | 1
3 | "Tips" | 2
```
**Check `.gitignore` bevat:**
**Wat zegt dit?**
- Post 1 en 2 zijn van user 1 (Tim)
- Post 3 is van user 2 (Anna)
---
### Relatie Types
**One-to-Many (1:N)** - Meest voorkomend!
```
.env*.local
Eén user → meerdere posts
Eén category → meerdere products
```
**One-to-One (1:1)** - Zeldzaam
```
Eén user → één profile
```
**Many-to-Many (N:N)** - Via tussentabel
```
Posts ↔ Tags (een post heeft meerdere tags, een tag heeft meerdere posts)
```
---
### Supabase SDK Installeren
### One-to-Many Voorbeeld
```bash
npm install @supabase/supabase-js
```
users posts
------ ------
id | name id | title | user_id
1 | Tim ←────────── 1 | "Blog 1" | 1
2 | Anna ←────┬───── 2 | "Blog 2" | 1
└───── 3 | "Tips" | 2
```
**Maak `src/lib/supabase.ts`:**
```typescript
import { createClient } from '@supabase/supabase-js'
**Lees:** Tim heeft 2 posts, Anna heeft 1 post.
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
---
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
### Many-to-Many met Tussentabel
```
posts post_tags tags
------ --------- ------
id | title post_id | tag_id id | name
1 | "React tips" 1 | 1 1 | "react"
2 | "CSS guide" 1 | 2 2 | "frontend"
2 | 2 3 | "css"
2 | 3
```
**Lees:**
- Post 1 heeft tags: react, frontend
- Post 2 heeft tags: frontend, css
---
### Normalisatie Basics
**Probleem: Data duplicatie**
```
orders (SLECHT)
------
id | customer_name | customer_email | product_name | price
1 | Tim | tim@email.com | Laptop | 999
2 | Tim | tim@email.com | Phone | 699
3 | Anna | anna@email.com | Laptop | 999
```
**Problemen:**
- Tim's email staat 2x (als hij verandert: 2 plekken updaten)
- "Laptop" en prijs staan 2x
---
### Genormaliseerde Versie
```
users products orders
------ -------- ------
id | name | email id | name | price id | user_id | product_id
1 | Tim | tim@... 1 | Laptop | 999 1 | 1 | 1
2 | Anna | anna@... 2 | Phone | 699 2 | 1 | 2
3 | 2 | 1
```
**Voordelen:**
- Elk gegeven staat 1x
- Update op 1 plek
- Minder opslagruimte
---
### NULL Values
**NULL = "geen waarde" (niet 0, niet "")**
```
users
------
id | name | phone
1 | Tim | 0612345678
2 | Anna | NULL ← Geen telefoon bekend
```
**Wanneer NULL toestaan?**
- Optionele velden (phone, description)
- Niet bij verplichte velden (name, email)
---
### Defaults
**Automatische waarde als je niks opgeeft:**
```
todos
------
id | title | completed | created_at
| | DEFAULT: false | DEFAULT: now()
```
Bij `INSERT INTO todos (title) VALUES ('Test')`:
```
id | title | completed | created_at
1 | Test | false | 2024-01-15 10:30:00
```
---
### CRUD Operaties
### Database Schema Tekenen
**C - Create (toevoegen):**
```typescript
const { data, error } = await supabase
.from('todos')
.insert({ title: 'Nieuwe taak' })
**Tools:** draw.io, Excalidraw, pen en papier
**Conventie:**
```
┌──────────────┐ ┌──────────────┐
│ users │ │ posts │
├──────────────┤ ├──────────────┤
│ id (PK) │───┐ │ id (PK) │
│ name │ │ │ title │
│ email │ └────→│ user_id (FK) │
│ created_at │ │ content │
└──────────────┘ │ created_at │
└──────────────┘
```
**R - Read (ophalen):**
```typescript
const { data, error } = await supabase
.from('todos')
.select('*')
.order('created_at', { ascending: false })
```
**U - Update (wijzigen):**
```typescript
const { data, error } = await supabase
.from('todos')
.update({ completed: true })
.eq('id', todoId)
```
**D - Delete (verwijderen):**
```typescript
const { error } = await supabase
.from('todos')
.delete()
.eq('id', todoId)
```
---
### Authenticatie met Auth UI
**Installeer auth packages:**
```bash
npm install @supabase/auth-ui-react @supabase/auth-ui-shared
```
**Login component:**
```tsx
import { Auth } from '@supabase/auth-ui-react'
import { ThemeSupa } from '@supabase/auth-ui-shared'
import { supabase } from '@/lib/supabase'
export function LoginForm() {
return (
<Auth
supabaseClient={supabase}
appearance={{ theme: ThemeSupa }}
providers={[]}
magicLink={true}
/>
)
}
```
**Huidige user checken:**
```typescript
const { data: { user } } = await supabase.auth.getUser()
if (user) {
// User is ingelogd
console.log('Logged in as:', user.email)
} else {
// Redirect naar login
}
```
---
### Deployment naar Vercel
**Stap 1: Push naar GitHub**
```bash
git add .
git commit -m "Add Supabase integration"
git push
```
**Stap 2: Deploy op Vercel**
1. Ga naar [vercel.com](https://vercel.com)
2. "Add New Project"
3. Import je GitHub repo
4. **BELANGRIJK:** Voeg Environment Variables toe!
- `NEXT_PUBLIC_SUPABASE_URL`
- `NEXT_PUBLIC_SUPABASE_ANON_KEY`
5. Klik "Deploy"
**Stap 3: Supabase Redirect URLs**
1. Ga naar Supabase → Authentication → URL Configuration
2. Voeg toe bij "Redirect URLs":
- `https://jouw-app.vercel.app/**`
---
### Lokaal vs Productie
| Aspect | Lokaal | Productie |
|--------|--------|-----------|
| URL | `localhost:3000` | `jouw-app.vercel.app` |
| Env vars | `.env.local` | Vercel Dashboard |
| Database | Supabase (zelfde) | Supabase (zelfde) |
| Command | `npm run dev` | Automatisch via Vercel |
**Let op:** Je gebruikt dezelfde Supabase database voor lokaal en productie. Voor echte projecten zou je aparte databases hebben.
PK = Primary Key
FK = Foreign Key
Pijl = Relatie richting
---
## Tools
- Supabase
- Next.js
- OpenCode/WebStorm
- Vercel
- Git
- Pen en papier / Excalidraw / draw.io
- Supabase Table Editor (vooruitblik)
---
## Lesopdracht (2 uur)
### Bouw een Todo App met Supabase
### Database Design Oefening
**Deel 1: Supabase Setup (30 min)**
**Deel 1: Blog Database Ontwerpen (45 min)**
1. Maak Supabase account en project
2. Maak `todos` tabel via Table Editor
3. Kopieer credentials
4. Installeer `@supabase/supabase-js`
5. Maak `src/lib/supabase.ts`
6. Configureer `.env.local`
Ontwerp een database voor een blog met:
- Users (kunnen posts schrijven)
- Posts (hebben een auteur)
- Comments (op posts, door users)
Test: `npm run dev` werkt zonder errors
Voor elke tabel:
1. Teken de tabel met kolommen
2. Bepaal data types
3. Markeer Primary Keys
4. Markeer Foreign Keys
5. Teken de relaties
**Deel 2: CRUD Interface (1 uur)**
**Deel 2: Normalisatie Oefening (30 min)**
Bouw UI voor todos:
1. Lijst van todos tonen
2. Form om nieuwe todo toe te voegen
3. Checkbox om todo af te vinken
4. Delete button per todo
Gegeven deze "slechte" tabel:
Gebruik AI hulp voor de components!
```
library
-------
book_title | author_name | author_email | borrower_name | borrowed_date
"1984" | "Orwell" | orwell@... | "Tim" | 2024-01-15
"1984" | "Orwell" | orwell@... | "Anna" | 2024-01-10
"Dune" | "Herbert" | herbert@... | "Tim" | 2024-01-12
```
**Deel 3: Authenticatie (30 min)**
Normaliseer naar aparte tabellen:
1. Welke entiteiten zie je?
2. Maak aparte tabellen
3. Voeg relaties toe
1. Installeer auth packages
2. Maak login pagina met Auth UI
3. Toon alleen app voor ingelogde users
4. Test: login met magic link
**Deel 3: Eindproject Schema (45 min)**
Ontwerp het database schema voor jouw eindproject:
1. Welke entiteiten heb je nodig?
2. Teken elke tabel met kolommen
3. Bepaal relaties
4. Documenteer je keuzes
### Deliverable
- Werkende Todo app lokaal
- GitHub repository met code
- Screenshot van werkende app
- Blog database schema (tekening)
- Genormaliseerde library database
- Eindproject database schema
---
## Huiswerk (2 uur)
### Deploy naar Productie + Uitbreiden
### Verdieping en Voorbereiding
**Deel 1: Deployment (30 min)**
**Deel 1: Eindproject Schema Uitwerken (1 uur)**
1. Push naar GitHub
2. Deploy naar Vercel
3. Configureer env vars in Vercel
4. Voeg Vercel URL toe aan Supabase Redirect URLs
5. Test: app werkt op productie URL!
Werk je database schema volledig uit:
**Deel 2: Features Uitbreiden (1 uur)**
1. **Per tabel:**
- Naam
- Alle kolommen met data types
- Primary key
- Foreign keys
- Defaults
- Nullable fields
Voeg toe:
1. Filter buttons: Alle / Actief / Voltooid
2. Sorteer op datum (nieuwste eerst)
3. Loading state tijdens data ophalen
4. Error state bij problemen
5. Empty state: "Geen todos gevonden"
2. **Documenteer:**
- Waarom deze structuur?
- Welke relaties?
- Eventuele alternatieve overwegingen
**Deel 3: Polish (30 min)**
**Deel 2: Supabase Account (30 min)**
1. Styling verbeteren met Tailwind
2. Responsive design (mobile friendly)
3. Kleine animaties (fade in/out)
Bereid je voor op volgende les:
1. Maak account op [supabase.com](https://supabase.com)
2. Verken de interface
3. Bekijk de Table Editor
**Deel 3: Reflectie (30 min)**
Beantwoord deze vragen (kort):
1. Wat is het verschil tussen primary en foreign key?
2. Waarom normaliseren we data?
3. Wanneer gebruik je one-to-many vs many-to-many?
4. Welke tabellen heeft jouw eindproject nodig?
### Deliverable
- Deployed app op Vercel (werkende URL!)
- Alle features werken in productie
- Screenshot van productie app
- Volledig uitgewerkt database schema voor eindproject
- Supabase account aangemaakt
- Reflectie vragen beantwoord
---
## Leerdoelen
Na deze les kan de student:
- Een Supabase project aanmaken en configureren
- Tabellen maken via de Table Editor (zonder SQL)
- Environment variables correct beheren
- De Supabase client installeren en configureren
- CRUD operaties uitvoeren met de Supabase SDK
- Authenticatie implementeren met Auth UI
- Deployen naar Vercel met environment variables
- Het verschil tussen lokale en productie omgeving begrijpen
- Uitleggen wat een relationele database is
- Tabellen, kolommen en rijen beschrijven
- De juiste data types kiezen
- Primary keys en hun doel uitleggen
- Foreign keys en relaties begrijpen
- One-to-many en many-to-many relaties herkennen
- Het probleem van data duplicatie identificeren
- Een database normaliseren
- NULL values en defaults begrijpen
- Een database schema ontwerpen en tekenen

View File

@@ -1,302 +1,305 @@
# Les 9: AI Agents - Custom GPTs & Claude Projects
# Les 9: Supabase Basics
---
## Hoofdstuk
**Hoofdstuk 2: Intermediate** (Les 4-9)
**Deel 2: Technical Foundations** (Les 5-9)
## Beschrijving
Leer werken met AI Agents: gepersonaliseerde AI assistenten die je kunt trainen op jouw specifieke taken en werkwijze.
Leer werken met Supabase: een complete backend-as-a-service met database en authenticatie. Pas je database schema uit Les 8 toe en bouw je eerste full-stack app.
---
## Te Behandelen
### Wat zijn AI Agents?
### Wat is Supabase?
**Chatbot vs Agent:**
**Supabase = Database + Auth in één**
- PostgreSQL database (gratis tier: 500MB)
- Ingebouwde authenticatie
- Real-time subscriptions
- File storage
- Auto-generated API
| Chatbot | Agent |
|---------|-------|
| Reageert op vragen | Neemt initiatief |
| Geen geheugen | Onthoudt context |
| Algemene kennis | Specifieke expertise |
| Eenmalige interactie | Langere samenwerkingen |
**Agent = AI met:**
- Custom instructies (hoe moet hij zich gedragen)
- Eigen kennis (documenten, voorbeelden)
- Specifieke taken (waar is hij goed in)
**Waarom Supabase voor beginners:**
- Geen eigen server nodig
- Visuele Table Editor (geen SQL kennis nodig)
- Simpele JavaScript SDK
- Gratis tier is ruim voldoende
---
### Custom GPTs (ChatGPT)
### Supabase Project Aanmaken
**Wat is een Custom GPT?**
Een gepersonaliseerde versie van ChatGPT voor specifieke taken.
**Stap 1:** Ga naar [supabase.com](https://supabase.com) en maak account
**Onderdelen:**
1. **Instructions:** Hoe moet de GPT zich gedragen?
2. **Conversation starters:** Voorbeeld prompts
3. **Knowledge:** Upload documenten als context
4. **Capabilities:** Web browsing, code interpreter, DALL-E
**Stap 2:** Klik "New Project"
- Naam: `todo-app`
- Database Password: (bewaar deze!)
- Region: `West EU (Frankfurt)` (dichtst bij NL)
**Voorbeeld: Code Reviewer GPT**
**Stap 3:** Wacht ~2 minuten tot project klaar is
*Instructions:*
**Stap 4:** Ga naar Settings → API en kopieer:
- `Project URL`
- `anon public` key
---
### Je Database Schema Implementeren
In Les 8 heb je een database schema ontworpen. Nu gaan we dat implementeren!
**In Supabase Dashboard → Table Editor:**
1. Klik "New Table"
2. Gebruik je schema uit Les 8
3. Voeg kolommen toe met de juiste types
4. Definieer Primary Keys en Foreign Keys
**Voorbeeld: todos tabel**
| Name | Type | Default | Primary |
|------|------|---------|---------|
| id | int8 | - | ✓ (auto) |
| title | text | - | |
| completed | bool | false | |
| created_at | timestamptz | now() | |
---
### Environment Variables
**Wat zijn environment variables?**
- Configuratie die NIET in je code hoort
- API keys, database URLs, secrets
- Verschillend per omgeving (lokaal vs productie)
**Maak `.env.local` in je project root:**
```bash
# .env.local - NOOIT committen naar Git!
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx
```
Je bent een strenge code reviewer voor React/TypeScript projecten.
Bij elke code review check je:
1. TypeScript types correct?
2. React best practices gevolgd?
3. Geen hardcoded values?
4. Error handling aanwezig?
5. Accessibility (ARIA labels)?
Geef feedback in dit format:
- ✅ Goed: [wat is goed]
- ⚠️ Verbeter: [wat kan beter]
- ❌ Fix: [wat moet gefixed worden]
Wees streng maar constructief.
**Maak ook `.env.example` (WEL committen):**
```bash
# .env.example - template voor anderen
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
```
---
### Claude Projects
### Supabase SDK Installeren
**Wat is een Claude Project?**
Een Claude-omgeving met custom context voor een specifiek project.
**Onderdelen:**
1. **Project Knowledge:** Upload relevante documenten
2. **Custom Instructions:** Hoe moet Claude zich gedragen
3. **Conversation History:** Context blijft bewaard
**Voordelen:**
- Langere context dan ChatGPT
- Betere nuance in antwoorden
- Artifacts voor code en documenten
**Voorbeeld: Project voor je Todo App**
*Custom Instructions:*
```
Dit is mijn Todo app project.
Tech stack:
- Next.js 14 met App Router
- TypeScript
- Tailwind CSS
- Supabase voor database en auth
Code conventies:
- Functional components
- Named exports
- Async/await (geen .then)
Als je code schrijft, volg altijd deze conventies.
```bash
npm install @supabase/supabase-js
```
*Project Knowledge:*
- Upload je belangrijkste component files
- Upload je Supabase schema
**Maak `src/lib/supabase.ts`:**
```typescript
import { createClient } from '@supabase/supabase-js'
---
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
### Wanneer Welke Gebruiken?
| Situatie | Tool |
|----------|------|
| Snelle code review | Custom GPT |
| Werken aan specifiek project | Claude Project |
| Documentatie genereren | Custom GPT |
| Lange context nodig | Claude Project |
| Wil delen met anderen | Custom GPT |
| Privé project context | Claude Project |
---
### Custom GPT Maken
**Stap 1:** Ga naar chat.openai.com → "Explore GPTs" → "Create"
**Stap 2:** Vul in:
- Naam: "React Code Reviewer"
- Beschrijving: "Reviews React/TypeScript code"
- Instructions: (zie voorbeeld hierboven)
**Stap 3:** Test met echte code
**Stap 4:** Itereer op instructions
- Wat mist hij?
- Wat doet hij verkeerd?
- Pas aan en test opnieuw
---
### Claude Project Maken
**Stap 1:** Ga naar claude.ai → "Projects" → "Create project"
**Stap 2:** Geef project een naam
**Stap 3:** Upload Project Knowledge
- Drag & drop je belangrijkste files
- Of kopieer/plak code snippets
**Stap 4:** Schrijf Custom Instructions
- Beschrijf je tech stack
- Beschrijf je conventies
- Beschrijf wat je wilt dat Claude doet
**Stap 5:** Start chatten binnen het project
---
### Agent Instructions Schrijven
**Goede instructions bevatten:**
1. **Rol:** Wie is de agent?
```
Je bent een senior React developer die code reviewt.
```
2. **Context:** Wat is de situatie?
```
Je reviewt code voor een startup met strakke deadlines.
Focus op kritieke issues, niet op style preferences.
```
3. **Gedrag:** Hoe moet hij reageren?
```
Wees direct maar vriendelijk.
Geef altijd een voorbeeld van de betere oplossing.
```
4. **Format:** Hoe moet output eruitzien?
```
Gebruik markdown formatting.
Groepeer feedback per categorie.
```
5. **Beperkingen:** Wat moet hij NIET doen?
```
Herschrijf niet de hele codebase.
Focus op de gevraagde code, niet op andere files.
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
```
---
### Praktische Agent Ideeën
### CRUD Operaties
| Agent | Doel |
|-------|------|
| **Code Reviewer** | Check code op bugs en best practices |
| **Doc Generator** | Genereer documentatie voor components |
| **Bug Debugger** | Help bij error messages uitleggen |
| **Refactor Helper** | Suggesties voor code verbetering |
| **Test Writer** | Genereer unit tests |
| **Rubber Duck** | Denk hardop mee over problemen |
**C - Create (toevoegen):**
```typescript
const { data, error } = await supabase
.from('todos')
.insert({ title: 'Nieuwe taak' })
```
**R - Read (ophalen):**
```typescript
const { data, error } = await supabase
.from('todos')
.select('*')
.order('created_at', { ascending: false })
```
**U - Update (wijzigen):**
```typescript
const { data, error } = await supabase
.from('todos')
.update({ completed: true })
.eq('id', todoId)
```
**D - Delete (verwijderen):**
```typescript
const { error } = await supabase
.from('todos')
.delete()
.eq('id', todoId)
```
---
### Authenticatie met Auth UI
**Installeer auth packages:**
```bash
npm install @supabase/auth-ui-react @supabase/auth-ui-shared
```
**Login component:**
```tsx
import { Auth } from '@supabase/auth-ui-react'
import { ThemeSupa } from '@supabase/auth-ui-shared'
import { supabase } from '@/lib/supabase'
export function LoginForm() {
return (
<Auth
supabaseClient={supabase}
appearance={{ theme: ThemeSupa }}
providers={[]}
magicLink={true}
/>
)
}
```
**Huidige user checken:**
```typescript
const { data: { user } } = await supabase.auth.getUser()
if (user) {
// User is ingelogd
console.log('Logged in as:', user.email)
} else {
// Redirect naar login
}
```
---
### Deployment naar Vercel
**Stap 1: Push naar GitHub**
```bash
git add .
git commit -m "Add Supabase integration"
git push
```
**Stap 2: Deploy op Vercel**
1. Ga naar [vercel.com](https://vercel.com)
2. "Add New Project"
3. Import je GitHub repo
4. **BELANGRIJK:** Voeg Environment Variables toe!
- `NEXT_PUBLIC_SUPABASE_URL`
- `NEXT_PUBLIC_SUPABASE_ANON_KEY`
5. Klik "Deploy"
**Stap 3: Supabase Redirect URLs**
1. Ga naar Supabase → Authentication → URL Configuration
2. Voeg toe bij "Redirect URLs":
- `https://jouw-app.vercel.app/**`
---
## Tools
- ChatGPT (Custom GPTs)
- Claude Desktop (Projects)
- Supabase
- Next.js
- OpenCode/WebStorm
- Vercel
- Git
---
## Lesopdracht (2 uur)
### Bouw Je Eerste AI Agents
### Bouw een Todo App met Supabase
**Deel 1: Custom GPT - Code Reviewer (45 min)**
**Groepsdiscussie (15 min):**
Bespreek klassikaal de database schemas uit Les 8 - wie heeft welke structuur gekozen en waarom?
1. Ga naar ChatGPT → Create GPT
2. Maak "Code Reviewer" met deze checklist:
- TypeScript types
- React best practices
- Error handling
- Accessibility
- Performance
3. Upload sample "goede" code als knowledge
4. Test met code uit je Todo app
5. Itereer op de instructions
**Deel 1: Supabase Setup (30 min)**
**Deel 2: Claude Project - Todo App Context (45 min)**
1. Maak Supabase account en project
2. Maak je tabellen via Table Editor (gebaseerd op Les 8 schema)
3. Kopieer credentials
4. Installeer `@supabase/supabase-js`
5. Maak `src/lib/supabase.ts`
6. Configureer `.env.local`
1. Maak nieuw Claude Project
2. Upload je Todo app files als knowledge
3. Schrijf custom instructions met je tech stack
4. Test: vraag Claude om een nieuwe feature te bouwen
5. Vergelijk: kent hij je project context?
Test: `npm run dev` werkt zonder errors
**Deel 3: Vergelijking (30 min)**
**Deel 2: CRUD Interface (1 uur)**
Test dezelfde vraag in beide:
```
Review deze code en geef verbeter suggesties:
[plak je TodoList component]
```
Bouw UI voor todos:
1. Lijst van todos tonen
2. Form om nieuwe todo toe te voegen
3. Checkbox om todo af te vinken
4. Delete button per todo
Documenteer:
- Welke geeft betere feedback?
- Welke voelt meer "op maat"?
- Wanneer zou je welke gebruiken?
Gebruik AI hulp voor de components!
**Deel 3: Authenticatie (30 min)**
1. Installeer auth packages
2. Maak login pagina met Auth UI
3. Toon alleen app voor ingelogde users
4. Test: login met magic link
### Deliverable
- Werkende Custom GPT (link delen)
- Claude Project met project context
- Vergelijkings notities
- Werkende Todo app lokaal
- GitHub repository met code
- Screenshot van werkende app
---
## Huiswerk (2 uur)
### Personal Dev Assistant
### Deploy naar Productie + Uitbreiden
**Deel 1: Bouw Je Personal Assistant (1 uur)**
**Deel 1: Deployment (30 min)**
Maak een Custom GPT of Claude Project die:
- Jouw coding standards kent
- Jouw tech stack begrijpt
- Jouw workflow ondersteunt
1. Push naar GitHub
2. Deploy naar Vercel
3. Configureer env vars in Vercel
4. Voeg Vercel URL toe aan Supabase Redirect URLs
5. Test: app werkt op productie URL!
**Include in instructions:**
- Jouw voorkeuren (tabs vs spaces, etc.)
- Jouw tech stack details
- Typische taken die je doet
- Hoe je feedback wilt krijgen
**Deel 2: Features Uitbreiden (1 uur)**
**Deel 2: Test in Echt Werk (45 min)**
Voeg toe:
1. Filter buttons: Alle / Actief / Voltooid
2. Sorteer op datum (nieuwste eerst)
3. Loading state tijdens data ophalen
4. Error state bij problemen
5. Empty state: "Geen todos gevonden"
Gebruik je assistant voor echte taken:
1. Code review van een component
2. Help bij een bug
3. Genereer documentatie
**Deel 3: Polish (30 min)**
**Deel 3: Reflectie (15 min)**
Schrijf korte reflectie (300 woorden):
- Hoe helpful was je agent?
- Wat zou je verbeteren?
- Ga je dit blijven gebruiken?
1. Styling verbeteren met Tailwind
2. Responsive design (mobile friendly)
3. Kleine animaties (fade in/out)
### Deliverable
- Personal Dev Assistant (GPT link of Claude Project screenshot)
- 3 voorbeelden van gebruik
- Reflectie (300 woorden)
- Deployed app op Vercel (werkende URL!)
- Alle features werken in productie
- Screenshot van productie app
---
## Leerdoelen
Na deze les kan de student:
- Het verschil uitleggen tussen chatbots en AI agents
- Custom GPTs bouwen met instructions en knowledge base
- Claude Projects opzetten met custom instructions en context
- Effectieve agent instructions schrijven
- De juiste tool kiezen (Custom GPT vs Claude Project)
- Een personal dev assistant maken voor eigen workflow
- Een Supabase project aanmaken en configureren
- Database schema implementeren via Table Editor
- Environment variables correct beheren
- De Supabase client installeren en configureren
- CRUD operaties uitvoeren met de Supabase SDK
- Authenticatie implementeren met Auth UI
- Deployen naar Vercel met environment variables
- Database principles uit Les 8 toepassen in de praktijk

View File

@@ -1,278 +1,270 @@
# Les 10: Introduction to Cursor
# Les 10: AI Tool Selection & Workflows
---
## Hoofdstuk
**Hoofdstuk 3: Advanced** (Les 10-18)
**Deel 3: AI Tooling & Prototyping** (Les 10-12)
## Beschrijving
Kennismaking met Cursor - de professionele AI code editor. Leer de core features en ontdek waarom dit de tool is voor serieuze AI-assisted development.
Leer de sterke en zwakke punten van elke AI tool kennen. Ontwikkel een framework om de juiste tool te kiezen voor de juiste taak en bouw je eigen workflow.
---
## Te Behandelen
### Waarom Cursor?
### Waarom Tool Selection Belangrijk Is
**Tot nu toe gebruikten we:**
- OpenCode (gratis, goed voor leren)
- Claude Desktop (voor agents en projects)
Je kent nu meerdere AI tools:
- ChatGPT (brainstormen, planning, uitleg)
- Claude (lange context, nuance, analyse)
- v0.dev (UI prototyping)
- OpenCode (code schrijven met project context)
**Cursor is de volgende stap:**
- Purpose-built voor AI-assisted coding
- Professionele editor (gebaseerd op VS Code)
- Superieure AI integratie
- Free tier beschikbaar (voldoende voor de cursus)
**Het probleem:** Elke tool heeft sterke en zwakke punten. De juiste tool kiezen bespaart tijd en levert betere resultaten.
---
### Free vs Pro
### Tool Vergelijking
| Aspect | Free Tier | Pro ($20/maand) |
|--------|-----------|-----------------|
| Tab completion | ✅ | ✅ |
| CMD+K edits | Beperkt | Onbeperkt |
| Chat | Beperkt | Onbeperkt |
| Composer | Beperkt | Onbeperkt |
| Models | GPT-4, Claude | Alle modellen |
**Voor deze cursus:** Free tier is voldoende!
| Tool | Sterk in | Minder sterk in | Kosten |
|------|----------|-----------------|--------|
| **ChatGPT** | Brainstormen, uitleg, planning, algemene kennis | Grote codebases, lange context | Gratis / Pro €20/maand |
| **Claude** | Lange documenten, nuance, analyse, veiligheid | Soms te voorzichtig, geen images genereren | Gratis / Pro $20/maand |
| **v0.dev** | UI components, snel prototypen, Tailwind | Complexe logica, backend | Gratis tier |
| **OpenCode** | Code schrijven, project context, terminal | Geen web access, geen images | Gratis |
---
### Installatie
### Tool Selection Framework
1. Ga naar [cursor.sh](https://cursor.sh)
2. Download voor jouw OS
3. Installeer
4. Open Cursor
5. Sign in met GitHub
**Stap 1: Identificeer de taak**
- Wat wil je bereiken?
- Hoe complex is het?
- Hoeveel context is nodig?
**Eerste keer:**
- Cursor vraagt om settings te importeren van VS Code (optioneel)
- Accept default keybindings
**Stap 2: Kies de juiste tool**
---
### Core Features
#### 1. Tab Completion
AI-powered autocomplete die hele blokken code voorspelt.
**Hoe het werkt:**
- Begin met typen
- Cursor suggereert code in grijs
- Druk Tab om te accepteren
- Druk Escape om te negeren
**Tip:** Schrijf een comment over wat je wilt, en Tab completion vult de code in.
```typescript
// Function that calculates the total price with tax
// [Tab completion vult de functie in]
```
Als je wilt... Gebruik...
─────────────────────────────────────────────────
Brainstormen over een idee → ChatGPT
Een lange codebase analyseren → Claude
Snel een UI component maken → v0.dev
Code schrijven met project context → OpenCode
Een complex document begrijpen → Claude
Uitleg krijgen over een concept → ChatGPT
React component met styling → v0.dev
Feature implementeren in project → OpenCode
```
#### 2. CMD+K (Inline Editing)
Selecteer code en vraag AI om het aan te passen.
---
**Hoe het werkt:**
1. Selecteer code (of zet cursor op een regel)
2. Druk CMD+K (Mac) of Ctrl+K (Windows)
3. Typ je instructie
4. Enter om te genereren
5. Accept of Reject de wijziging
### Workflow Patterns
**Voorbeelden:**
- "Add error handling"
- "Convert to TypeScript"
- "Make this responsive"
- "Add loading state"
#### 3. Chat (Sidebar)
Converseer met AI over je code.
**Hoe het werkt:**
1. CMD+Shift+L opent Chat
2. Stel je vraag
3. AI heeft context van je open file
**Voorbeelden:**
- "Explain what this function does"
- "How can I optimize this?"
- "What's wrong with this code?"
#### 4. @ Mentions
Refereer naar files, folders, of documentatie.
**Syntax:**
- `@filename.tsx` - specifieke file
- `@folder/` - hele folder
- `@Docs` - officiële docs zoeken
- `@Web` - web zoeken
**Voorbeeld:**
**Pattern 1: Planning → Prototyping → Implementation**
```
@components/Button.tsx - How can I add a loading prop to this?
1. ChatGPT: Brainstorm features, maak planning
2. v0.dev: Genereer UI prototypes
3. OpenCode: Implementeer met project context
```
#### 5. Composer Mode
Multi-file generatie in één keer.
**Pattern 2: Research → Design → Build**
```
1. ChatGPT/Claude: Research beste aanpak
2. v0.dev: Design components
3. OpenCode: Bouw en integreer
```
**Hoe het werkt:**
1. CMD+I opent Composer
2. Beschrijf wat je wilt bouwen
3. AI genereert meerdere files tegelijk
4. Review en accept changes
**Wanneer gebruiken:**
- Nieuwe features met meerdere components
- Refactoring over meerdere files
- Boilerplate code genereren
**Pattern 3: Quick Iteration**
```
1. v0.dev: Snel component genereren
2. OpenCode: Aanpassen en integreren
3. Repeat
```
---
### Workflow Vergelijking
### Praktijk: Dezelfde Taak, Drie Tools
| Taak | OpenCode | Cursor |
|------|----------|--------|
| Snelle fix | Chat | CMD+K |
| Nieuwe component | Chat | Tab completion + CMD+K |
| Multi-file feature | Meerdere chats | Composer |
| Code uitleg | Chat | Chat + @ mentions |
| Refactoring | Chat | CMD+K of Composer |
**Opdracht:** Bouw een Contact Form component
**Met ChatGPT:**
```
Prompt: Ik wil een contact form maken met React en Tailwind.
Velden: naam, email, bericht. Validatie nodig.
Geef me de code en leg uit hoe het werkt.
```
→ Krijg: Uitleg + code, maar zonder project context
**Met v0.dev:**
```
Prompt: Modern contact form with name, email, message fields.
Tailwind styling, validation, responsive design.
```
→ Krijg: Visueel prototype, direct te gebruiken
**Met OpenCode:**
```
Prompt: Maak een ContactForm component in src/components/
met naam, email en bericht velden. Gebruik onze bestaande
Input en Button components. Voeg Zod validatie toe.
```
→ Krijg: Geïntegreerde code die past in je project
---
### Tips voor Beginners
### Wanneer Combineer Je Tools?
1. **Start met Tab completion**
- Gewoon typen en kijken wat er gebeurt
- Comments zijn je vriend
**Scenario 1: Nieuwe feature bouwen**
1. ChatGPT: "Hoe zou je een dark mode toggle implementeren in React?"
2. v0.dev: "Dark mode toggle component with smooth transition"
3. OpenCode: "Integreer deze toggle in onze navbar, sla preference op in localStorage"
2. **CMD+K voor snelle edits**
- Selecteer precies wat je wilt aanpassen
- Wees specifiek in je instructie
**Scenario 2: Bug oplossen**
1. OpenCode: Vraag om bug te identificeren
2. Claude: Als de foutmelding complex is, vraag om uitleg
3. OpenCode: Implementeer de fix
3. **Chat voor vragen**
- Als je iets niet begrijpt
- Als je opties wilt vergelijken
4. **@ mentions voor context**
- AI weet niet automatisch over andere files
- Voeg relevante files toe met @
**Scenario 3: Nieuwe technologie leren**
1. ChatGPT: "Leg uit hoe React Server Components werken"
2. v0.dev: "Example of React Server Component with data fetching"
3. OpenCode: "Help me dit toe te passen in mijn Next.js project"
---
### Keyboard Shortcuts Cheat Sheet
### Anti-Patterns (Wat Niet Te Doen)
| Actie | Mac | Windows |
|-------|-----|---------|
| Tab completion accept | Tab | Tab |
| Inline edit | CMD+K | Ctrl+K |
| Open Chat | CMD+Shift+L | Ctrl+Shift+L |
| Open Composer | CMD+I | Ctrl+I |
| Accept suggestion | CMD+Y | Ctrl+Y |
| Reject suggestion | CMD+N | Ctrl+N |
**❌ Verkeerde tool voor de taak:**
- ChatGPT vragen om een hele app te bouwen → te weinig context
- v0.dev vragen om complexe backend logica → niet zijn sterke punt
- OpenCode vragen om design inspiratie → kan geen images maken
**❌ Heen en weer kopiëren zonder begrip:**
- Kopieer niet blind code van ChatGPT naar je project
- Begrijp eerst WAT de code doet
**❌ Dezelfde prompt in elke tool:**
- Pas je prompt aan per tool
- v0.dev wil visuele beschrijvingen
- OpenCode wil project-specifieke context
---
## Tools
- Cursor
- GitHub
- ChatGPT
- Claude
- v0.dev
- OpenCode/WebStorm
---
## Lesopdracht (2 uur)
### Cursor Verkennen
### Tool Comparison Challenge
**Deel 1: Setup (20 min)**
**Deel 1: Dezelfde Taak, Drie Tools (1 uur)**
1. Download en installeer Cursor
2. Sign in met GitHub
3. Open je Todo app project
4. Verken de interface
Bouw een "Contact Form" component met alle drie de tools:
**Deel 2: Tab Completion (30 min)**
1. **ChatGPT (20 min)**
- Vraag om code + uitleg
- Noteer: hoe lang duurde het, kwaliteit output, wat miste?
Maak nieuwe file `src/components/LoadingSpinner.tsx`:
1. Typ comment: `// Loading spinner component with size prop`
2. Laat Tab completion de rest doen
3. Itereer met meer comments
4. Noteer: hoe goed is de completion?
2. **v0.dev (20 min)**
- Genereer visueel prototype
- Noteer: hoe snel, hoe mooi, hoe aanpasbaar?
**Deel 3: CMD+K Oefenen (30 min)**
3. **OpenCode (20 min)**
- Integreer in bestaand project
- Noteer: hoe goed past het, hoeveel aanpassing nodig?
Open je TodoList component:
1. Selecteer de list rendering code
2. CMD+K → "Add loading state with skeleton"
3. Selecteer een button
4. CMD+K → "Add disabled state while loading"
5. Selecteer een function
6. CMD+K → "Add try-catch with error toast"
**Deel 2: Analyse (30 min)**
Noteer wat werkt en wat niet.
Vul dit schema in:
**Deel 4: Chat + @ Mentions (20 min)**
| Aspect | ChatGPT | v0.dev | OpenCode |
|--------|---------|--------|----------|
| Tijd tot werkend component | | | |
| Kwaliteit code | | | |
| Visueel design | | | |
| Past in project | | | |
| Hoeveel aanpassing nodig | | | |
| Totaalscore (1-10) | | | |
1. Open Chat (CMD+Shift+L)
2. Vraag: "@TodoList.tsx What could I improve in this component?"
3. Vraag: "@lib/supabase.ts How do I add real-time subscriptions?"
4. Probeer @Docs voor Next.js documentatie
**Deel 3: Workflow Documentatie (30 min)**
**Deel 5: Composer Proberen (20 min)**
1. Open Composer (CMD+I)
2. Vraag: "Create a Settings page with dark mode toggle and notification preferences. Use our existing component style."
3. Review de gegenereerde files
4. Accept of reject
- Maak `docs/WORKFLOW.md` in je project
- Documenteer je ideale workflow per taaktype
- Inclusief template prompts voor elke tool
### Deliverable
- Screenshot van werkende Tab completion
- 3 voorbeelden van CMD+K edits
- Notities: wat werkt wel/niet goed
- Screenshot van alle 3 contact forms
- Ingevuld vergelijkingsschema
- `docs/WORKFLOW.md` bestand
---
## Huiswerk (2 uur)
### Bouw Feature met Cursor
### Bouw Je Tool Selection Cheat Sheet
**Deel 1: Feature Bouwen (1.5 uur)**
**Deel 1: Cheat Sheet Maken (1 uur)**
Voeg "Due Dates" toe aan je Todo app:
1. Elk todo kan een due date hebben
2. Toon due date in de lijst
3. Sorteer op due date
4. Markeer overdue items in rood
Maak een persoonlijke "Tool Selection Cheat Sheet" (1 pagina):
**Gebruik ALLE Cursor features:**
- Tab completion voor nieuwe code
- CMD+K voor aanpassingen
- Chat voor vragen
- Composer voor multi-file changes
```markdown
# Mijn AI Tool Cheat Sheet
**Deel 2: Reflectie (30 min)**
## Wanneer gebruik ik wat?
Schrijf vergelijking (400 woorden):
- Cursor vs OpenCode: wat is beter?
- Welke feature gebruik je het meest?
- Is free tier voldoende?
- Ga je overstappen?
### ChatGPT
- ✅ Gebruik voor: [jouw ervaring]
- ❌ Niet voor: [jouw ervaring]
- 💡 Beste prompt tip: [jouw tip]
### Claude
- ✅ Gebruik voor: [jouw ervaring]
- ❌ Niet voor: [jouw ervaring]
- 💡 Beste prompt tip: [jouw tip]
### v0.dev
- ✅ Gebruik voor: [jouw ervaring]
- ❌ Niet voor: [jouw ervaring]
- 💡 Beste prompt tip: [jouw tip]
### OpenCode
- ✅ Gebruik voor: [jouw ervaring]
- ❌ Niet voor: [jouw ervaring]
- 💡 Beste prompt tip: [jouw tip]
```
**Deel 2: Testen op Nieuwe Taken (45 min)**
Test je cheat sheet op 2 nieuwe taken:
1. Bouw een "Testimonial Card" component
2. Voeg een "Dark Mode Toggle" toe
Per taak: kies tools op basis van cheat sheet, voer uit, update cheat sheet.
**Deel 3: Reflectie (15 min)**
Schrijf korte reflectie (400 woorden):
- Welke tool is jouw favoriet en waarom?
- Wanneer combineer je tools?
- Wat ga je anders doen na deze les?
### Deliverable
- Werkende Due Dates feature
- GitHub commit met de changes
- Tool Selection Cheat Sheet (1 pagina)
- 2 gebouwde components
- Reflectie (400 woorden)
---
## Leerdoelen
Na deze les kan de student:
- Cursor installeren en configureren
- Tab completion effectief gebruiken
- CMD+K gebruiken voor inline edits
- Chat gebruiken met @ mentions voor context
- Composer mode gebruiken voor multi-file generatie
- Het verschil beoordelen tussen Cursor en OpenCode
- De juiste Cursor feature kiezen per taak
- De sterke en zwakke punten van elke AI tool benoemen
- De juiste tool kiezen voor een specifieke taak
- Meerdere tools combineren in een effectieve workflow
- Een persoonlijke workflow documenteren
- Template prompts schrijven per tool
- Kritisch evalueren welke tool wanneer het beste werkt

View File

@@ -1,448 +1,237 @@
# Les 11: Project Setup & Repository Structure
# Les 11: Hands-on: Van Idee naar Prototype
---
## Hoofdstuk
**Hoofdstuk 3: Advanced** (Les 10-18)
**Deel 3: AI Tooling & Prototyping** (Les 10-12)
## Beschrijving
Zet je eindproject professioneel op met de juiste structuur, documentatie, en AI-configuratie. Je past alles toe wat je hebt geleerd en maakt je project klaar voor Cursor.
Pas alles wat je hebt geleerd toe in een hands-on sessie. Ga van een vaag idee naar een werkend prototype met behulp van je AI workflow.
---
## Te Behandelen
### Waarom Goede Structuur Belangrijk Is
### Van Idee naar Feature Breakdown
**Voor AI:**
- AI begrijpt beter wat je project doet
- Betere code suggestions
- Minder hallucinaties
**Het probleem:** Je hebt een idee, maar waar begin je?
**Voor jezelf:**
- Makkelijker navigeren
- Sneller features bouwen
- Betere samenwerking
**Stap 1: Beschrijf je idee in 1-2 zinnen**
```
"Ik wil een app waar je kunt bijhouden welke planten water nodig hebben."
```
**Stap 2: Vraag AI om feature breakdown**
```
Prompt: Ik wil een plant watering tracker app bouwen.
Wat zijn de minimale features voor een werkend prototype?
Denk aan: wat moet een gebruiker kunnen doen?
```
**Stap 3: Prioriteer (MVP denken)**
- Wat is essentieel? → In prototype
- Wat is nice-to-have? → Later
---
### Eindproject Aanmaken
### Component Thinking
```bash
# Kies een goede naam voor je project
npx create-next-app@latest ai-recipe-generator
# of: smart-budget-buddy
# of: travel-planner-ai
# of: jouw-eigen-idee
**Vraag jezelf af:**
- Welke "blokken" zie ik op het scherm?
- Welke blokken worden herhaald?
- Welke blokken komen op meerdere pagina's?
# Beantwoord de vragen:
# ✔ Would you like to use TypeScript? → Yes
# ✔ Would you like to use ESLint? → Yes
# ✔ Would you like to use Tailwind CSS? → Yes
# ✔ Would you like to use `src/` directory? → Yes
# ✔ Would you like to use App Router? → Yes
# ✔ Would you like to customize the default import alias? → No
**Voorbeeld: Plant Tracker**
```
Herhaalde componenten:
- PlantCard (naam, foto, laatste water datum)
- WaterButton (markeer als water gegeven)
cd ai-recipe-generator
Pagina componenten:
- PlantList (toont alle PlantCards)
- AddPlantForm (nieuw plant toevoegen)
```
---
### De Ideale Folder Structuur
### MVP (Minimum Viable Product) Denken
**Wat is MVP?**
De simpelste versie van je app die nog steeds waarde levert.
**❌ Niet MVP:**
- Alle features tegelijk
- Perfect design
- Edge cases afhandelen
- Login systeem
**✅ Wel MVP:**
- Core functionaliteit werkt
- Basis styling
- Happy path werkt
- Hardcoded data is oké
---
### De Prototype Workflow
```
ai-recipe-generator/
├── .cursor/
│ └── rules/
└── general.mdc # Cursor instructies
├── docs/
├── PROJECT-BRIEF.md # Project beschrijving
│ ├── PROMPT-LOG.md # AI prompts logboek
│ └── AI-DECISIONS.md # Architectuur beslissingen
├── src/
├── app/
│ │ ├── api/ # API routes (voor AI)
│ │ ├── layout.tsx
│ │ └── page.tsx
│ ├── components/
│ │ ├── ui/ # Herbruikbare UI components
│ │ └── features/ # Feature-specifieke components
│ ├── lib/
│ │ └── supabase.ts # Supabase client
│ └── types/
│ └── index.ts # TypeScript types
├── .env.example # Template voor env vars
├── .env.local # Echte env vars (niet committen!)
├── .gitignore
└── README.md
```
**Maak de folders aan:**
```bash
mkdir -p .cursor/rules
mkdir -p docs
mkdir -p src/components/ui
mkdir -p src/components/features
mkdir -p src/lib
mkdir -p src/types
1. IDEE (1-2 zinnen)
2. FEATURES (AI breakdown)
3. PRIORITEER (wat is MVP?)
4. COMPONENTS (welke blokken?)
5. BOUWEN (tool per stap)
6. ITEREREN (feedback → aanpassen)
```
---
### .cursorrules Files
### Voorbeeld: Weer Widget Prototype
**.cursor/rules/general.mdc:**
```markdown
# Project: AI Recipe Generator
**Stap 1: Idee**
"Simpele weer widget met 3-daagse forecast"
## Tech Stack
- Next.js 14 met App Router
- TypeScript (strict mode)
- Tailwind CSS voor styling
- Supabase voor database en auth
- Vercel AI SDK voor chat features
## Code Conventies
- Gebruik functionele React components
- Gebruik named exports (geen default exports)
- Destructure props in function signature
- Gebruik async/await (geen .then() chains)
- Schrijf TypeScript types voor alle props en data
## File Naming
- Components: PascalCase (Button.tsx, RecipeCard.tsx)
- Utilities: camelCase (formatDate.ts, fetchRecipes.ts)
- Types: PascalCase met 'Type' suffix (RecipeType.ts)
## Styling
- Alleen Tailwind classes, geen inline styles
- Mobile-first approach
- Gebruik consistent spacing (4, 8, 16, 24, 32)
## Supabase
- Client in src/lib/supabase.ts
- Gebruik typed queries waar mogelijk
- Handle errors expliciet
## AI Features
- API routes in src/app/api/
- Gebruik Vercel AI SDK useChat hook
- Stream responses voor betere UX
**Stap 2: AI Feature Breakdown**
```
Vraag aan ChatGPT:
"Wat zijn de minimale features voor een weer widget met 3-daagse forecast?"
Antwoord:
- Huidige temperatuur tonen
- Weer icoon (zon, regen, etc.)
- 3-daagse forecast (dag + temp + icoon)
- Locatie tonen
```
**Stap 3: MVP Selectie**
- ✅ Huidige temperatuur
- ✅ Weer icoon
- ✅ 3 dagen forecast
- ❌ Locatie selectie (later)
- ❌ Animated icons (later)
**Stap 4: Components**
```
WeatherWidget/
├── CurrentWeather (temp + icoon)
├── ForecastDay (dag + temp + icoon)
└── ForecastList (3x ForecastDay)
```
**Stap 5: Bouwen**
1. v0.dev: "Weather widget with current temp and 3 day forecast, minimal design"
2. OpenCode: "Integreer dit in mijn project, maak components in src/components/weather/"
**Stap 6: Itereren**
- Wat werkt niet?
- Wat kan beter?
- Vraag AI om verbeteringen
---
### docs/ Folder
### Mini-Project Ideeën
#### docs/PROJECT-BRIEF.md
```markdown
# Project Brief: AI Recipe Generator
## Projectnaam
AI Recipe Generator
## Tagline
"Ontdek recepten op basis van wat je in huis hebt"
## Probleem
Mensen hebben vaak ingrediënten in huis maar weten niet wat ze
ermee kunnen maken. Ze verspillen voedsel of bestellen onnodig.
## Oplossing
Een app waar je ingrediënten invoert en AI receptsuggesties genereert.
Je kunt chatten met de AI voor variaties en tips.
## Doelgroep
- Studenten met beperkt budget
- Thuiskoks die inspiratie zoeken
- Mensen die voedselverspilling willen verminderen
## Core Features
1. Ingrediënten invoeren
2. AI genereert recepten op basis van ingrediënten
3. Chat interface voor follow-up vragen
4. Recepten opslaan als favoriet
5. Login om favorieten te bewaren
## Nice-to-have Features
- Dieetwensen (vegetarisch, glutenvrij, etc.)
- Boodschappenlijst genereren
- Recept delen
## Tech Stack
- Frontend: Next.js, TypeScript, Tailwind CSS
- Backend: Supabase (database, auth)
- AI: Vercel AI SDK met OpenAI
- Deployment: Vercel
```
#### docs/PROMPT-LOG.md
```markdown
# Prompt Log
Dit document bevat de belangrijkste prompts die ik heb gebruikt.
## Template per prompt:
### [Datum] - [Onderwerp]
**Doel:** Wat wilde ik bereiken?
**Prompt:**
\`\`\`
De exacte prompt die ik gebruikte
\`\`\`
**Resultaat:** Wat was het resultaat? Werkte het?
**Geleerd:** Wat heb ik hiervan geleerd?
---
## Prompts
### [Datum] - Project Setup
**Doel:** Basis project structuur opzetten
**Prompt:**
\`\`\`
[Nog in te vullen tijdens development]
\`\`\`
**Resultaat:**
**Geleerd:**
---
(Voeg minimaal 10 prompts toe tijdens je project)
```
#### docs/AI-DECISIONS.md
```markdown
# AI Decisions Log
Dit document bevat architectuur- en designbeslissingen gemaakt met AI hulp.
## Template per beslissing:
### [Datum] - [Beslissing titel]
**Context:** Wat was de situatie?
**Vraag aan AI:** Wat heb ik gevraagd?
**Opties:** Welke opties werden voorgesteld?
**Keuze:** Wat heb ik gekozen en waarom?
**Trade-offs:** Wat zijn de voor- en nadelen?
---
## Beslissingen
### [Datum] - Database Schema
**Context:** Ik moet bepalen hoe ik recepten opsla.
**Vraag aan AI:** "Wat is een goede database structuur voor een recept app?"
**Opties:**
1. Één tabel met JSON voor ingrediënten
2. Genormaliseerde tabellen (recipes, ingredients, recipe_ingredients)
**Keuze:** Optie 1 - één tabel met JSON
**Trade-offs:**
- Pro: Simpeler, sneller te implementeren
- Con: Minder flexibel voor complexe queries
---
(Voeg minimaal 5 beslissingen toe tijdens je project)
```
---
### Environment Variables
**.env.example (WEL committen):**
```bash
# Supabase
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
# OpenAI (voor Vercel AI SDK)
OPENAI_API_KEY=your-openai-key
```
**.env.local (NIET committen):**
```bash
# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://xxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx
# OpenAI
OPENAI_API_KEY=sk-xxxxx
```
---
### README.md Best Practices
```markdown
# AI Recipe Generator
Ontdek recepten op basis van wat je in huis hebt.
## Features
- Voer ingrediënten in die je hebt
- AI genereert receptsuggesties
- Chat voor follow-up vragen
- Sla favoriete recepten op
## Tech Stack
- Next.js 14 (App Router)
- TypeScript
- Tailwind CSS
- Supabase
- Vercel AI SDK
## Getting Started
### Prerequisites
- Node.js 18+
- npm of yarn
- Supabase account
- OpenAI API key
### Installation
1. Clone de repository:
\`\`\`bash
git clone https://github.com/jouw-username/ai-recipe-generator.git
cd ai-recipe-generator
\`\`\`
2. Installeer dependencies:
\`\`\`bash
npm install
\`\`\`
3. Kopieer environment variables:
\`\`\`bash
cp .env.example .env.local
\`\`\`
4. Vul je credentials in `.env.local`
5. Start development server:
\`\`\`bash
npm run dev
\`\`\`
6. Open [http://localhost:3000](http://localhost:3000)
## Scripts
- `npm run dev` - Start development server
- `npm run build` - Build voor productie
- `npm run lint` - Run ESLint
## Deployment
Deze app is gedeployed op Vercel: [link naar productie]
## Author
[Jouw naam]
```
---
### GitHub Repository Aanmaken
```bash
# Initialiseer Git (als dat nog niet is gebeurd)
git init
# Maak eerste commit
git add .
git commit -m "Initial Next.js setup with project structure"
# Maak repository op GitHub.com, dan:
git remote add origin https://github.com/jouw-username/ai-recipe-generator.git
git branch -M main
git push -u origin main
```
| Project | Core Feature | Complexiteit |
|---------|-------------|--------------|
| **Weer Widget** | 3-daagse forecast | ⭐ |
| **Quiz App** | 3 vragen + score | ⭐ |
| **Recipe Card** | Ingrediënten toggle | ⭐ |
| **Pomodoro Timer** | Start/stop + countdown | ⭐⭐ |
| **Expense Tracker** | Lijst + totaal | ⭐⭐ |
---
## Tools
- Next.js
- Cursor
- Git & GitHub
- Supabase
- ChatGPT (voor planning)
- v0.dev (voor prototypes)
- OpenCode/WebStorm (voor implementation)
---
## Lesopdracht (2 uur)
### Richt je Eindproject Repository In
### Bouw Je Mini-Prototype
**Deel 1: Project Aanmaken (20 min)**
- Kies je eindproject (Recipe Generator / Budget Buddy / Travel Planner / eigen idee)
- Run `npx create-next-app@latest [project-naam]`
- Open in Cursor
**Groepsdiscussie (15 min):**
Bespreek klassikaal de Tool Selection reflecties uit Les 10 - welke workflows werken het beste?
**Deel 2: Folder Structuur (20 min)**
- Maak alle folders aan volgens de structuur
- Maak alle bestanden aan
- Test: folder structuur is compleet
**Deel 1: Planning (30 min)**
**Deel 3: .cursorrules (30 min)**
- Schrijf `general.mdc` met jouw project details
- Pas de tech stack, conventies, en styling regels aan
- Test: open een file en vraag Cursor iets - volgt hij je regels?
1. Kies een project uit de lijst (of bedenk eigen simpel idee)
2. Schrijf je idee in 1-2 zinnen
3. Vraag ChatGPT om feature breakdown
4. Selecteer MVP features (max 3)
5. Schets de components op papier
**Deel 4: Documentatie (30 min)**
- Vul PROJECT-BRIEF.md volledig in
- Maak templates klaar in PROMPT-LOG.md en AI-DECISIONS.md
- Schrijf complete README.md
**Deel 2: Bouwen (1 uur)**
**Deel 5: Git (20 min)**
- Initialiseer Git
- Maak GitHub repository
- Push alles
1. Genereer UI in v0.dev
2. Open project in OpenCode
3. Integreer en pas aan
4. Zorg dat het werkt (happy path)
**Focus op WORKFLOW, niet perfectie!**
**Deel 3: Documentatie (15 min)**
Maak `docs/PROTOTYPE-LOG.md`:
- Je idee
- Feature breakdown
- MVP keuzes
- Prompts die werkten
- Wat ging fout en hoe opgelost
### Deliverable
- GitHub repository URL
- Volledig ingevulde PROJECT-BRIEF.md
- Werkende .cursorrules file
- Screenshot van Cursor die je regels volgt
- Werkend prototype (kan simpel zijn)
- `docs/PROTOTYPE-LOG.md` met je proces
- Screenshot van werkend prototype
---
## Huiswerk (2 uur)
### Verfijn Setup & Start Bouwen
### Verbeter en Reflecteer
**Deel 1: Extra .cursorrules (30 min)**
- Maak `components.mdc` met component conventies
- Maak `api.mdc` met API route conventies
- Test beide in Cursor
**Deel 1: Prototype Verbeteren (1 uur)**
**Deel 2: Basis Components (1 uur)**
Maak 3-5 basis UI components in `src/components/ui/`:
- Button.tsx
- Card.tsx
- Input.tsx
- (optioneel: Modal.tsx, Toast.tsx)
1. Fix eventuele bugs
2. Voeg 1 extra feature toe
3. Verbeter styling
4. Handle 1 edge case
Gebruik Cursor met je .cursorrules!
Log effectieve prompts in PROMPT-LOG.md
**Deel 2: Peer Review (30 min)**
**Deel 3: Supabase Setup (30 min)**
- Maak nieuw Supabase project voor eindopdracht
- Configureer `.env.local` en `.env.example`
- Bespreek met AI welke tabellen je nodig hebt
- Maak eerste tabel aan
- Documenteer in AI-DECISIONS.md
- Deel je prototype met een klasgenoot
- Krijg feedback
- Geef feedback op hun prototype
**Deel 3: Reflectie (30 min)**
Schrijf "Lessons Learned" document (300 woorden):
- Wat ging goed in je workflow?
- Waar liep je vast?
- Welke tool was het meest nuttig?
- Wat doe je volgende keer anders?
- Hoe voelde het om met AI te bouwen vs alleen?
### Deliverable
- Minimaal 2 .cursorrules files
- Minimaal 3 UI components
- Supabase project gekoppeld
- Eerste entries in PROMPT-LOG.md en AI-DECISIONS.md
- Verbeterd prototype
- Peer review feedback (gegeven en ontvangen)
- Lessons Learned document (300 woorden)
---
## Leerdoelen
Na deze les kan de student:
- Een professionele project structuur opzetten
- .cursorrules files schrijven die Cursor instrueren
- Documentatie files aanmaken (PROJECT-BRIEF, PROMPT-LOG, AI-DECISIONS)
- Environment variables correct beheren
- Een GitHub repository aanmaken en pushen
- De basis leggen voor AI-assisted development met goede context
- Van een vaag idee naar concrete features gaan
- AI gebruiken voor feature breakdown
- MVP denken toepassen (essentieel vs nice-to-have)
- Een app opdelen in components
- De complete workflow doorlopen (idee → prototype)
- Het bouwproces documenteren
- Reflecteren op wat werkt en wat niet

View File

@@ -1,363 +1,261 @@
# Les 12: MCP & Context Management
# Les 12: Introduction to Cursor
---
## Hoofdstuk
**Hoofdstuk 3: Advanced** (Les 10-18)
**Deel 3: AI Tooling & Prototyping** (Les 10-12)
## Beschrijving
Leer over MCP (Model Context Protocol) en hoe je context effectief beheert voor betere AI-assisted development.
Kennismaking met Cursor - de professionele AI code editor. Leer de core features en ontdek waarom dit de tool is voor serieuze AI-assisted development.
---
## Te Behandelen
### Wat is MCP?
### Groepsdiscussie (15 min)
Bespreek klassikaal de prototype ervaringen uit Les 11 - welke workflow patterns werkten goed? Wat ging fout en hoe loste je dat op?
**MCP = Model Context Protocol**
### Waarom Cursor?
Een protocol van Anthropic waarmee AI tools veilig kunnen verbinden met externe data bronnen.
**Tot nu toe gebruikten we:**
- OpenCode (gratis, goed voor leren)
- Claude Desktop (voor agents en projects)
**Zonder MCP:**
- Je kopieert handmatig data naar Claude
- Context gaat verloren tussen sessies
- Geen toegang tot live data
**Met MCP:**
- Claude kan direct je files lezen
- Toegang tot databases, APIs, GitHub
- Real-time data in je conversations
**Cursor is de volgende stap:**
- Purpose-built voor AI-assisted coding
- Professionele editor (gebaseerd op VS Code)
- Superieure AI integratie
- Free tier beschikbaar (voldoende voor de cursus)
---
### MCP Servers
### Free vs Pro
MCP werkt met "servers" - kleine programma's die specifieke data bronnen ontsluiten.
| Aspect | Free Tier | Pro ($20/maand) |
|--------|-----------|-----------------|
| Tab completion | ✅ | ✅ |
| CMD+K edits | Beperkt | Onbeperkt |
| Chat | Beperkt | Onbeperkt |
| Composer | Beperkt | Onbeperkt |
| Models | GPT-4, Claude | Alle modellen |
**Populaire MCP Servers:**
| Server | Wat het doet |
|--------|--------------|
| **filesystem** | Lees/schrijf lokale files |
| **github** | Toegang tot repos, issues, PRs |
| **postgres** | Direct database queries |
| **slack** | Berichten en channels |
| **brave-search** | Web zoeken |
**Voor deze cursus:** Free tier is voldoende!
---
### Claude Desktop + MCP Configureren
### Installatie
**Stap 1:** Open Claude Desktop settings
1. Ga naar [cursor.sh](https://cursor.sh)
2. Download voor jouw OS
3. Installeer
4. Open Cursor
5. Sign in met GitHub
**Stap 2:** Ga naar "Developer" → "Edit Config"
**Stap 3:** Voeg MCP servers toe in `claude_desktop_config.json`:
```json
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/jouw-username/projects/ai-recipe-generator"
]
}
}
}
```
**Stap 4:** Herstart Claude Desktop
**Stap 5:** Je ziet nu een 🔧 icoon in Claude - dit toont actieve MCP servers
**Eerste keer:**
- Cursor vraagt om settings te importeren van VS Code (optioneel)
- Accept default keybindings
---
### Filesystem MCP Testen
### Core Features
Met filesystem MCP kan Claude:
- Je project files lezen
- File structuur bekijken
- Code analyseren
#### 1. Tab Completion
AI-powered autocomplete die hele blokken code voorspelt.
**Test prompt:**
```
Analyseer mijn project structuur en geef me een overzicht
van de belangrijkste files en hun functies.
**Hoe het werkt:**
- Begin met typen
- Cursor suggereert code in grijs
- Druk Tab om te accepteren
- Druk Escape om te negeren
**Tip:** Schrijf een comment over wat je wilt, en Tab completion vult de code in.
```typescript
// Function that calculates the total price with tax
// [Tab completion vult de functie in]
```
Claude kan nu direct je files lezen zonder dat je ze kopieert!
#### 2. CMD+K (Inline Editing)
Selecteer code en vraag AI om het aan te passen.
**Hoe het werkt:**
1. Selecteer code (of zet cursor op een regel)
2. Druk CMD+K (Mac) of Ctrl+K (Windows)
3. Typ je instructie
4. Enter om te genereren
5. Accept of Reject de wijziging
**Voorbeelden:**
- "Add error handling"
- "Convert to TypeScript"
- "Make this responsive"
- "Add loading state"
#### 3. Chat (Sidebar)
Converseer met AI over je code.
**Hoe het werkt:**
1. CMD+Shift+L opent Chat
2. Stel je vraag
3. AI heeft context van je open file
**Voorbeelden:**
- "Explain what this function does"
- "How can I optimize this?"
- "What's wrong with this code?"
#### 4. @ Mentions
Refereer naar files, folders, of documentatie.
**Syntax:**
- `@filename.tsx` - specifieke file
- `@folder/` - hele folder
- `@Docs` - officiële docs zoeken
- `@Web` - web zoeken
**Voorbeeld:**
```
@components/Button.tsx - How can I add a loading prop to this?
```
#### 5. Composer Mode
Multi-file generatie in één keer.
**Hoe het werkt:**
1. CMD+I opent Composer
2. Beschrijf wat je wilt bouwen
3. AI genereert meerdere files tegelijk
4. Review en accept changes
**Wanneer gebruiken:**
- Nieuwe features met meerdere components
- Refactoring over meerdere files
- Boilerplate code genereren
---
### GitHub MCP
### Workflow Vergelijking
```json
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxxxx"
}
}
}
}
```
**Wat kun je doen:**
- "Toon mijn open issues"
- "Maak een nieuwe branch"
- "Wat zijn de recente commits?"
| Taak | OpenCode | Cursor |
|------|----------|--------|
| Snelle fix | Chat | CMD+K |
| Nieuwe component | Chat | Tab completion + CMD+K |
| Multi-file feature | Meerdere chats | Composer |
| Code uitleg | Chat | Chat + @ mentions |
| Refactoring | Chat | CMD+K of Composer |
---
## Context Management
### Keyboard Shortcuts Cheat Sheet
### Wat is Context?
**Context = alle informatie die AI heeft tijdens een conversatie**
- Je vraag
- Eerdere berichten
- Geüploade files
- MCP data
**Beperking:** AI heeft een "context window" - maximale hoeveelheid tokens.
| Model | Context Window |
|-------|----------------|
| GPT-4 | ~128K tokens |
| Claude 3.5 | ~200K tokens |
| Claude 3 Opus | ~200K tokens |
**1 token ≈ 4 karakters** (of ~¾ woord)
---
### Waarom Context Belangrijk Is
**Meer context = beter begrip**
Met context over je project kan AI:
- Consistente code genereren
- Bestaande patterns volgen
- Juiste imports gebruiken
**Te veel context = problemen**
- Langzamere responses
- Hogere kosten
- AI raakt "afgeleid"
---
### Context Strategieën
**1. Start Breed, Narrow Down**
```
Begin: "Bekijk mijn hele project structuur"
Dan: "Focus op de components folder"
Dan: "Specifiek TodoList.tsx"
```
**2. Alleen Relevante Files**
- Niet je hele codebase delen
- Focus op files die relevant zijn voor de taak
**3. @ Mentions in Cursor**
```
@components/Button.tsx @lib/utils.ts
Hoe kan ik een loading state toevoegen aan de Button?
```
**4. Fresh Start bij Nieuwe Taken**
- Nieuwe chat voor nieuwe onderwerpen
- Voorkomt context pollution
---
### .cursorignore
Net als .gitignore, maar voor Cursor's AI indexing.
**Maak `.cursorignore` in je project root:**
```
# Dependencies
node_modules/
# Build outputs
.next/
dist/
build/
# Large files
*.log
*.lock
# Sensitive
.env.local
```
**Waarom:**
- Snellere indexing
- Geen irrelevante suggestions
- Betere focus op je code
---
### Context Optimalisatie Checklist
**Goede project documentatie**
- README met overview
- Duidelijke folder structuur
- Comments in complexe code
**Semantische naming**
- `fetchUserData()` niet `getData()`
- `UserProfileCard.tsx` niet `Card1.tsx`
**Kleine, focused files**
- Max ~300 regels per file
- Eén verantwoordelijkheid per file
**Proper imports**
- Absolute imports (`@/components/...`)
- Georganiseerde imports
---
### Context in Cursor vs Claude Desktop
| Aspect | Cursor | Claude Desktop + MCP |
|--------|--------|---------------------|
| Automatische context | Open files | MCP servers |
| File access | @ mentions | Filesystem MCP |
| Project begrip | .cursorrules | Project Knowledge |
| Beste voor | Coding | Research, planning |
**Combineer ze:**
- Claude Desktop + MCP voor planning en grote analyses
- Cursor voor daadwerkelijk coderen
| Actie | Mac | Windows |
|-------|-----|---------|
| Tab completion accept | Tab | Tab |
| Inline edit | CMD+K | Ctrl+K |
| Open Chat | CMD+Shift+L | Ctrl+Shift+L |
| Open Composer | CMD+I | Ctrl+I |
| Accept suggestion | CMD+Y | Ctrl+Y |
| Reject suggestion | CMD+N | Ctrl+N |
---
## Tools
- Claude Desktop
- MCP servers
- Cursor
- .cursorignore
- GitHub
---
## Lesopdracht (2 uur)
### MCP Setup & Context Optimalisatie
### Cursor Verkennen
**Deel 1: Claude Desktop MCP Setup (45 min)**
**Deel 1: Setup (20 min)**
1. Open Claude Desktop settings
2. Configureer filesystem MCP voor je eindproject folder
3. Herstart Claude Desktop
4. Verifieer: vraag Claude om je project te analyseren
1. Download en installeer Cursor
2. Sign in met GitHub
3. Open je Todo app project
4. Verken de interface
Test prompts:
- "Wat is de structuur van mijn project?"
- "Welke dependencies gebruik ik?"
- "Analyseer mijn TodoList component"
**Deel 2: Tab Completion (30 min)**
**Deel 2: GitHub MCP (optioneel) (30 min)**
Maak nieuwe file `src/components/LoadingSpinner.tsx`:
1. Typ comment: `// Loading spinner component with size prop`
2. Laat Tab completion de rest doen
3. Itereer met meer comments
4. Noteer: hoe goed is de completion?
1. Maak GitHub Personal Access Token
2. Configureer GitHub MCP
3. Test met je eindproject repo
**Deel 3: CMD+K Oefenen (30 min)**
Test prompts:
- "Toon mijn recente commits"
- "Wat zijn mijn open issues?"
Open je TodoList component:
1. Selecteer de list rendering code
2. CMD+K → "Add loading state with skeleton"
3. Selecteer een button
4. CMD+K → "Add disabled state while loading"
5. Selecteer een function
6. CMD+K → "Add try-catch with error toast"
**Deel 3: Context Optimalisatie (45 min)**
Noteer wat werkt en wat niet.
1. Maak `.cursorignore` voor je project
2. Voeg node_modules, .next, etc. toe
3. Herindexeer project in Cursor
**Deel 4: Chat + @ Mentions (20 min)**
4. Test context kwaliteit:
- Vraag Cursor iets over je project
- Zijn de antwoorden accuraat?
- Gebruikt hij de juiste patterns?
1. Open Chat (CMD+Shift+L)
2. Vraag: "@TodoList.tsx What could I improve in this component?"
3. Vraag: "@lib/supabase.ts How do I add real-time subscriptions?"
4. Probeer @Docs voor Next.js documentatie
5. Verbeter indien nodig:
- Voeg comments toe aan complexe code
- Verbeter naming
- Split grote files
**Deel 5: Composer Proberen (20 min)**
1. Open Composer (CMD+I)
2. Vraag: "Create a Settings page with dark mode toggle and notification preferences. Use our existing component style."
3. Review de gegenereerde files
4. Accept of reject
### Deliverable
- Werkende MCP configuratie (screenshot)
- .cursorignore file
- Notities over context kwaliteit
- Screenshot van werkende Tab completion
- 3 voorbeelden van CMD+K edits
- Notities: wat werkt wel/niet goed
---
## Huiswerk (2 uur)
### Context Deep Dive
### Bouw Feature met Cursor
**Deel 1: MCP Experimenteren (1 uur)**
**Deel 1: Feature Bouwen (1.5 uur)**
Kies en configureer nog een MCP server:
- brave-search (voor web zoeken)
- sqlite (voor lokale databases)
- Of een andere uit de [MCP registry](https://github.com/modelcontextprotocol/servers)
Voeg "Due Dates" toe aan je Todo app:
1. Elk todo kan een due date hebben
2. Toon due date in de lijst
3. Sorteer op due date
4. Markeer overdue items in rood
Test uitgebreid:
- Wat kun je ermee?
- Wanneer is het nuttig?
- Wat zijn beperkingen?
**Gebruik ALLE Cursor features:**
- Tab completion voor nieuwe code
- CMD+K voor aanpassingen
- Chat voor vragen
- Composer voor multi-file changes
**Deel 2: Context Playbook (1 uur)**
**Deel 2: Reflectie (30 min)**
Schrijf een persoonlijk "Context Management Playbook" (1 pagina):
```markdown
# Mijn Context Management Playbook
## Wanneer gebruik ik wat?
### Claude Desktop + MCP
- [situaties]
### Cursor met @ mentions
- [situaties]
## Mijn .cursorignore template
- [wat ignore ik altijd]
## Context strategieën
- [wat werkt voor mij]
## Red flags
- [wanneer is context slecht]
## Optimalisatie tips
- [mijn beste tips]
```
Schrijf vergelijking (400 woorden):
- Cursor vs OpenCode: wat is beter?
- Welke feature gebruik je het meest?
- Is free tier voldoende?
- Ga je overstappen?
### Deliverable
- Extra MCP server geconfigureerd
- Context Management Playbook (1 pagina)
- Documentatie in AI-DECISIONS.md over je context keuzes
- Werkende Due Dates feature
- GitHub commit met de changes
- Reflectie (400 woorden)
---
## Leerdoelen
Na deze les kan de student:
- MCP begrijpen en uitleggen
- MCP servers configureren in Claude Desktop
- Filesystem en GitHub MCP gebruiken
- Context windows en token limits begrijpen
- .cursorignore effectief gebruiken
- Context strategieën toepassen
- De juiste tool kiezen voor context management
- Cursor installeren en configureren
- Tab completion effectief gebruiken
- CMD+K gebruiken voor inline edits
- Chat gebruiken met @ mentions voor context
- Composer mode gebruiken voor multi-file generatie
- Het verschil beoordelen tussen Cursor en OpenCode
- De juiste Cursor feature kiezen per taak

View File

@@ -1,284 +1,287 @@
# Les 13: Mastering Cursor
# Les 13: AI Agents & Custom GPTs
---
## Hoofdstuk
**Hoofdstuk 3: Advanced** (Les 10-18)
**Deel 4: Advanced AI Features** (Les 13-18)
## Beschrijving
Verdieping in Cursor's geavanceerde features. Leer model keuze, Composer Mode, @ mentions, en .cursorrules optimaal gebruiken.
Leer werken met AI agents en custom GPTs. Bouw je eigen gespecialiseerde AI assistenten en begrijp hoe agents autonome taken kunnen uitvoeren.
---
## Te Behandelen
### Model Keuze
### Groepsdiscussie (15 min)
Bespreek klassikaal de Cursor reflecties uit Les 12 - welke features werken het beste voor welke taken?
**Wanneer welk model?**
### Wat zijn AI Agents?
| Model | Gebruik voor | Kosten |
|-------|-------------|--------|
| **Haiku** | Simpele taken, autocomplete | Goedkoop |
| **Sonnet** | Dagelijks werk, de meeste taken | Medium |
| **Opus** | Complexe architectuur, multi-file | Duur |
**Definitie:** AI systemen die autonoom taken kunnen uitvoeren, niet alleen antwoorden geven.
**Vuistregels:**
- Tab completion: Haiku (automatisch)
- CMD+K: Sonnet (default)
- Composer: Sonnet of Opus
- Complexe debugging: Opus
**Verschil Chat vs Agent:**
| Aspect | Chat | Agent |
|--------|------|-------|
| Gedrag | Beantwoordt vragen | Voert taken uit |
| Autonomie | Wacht op input | Kan zelf beslissingen nemen |
| Tools | Alleen tekst | Kan tools gebruiken |
| Voorbeeld | "Hoe maak ik X?" | "Maak X voor mij" |
---
### Composer Mode Diepgaand
### Claude Projects
**Wat is Composer?**
Multi-file generatie in één keer. Cursor plant en voert wijzigingen uit over meerdere bestanden.
**Wat is een Claude Project?**
- Verzameling van context specifiek voor één doel
- Blijft behouden over conversaties
- Kan bestanden bevatten
**Wanneer Composer gebruiken:**
- Nieuwe feature met meerdere components
- Refactoring over meerdere files
- Boilerplate generatie
- Complexe wijzigingen
**Wanneer gebruiken:**
- Terugkerend werk aan hetzelfde project
- Consistente coding style nodig
- Documentatie die AI moet kennen
**Composer Workflow:**
1. CMD+I opent Composer
2. Beschrijf je doel duidelijk
3. Voeg context toe met @ mentions
4. Laat Cursor plannen
5. Review het plan
6. Accept of reject per file
7. Itereer met feedback
**Project aanmaken:**
1. Ga naar claude.ai → Projects
2. Klik "New Project"
3. Voeg project knowledge toe (files, instructies)
4. Start conversaties binnen het project
**Voorbeeld prompt:**
**Voorbeeld Project Instructions:**
```
Create a user profile page with:
- @components/ui/ style components
- Profile header with avatar
- Edit form with validation
- Save to @lib/supabase.ts
- Loading and error states
Je bent een expert React/Next.js developer.
Technologie stack:
- Next.js 14 met App Router
- TypeScript strict mode
- Tailwind CSS
- Supabase voor backend
Coding conventions:
- Functional components met TypeScript
- Named exports (geen default exports)
- Error handling met try/catch
- Nederlandse comments in code
```
---
### @ Mentions Systeem
### Custom GPTs
**Alle types:**
**Wat zijn Custom GPTs?**
Gespecialiseerde ChatGPT versies met:
- Specifieke instructies
- Eigen kennis (uploaded files)
- Optioneel: Actions (API calls)
| Mention | Wat het doet | Voorbeeld |
|---------|--------------|-----------|
| `@file.tsx` | Specifieke file | `@Button.tsx` |
| `@folder/` | Hele folder | `@components/` |
| `@codebase` | Zoek in codebase | `@codebase auth logic` |
| `@Docs` | Officiële docs | `@Docs Next.js routing` |
| `@Web` | Web zoeken | `@Web Supabase auth setup` |
**Wanneer een Custom GPT maken:**
- Repetitieve taken met dezelfde context
- Specifieke expertise nodig
- Delen met anderen
**Best practices:**
- Wees specifiek met file mentions
- Gebruik folder mentions voor context
- @Docs voor up-to-date informatie
- Combineer mentions voor betere context
---
### .cursorrules Advanced
**Meerdere rules files:**
**Custom GPT maken:**
1. Ga naar chat.openai.com/gpts
2. Klik "Create"
3. Configureer in "Create" tab OF gebruik "Configure"
**Voorbeeld: Code Review GPT**
```
.cursor/
└── rules/
├── general.mdc # Project-brede regels
├── components.mdc # Component conventies
├── api.mdc # API route regels
└── testing.mdc # Test conventies
```
Instructions:
Je bent een code reviewer gespecialiseerd in React/Next.js.
**Effectieve rules schrijven:**
Bij elke code review check je:
1. TypeScript best practices
2. React hooks correct gebruik
3. Performance (unnecessary re-renders)
4. Accessibility basics
5. Error handling
```markdown
# Component Rules
## Structure
Alle components moeten volgen:
1. Props interface bovenaan
2. Component function
3. Named export onderaan
## Example
\`\`\`tsx
interface ButtonProps {
label: string
onClick: () => void
variant?: 'primary' | 'secondary'
}
export function Button({ label, onClick, variant = 'primary' }: ButtonProps) {
return (
<button onClick={onClick} className={...}>
{label}
</button>
)
}
\`\`\`
## DON'Ts
- Geen default exports
- Geen inline styles
- Geen any types
Geef feedback in dit format:
- ✅ Goed: [wat goed is]
- ⚠️ Suggestie: [verbeterpunten]
- ❌ Issue: [problemen die gefixed moeten worden]
```
---
### Codebase Indexing
### Agent Capabilities
**Hoe Cursor indexeert:**
- Scant alle files in je project
- Bouwt semantic understanding
- Gebruikt voor autocomplete en context
**Wat kunnen agents:**
- Code schrijven en testen
- Files aanmaken en bewerken
- Terminal commands uitvoeren
- Web searches doen
- Meerdere stappen plannen
**Optimaliseren:**
1. Goede `.cursorignore` (node_modules, .next, etc.)
2. Semantische naming
3. Duidelijke file structuur
4. Comments waar nodig
**Cursor als Agent:**
- Composer mode plant en voert multi-file changes uit
- @ mentions geven context
- Tab completion voorspelt volgende stappen
**Re-indexeren:**
CMD+Shift+P → "Reindex"
**Claude als Agent (met MCP):**
- Kan tools gebruiken
- Filesystem access
- Database queries
- External APIs
---
### Cost Management
### Best Practices voor Agent Instructies
**Token gebruik monitoren:**
- Cursor toont token count in chat
- Check monthly usage in settings
**Wees specifiek:**
```
❌ "Help me met mijn project"
✅ "Review de auth logic in src/lib/auth.ts en check voor security issues"
```
**Bespaartips:**
1. Gebruik Haiku voor simpele taken
2. Beperk context (niet hele codebase)
3. Wees specifiek in prompts
4. Fresh chat voor nieuwe onderwerpen
**Geef constraints:**
```
❌ "Maak het beter"
✅ "Refactor naar max 50 regels, behoud dezelfde functionaliteit"
```
**Free tier strategie:**
- Focus op Tab completion (onbeperkt)
- Gebruik CMD+K spaarzaam
- Composer alleen voor grote taken
**Definieer output format:**
```
Geef je antwoord in dit format:
1. Samenvatting (1 zin)
2. Gevonden issues (bullet points)
3. Voorgestelde fix (code)
```
---
### Prompt Templates
**Code Generation Template:**
```
Context: [beschrijf je project/stack]
Taak: [wat moet er gemaakt worden]
Requirements:
- [requirement 1]
- [requirement 2]
Constraints:
- [constraint 1]
Output: [gewenst format]
```
**Debugging Template:**
```
Error message:
[plak error]
Relevante code:
[plak code]
Wat ik verwacht:
[gewenst gedrag]
Wat er gebeurt:
[actueel gedrag]
```
---
## Tools
- Cursor
- Claude models (Haiku/Sonnet/Opus)
- .cursorrules
- ChatGPT Custom GPTs
- Claude Projects
- Cursor (Composer mode)
---
## Lesopdracht (2 uur)
### Multi-Step Form Wizard
### Bouw Je Eigen AI Assistant
**Bouw met Composer:**
**Deel 1: Claude Project (45 min)**
| Stap | Features |
|------|----------|
| 1 | Personal info (naam, email) |
| 2 | Preferences (theme, notifications) |
| 3 | Review & confirm |
| 4 | Success animation |
Maak een Claude Project voor je eindproject:
1. Ga naar claude.ai → Projects → New Project
2. Schrijf project instructions:
- Tech stack
- Coding conventions
- Project specifieke regels
3. Upload relevante files (schema, README)
4. Test met 3 verschillende vragen
**Requirements:**
- Progress indicator
- Per-stap validatie
- localStorage persistence
- TypeScript strict
- Tailwind styling
- Mobile responsive
**Deel 2: Custom GPT (45 min)**
**Process:**
Maak een Custom GPT voor code review:
1. Ga naar chat.openai.com/gpts
2. Klik "Create"
3. Schrijf instructions voor jouw stack
4. Test met code uit je project
**Deel 1: Composer Setup (30 min)**
1. Open Composer (CMD+I)
2. Schrijf comprehensive prompt
3. Include @ mentions naar relevante files
4. Kies Sonnet of Opus
**Deel 3: Vergelijking (30 min)**
**Deel 2: Generatie & Review (45 min)**
1. Laat Composer genereren
2. Review elke file
3. Accept wat goed is
4. Reject wat niet past
**Deel 3: Refinement (45 min)**
1. Gebruik CMD+K voor kleine fixes
2. Chat voor vragen
3. Itereer tot het werkt
Test dezelfde taak met beide:
- "Review deze component op best practices"
- Noteer verschillen in output
- Welke is beter voor welk doel?
### Deliverable
- Werkende form wizard
- Notities: welk model wanneer, hoeveel iteraties
- Claude Project URL
- Custom GPT (als je ChatGPT Plus hebt) of instructies doc
- Vergelijkingsnotities
---
## Huiswerk (2 uur)
### Perfecte .cursorrules
### Optimaliseer Je AI Assistants
**Deel 1: Research (30 min)**
- Zoek 3-5 .cursorrules voorbeelden online
- Analyseer wat ze effectief maakt
**Deel 1: Iteratie (1 uur)**
**Deel 2: Write Comprehensive Rules (1 uur)**
Verbeter je Claude Project:
1. Test met 5 verschillende taken
2. Noteer waar instructies tekortschieten
3. Pas instructies aan
4. Test opnieuw
Maak complete .cursorrules voor je eindproject:
Documenteer in `docs/AI-ASSISTANTS.md`:
- Originele instructies
- Wat niet werkte
- Verbeterde instructies
- Resultaat verschil
**Deel 2: Prompt Library (30 min)**
Maak een persoonlijke prompt library:
```markdown
# [Project Naam]
# Mijn Prompt Templates
## Tech Stack
[Jouw stack]
## Code Generation
[template]
## Code Conventions
[Jouw conventies]
## Debugging
[template]
## File Naming
[Jouw regels]
## Code Review
[template]
## Component Structure
[Jouw patterns]
## Styling
[Tailwind regels]
## API Routes
[Route conventies]
## Error Handling
[Error patterns]
## DON'Ts
[Wat te vermijden]
## Refactoring
[template]
```
**Deel 3: Test (30 min)**
1. Start nieuw component
2. Vraag Cursor om het te bouwen
3. Check: volgt Cursor je regels?
4. Itereer indien nodig
**Deel 3: Reflectie (30 min)**
Schrijf reflectie (300 woorden):
- Welke AI assistant gebruik je waarvoor?
- Wat is het verschil tussen Claude Projects en Custom GPTs?
- Hoe heeft dit je workflow verbeterd?
### Deliverable
- Complete .cursorrules file
- Screenshot van Cursor die regels volgt
- Korte analyse: wat werkt goed, wat niet
- Geoptimaliseerde AI assistant instructies
- Prompt library document
- Reflectie (300 woorden)
---
## Leerdoelen
Na deze les kan de student:
- Het juiste Claude model kiezen per taak
- Composer Mode effectief gebruiken voor multi-file features
- @ mentions strategisch inzetten voor context
- Geavanceerde .cursorrules files schrijven
- Codebase indexing optimaliseren
- Token gebruik monitoren en kosten beheren
- Het verschil uitleggen tussen chat en agent
- Een Claude Project aanmaken en configureren
- Een Custom GPT maken met specifieke instructies
- Effectieve agent instructies schrijven
- Prompt templates gebruiken voor consistente resultaten
- De juiste AI assistant kiezen per taak

View File

@@ -1,211 +1,438 @@
# Les 14: Debugging & Code Review met AI
> 📋 **Lesmateriaal nog niet uitgewerkt**
>
> De volgende bestanden worden gegenereerd wanneer deze les wordt uitgewerkt:
> - Les14-Slide-Overzicht.md
> - Les14-Lesplan.md
> - Les14-Bijlage-A-Lesopdracht.md
> - Les14-Bijlage-B-Huiswerkopdracht.md
# Les 14: Project Setup & Repository Structure
---
## Hoofdstuk
**Hoofdstuk 3: Advanced** (Les 10-18)
**Deel 4: Advanced AI Features** (Les 13-18)
## Beschrijving
Leer hoe je AI effectief inzet voor debugging en code review. Begrijp foutmeldingen, los problemen op, en verbeter je code kwaliteit.
Leer professionele project setup en repository structuur. Begrijp hoe een goed georganiseerd project AI tools effectiever maakt en samenwerking vergemakkelijkt.
---
## Te Behandelen
### Waarom AI voor Debugging?
- AI begrijpt error messages vaak beter dan Google
- Kan context van jouw code meenemen
- Suggereert oplossingen specifiek voor jouw situatie
- Leert je patterns herkennen
### Groepsdiscussie (15 min)
Bespreek klassikaal de AI assistant reflecties uit Les 13 - welke instructies werkten goed en welke niet?
### Error Messages Begrijpen
### Waarom Project Structuur Belangrijk Is
**Typische JavaScript/React errors:**
- `TypeError: Cannot read properties of undefined`
- `ReferenceError: x is not defined`
- `SyntaxError: Unexpected token`
- `Hydration error` (Next.js specifiek)
**Voor jezelf:**
- Sneller code terugvinden
- Makkelijker onderhouden
- Minder bugs door consistentie
**Hoe AI vragen:**
**Voor AI tools:**
- Betere context understanding
- Consistentere code generation
- Cursor/Claude begrijpt je project beter
**Voor samenwerking:**
- Anderen begrijpen je code sneller
- Standaard conventies = minder discussie
- Onboarding nieuwe developers eenvoudiger
---
### Next.js 14 Project Structuur
**Aanbevolen structuur:**
```
Ik krijg deze error:
[plak error message]
In deze code:
[plak relevante code]
Wat gaat er mis en hoe los ik het op?
project-root/
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── (auth)/ # Route group voor auth pagina's
│ │ │ ├── login/
│ │ │ └── register/
│ │ ├── api/ # API routes
│ │ │ └── chat/
│ │ ├── dashboard/
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ └── globals.css
│ │
│ ├── components/ # React components
│ │ ├── ui/ # Basis UI components
│ │ │ ├── Button.tsx
│ │ │ ├── Input.tsx
│ │ │ └── Card.tsx
│ │ ├── layout/ # Layout components
│ │ │ ├── Header.tsx
│ │ │ ├── Footer.tsx
│ │ │ └── Sidebar.tsx
│ │ └── features/ # Feature-specifieke components
│ │ ├── auth/
│ │ └── dashboard/
│ │
│ ├── lib/ # Utilities en configuraties
│ │ ├── supabase.ts # Supabase client
│ │ ├── utils.ts # Helper functies
│ │ └── constants.ts # App constanten
│ │
│ ├── hooks/ # Custom React hooks
│ │ ├── useAuth.ts
│ │ └── useTodos.ts
│ │
│ └── types/ # TypeScript types
│ ├── database.ts
│ └── api.ts
├── public/ # Static assets
│ ├── images/
│ └── favicon.ico
├── docs/ # Documentatie
│ ├── PROMPT-LOG.md
│ ├── AI-DECISIONS.md
│ └── PROJECT-BRIEF.md
├── .cursorrules # Cursor AI configuratie
├── .env.local # Environment variables (niet in git!)
├── .env.example # Template voor env vars
├── .gitignore
├── package.json
├── tsconfig.json
├── tailwind.config.ts
└── README.md
```
### Debugging Workflow met AI
---
**Stap 1: Isoleer het probleem**
- Waar treedt de error op?
- Wat was de laatste wijziging?
- Kan je het reproduceren?
### Component Organisatie
**Stap 2: Verzamel context**
- Error message (volledig!)
- Relevante code
- Wat je verwacht vs wat er gebeurt
**UI Components (src/components/ui/):**
- Herbruikbare, generieke components
- Geen business logic
- Props-driven
- Voorbeelden: Button, Input, Modal, Card
**Stap 3: Vraag AI**
- Wees specifiek
- Geef context
- Vraag om uitleg, niet alleen fix
**Layout Components (src/components/layout/):**
- Structurele components
- Meestal één per type
- Voorbeelden: Header, Footer, Sidebar, Navigation
**Stap 4: Begrijp de oplossing**
- Vraag door als je het niet snapt
- Leer het pattern voor volgende keer
**Feature Components (src/components/features/):**
- Business logic bevattend
- Specifiek voor één feature
- Groepeer per feature/domein
### Console.log Debugging
- Strategisch plaatsen
- Variabele waarden checken
- Flow van code volgen
- AI kan helpen met waar te loggen
---
### Browser DevTools Basics
- Console tab: errors en logs
- Network tab: API calls checken
- Elements tab: HTML/CSS inspecteren
- React DevTools: component state bekijken
### File Naming Conventions
### Code Review met AI
**Wat kan AI reviewen:**
- Code kwaliteit en leesbaarheid
- Potentiële bugs
- Performance issues
- Security problemen
- Best practices
**Goede review prompt:**
**Components:**
```
Review deze code op:
1. Bugs of edge cases die ik mis
2. Performance verbeteringen
3. Leesbaarheid
4. Best practices voor React/Next.js
[plak code]
✅ Button.tsx # PascalCase
✅ UserProfile.tsx
❌ button.tsx
❌ user-profile.tsx
```
### Veelvoorkomende Issues die AI Vindt
- Missing error handling
- Memory leaks (useEffect cleanup)
- Onnodig re-renders
- Hardcoded values
- Missing loading/error states
- Accessibility issues
**Hooks:**
```
✅ useAuth.ts # camelCase met 'use' prefix
✅ useTodos.ts
❌ UseAuth.ts
❌ auth-hook.ts
```
### Refactoring met AI
- "Hoe kan ik deze code simplificeren?"
- "Extract dit naar een custom hook"
- "Maak dit component meer herbruikbaar"
**Utilities:**
```
✅ formatDate.ts # camelCase
✅ utils.ts
✅ constants.ts
```
### Wanneer NIET AI Vertrouwen
- Als je de oplossing niet begrijpt
- Bij security-gerelateerde code (dubbel check!)
- Bij verouderde info (check versie docs)
**Types:**
```
✅ database.ts # camelCase
✅ User.types.ts # optioneel: .types suffix
```
---
### .cursorrules Setup
**Maak .cursorrules in project root:**
```markdown
# Project: [Jouw Project Naam]
## Tech Stack
- Next.js 14 met App Router
- TypeScript (strict mode)
- Tailwind CSS
- Supabase
- React Query
## File Structure
- Components in src/components/
- UI components in src/components/ui/
- API routes in src/app/api/
## Code Conventions
- Functional components only
- Named exports (geen default exports)
- Props interface boven component
- Nederlandse comments
## Naming
- Components: PascalCase (Button.tsx)
- Hooks: camelCase met use prefix (useAuth.ts)
- Utils: camelCase (formatDate.ts)
## Styling
- Tailwind CSS classes
- Geen inline styles
- Responsive mobile-first
## TypeScript
- Strict mode
- Geen any types
- Interfaces voor props
- Types voor data
## Don'ts
- Geen console.log in productie
- Geen hardcoded strings
- Geen unused imports
```
---
### Git Best Practices
**Commit Message Format:**
```
type: korte beschrijving
Types:
- feat: nieuwe feature
- fix: bug fix
- refactor: code verbetering
- docs: documentatie
- style: formatting
- test: tests toevoegen
```
**Voorbeelden:**
```bash
git commit -m "feat: add user authentication with Supabase"
git commit -m "fix: resolve hydration error in TodoList"
git commit -m "docs: update README with setup instructions"
```
**.gitignore essentials:**
```
# Dependencies
node_modules/
# Environment
.env*.local
# Next.js
.next/
out/
# IDE
.idea/
.vscode/
# OS
.DS_Store
```
---
### Environment Variables
**Structuur:**
```bash
# .env.local (NOOIT committen!)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGci...
OPENAI_API_KEY=sk-...
# .env.example (WEL committen)
NEXT_PUBLIC_SUPABASE_URL=your-supabase-url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
OPENAI_API_KEY=your-openai-key
```
**Regels:**
- `NEXT_PUBLIC_` prefix = zichtbaar in browser
- Zonder prefix = alleen server-side
- Nooit secrets in `NEXT_PUBLIC_` vars
---
### README.md Template
```markdown
# Project Naam
Korte beschrijving van je project.
## Features
- Feature 1
- Feature 2
- Feature 3
## Tech Stack
- Next.js 14
- TypeScript
- Tailwind CSS
- Supabase
- Vercel AI SDK
## Getting Started
### Prerequisites
- Node.js 18+
- npm of yarn
- Supabase account
### Installation
1. Clone de repository
```bash
git clone https://github.com/username/project.git
cd project
```
2. Installeer dependencies
```bash
npm install
```
3. Maak .env.local (zie .env.example)
4. Start development server
```bash
npm run dev
```
## Environment Variables
Zie `.env.example` voor benodigde variabelen.
## Deployment
Deployed op Vercel: [productie-url]
## Documentatie
- [PROMPT-LOG.md](docs/PROMPT-LOG.md)
- [AI-DECISIONS.md](docs/AI-DECISIONS.md)
```
---
## Tools
- Cursor
- Browser DevTools
- React DevTools
- Console/Terminal
- Git
- GitHub
---
## Lesopdracht (2 uur)
### Debugging Challenge
### Setup Je Eindproject
Je krijgt een project met opzettelijke bugs. Los ze op met AI hulp.
**Deel 1: Project Structuur (45 min)**
**Deel 1: Setup (10 min)**
- Clone het buggy project (wordt gedeeld)
- Run `npm install` en `npm run dev`
- Zie alle errors!
1. Maak nieuw Next.js project:
```bash
npx create-next-app@latest mijn-eindproject --typescript --tailwind --app
```
**Deel 2: Bug Hunting (1 uur 20 min)**
2. Maak de mappenstructuur:
- src/components/ui/
- src/components/layout/
- src/components/features/
- src/lib/
- src/hooks/
- src/types/
- docs/
Los de volgende bugs op (met AI hulp):
3. Maak placeholder files:
- src/lib/supabase.ts
- src/lib/utils.ts
| Bug | Symptoom |
|-----|----------|
| 1 | App crashed bij opstarten |
| 2 | Data wordt niet geladen |
| 3 | Form submit werkt niet |
| 4 | Styling is broken op mobile |
| 5 | Infinite loop bij useEffect |
| 6 | Button click doet niets |
**Deel 2: Configuratie (30 min)**
**Per bug:**
- Identificeer de error message
- Vraag AI om hulp met context
- Implementeer de fix
- Documenteer wat je geleerd hebt
1. Maak .cursorrules met jouw conventies
2. Maak .env.example
3. Update .gitignore
4. Maak README.md met template
**Deel 3: Documentatie (30 min)**
- Voeg toe aan je `PROMPT-LOG.md`:
- De prompts die je gebruikte
- Wat werkte wel/niet
**Deel 3: Git Setup (25 min)**
1. git init
2. Initial commit met goede message
3. Push naar GitHub
4. Check: .env.local NIET gecommit?
**Deel 4: Documentatie Start (20 min)**
Maak in docs/:
- PROJECT-BRIEF.md (beschrijving eindproject)
- PROMPT-LOG.md (leeg template)
- AI-DECISIONS.md (leeg template)
### Deliverable
- Alle 6 bugs gefixed
- PROMPT-LOG.md bijgewerkt
- Korte notities per bug: wat was het probleem, hoe opgelost
- GitHub repository met correcte structuur
- .cursorrules file
- README.md
- docs/ folder met templates
---
## Huiswerk (2 uur)
### Code Review Je Eigen Project
### Bouw Project Foundation
**Deel 1: Self-Review met AI (1 uur)**
- Kies 3 belangrijke files uit je eindproject
- Laat AI ze reviewen met een goede prompt
- Documenteer bevindingen in `AI-DECISIONS.md`
**Deel 1: Base Components (1 uur)**
**Per file noteer:**
- Welke issues AI vond
- Welke je hebt gefixed
- Welke je bewust negeert (en waarom)
Maak basis UI components met AI hulp:
- src/components/ui/Button.tsx
- src/components/ui/Input.tsx
- src/components/ui/Card.tsx
- src/components/layout/Header.tsx
- src/components/layout/Footer.tsx
**Deel 2: Refactoring (45 min)**
- Kies 1 component dat te complex is
- Vraag AI om refactoring suggesties
- Implementeer de verbeteringen
- Vergelijk before/after
Requirements:
- TypeScript interfaces voor props
- Tailwind styling
- Responsive design
- Volg je .cursorrules
**Deel 3: Debugging Checklist (15 min)**
- Maak persoonlijke debugging checklist
- Wat check je eerst bij errors?
- Welke prompts werken goed voor jou?
**Deel 2: Supabase Setup (30 min)**
1. Maak Supabase project (of hergebruik van Les 9)
2. Configureer src/lib/supabase.ts
3. Voeg env vars toe aan .env.local
4. Test connectie
**Deel 3: Eerste Feature (30 min)**
Kies je eindproject en implementeer 1 basisfeature:
- Recipe Generator: ingredient input form
- Budget Buddy: expense entry form
- Travel Planner: destination search
Commit en push!
### Deliverable
- AI-DECISIONS.md met review bevindingen
- 1 gerefactored component
- Persoonlijke debugging checklist
- Werkende UI components
- Supabase connectie
- 1 basic feature
- Alle commits met goede messages
---
## Leerdoelen
Na deze les kan de student:
- Error messages lezen en begrijpen
- Effectieve debugging prompts schrijven voor AI
- Browser DevTools gebruiken voor debugging
- Code laten reviewen door AI
- Feedback van AI kritisch evalueren
- Refactoring uitvoeren met AI suggesties
- Documenteren wat geleerd is van debugging sessies
- Een professionele project structuur opzetten
- File naming conventions toepassen
- Een effectieve .cursorrules file schrijven
- Git best practices volgen
- Environment variables correct beheren
- Een README.md schrijven
- Project documentatie structureren

View File

@@ -1,329 +1,336 @@
# Les 15: Vercel AI SDK - AI Features in je App
# Les 15: MCP & Context Management
---
## Hoofdstuk
**Hoofdstuk 3: Advanced** (Les 10-18)
**Deel 4: Advanced AI Features** (Les 13-18)
## Beschrijving
Bouw AI-powered features in je apps met de Vercel AI SDK. Leer hoe je chat interfaces, streaming responses en AI-gegenereerde content implementeert.
Leer werken met Model Context Protocol (MCP) en geavanceerd context management. Begrijp hoe je AI tools maximale context geeft voor betere resultaten.
---
## Te Behandelen
### Waarom Vercel AI SDK?
### Groepsdiscussie (15 min)
Bespreek klassikaal de project setup ervaringen uit Les 14 - welke structuur conventies werken goed en welke niet?
**Het probleem:** Direct API calls naar OpenAI/Anthropic zijn complex:
- Streaming handmatig implementeren
- Error handling
- State management
### Wat is Context?
**De oplossing:** Vercel AI SDK
- Simpele React hooks
- Built-in streaming
- Provider-agnostic (OpenAI, Anthropic, etc.)
- Edge-ready
**Context = wat de AI weet over jouw situatie**
**Soorten context:**
- **Code context:** welke files, welke functies
- **Project context:** tech stack, conventies
- **Taak context:** wat je probeert te bereiken
- **Historische context:** eerdere conversatie
**Meer context = betere antwoorden**
---
### Installatie & Setup
### Model Context Protocol (MCP)
```bash
npm install ai @ai-sdk/openai
# of voor Anthropic:
npm install ai @ai-sdk/anthropic
**Wat is MCP?**
- Open protocol van Anthropic
- Standaard manier om AI models context te geven
- Verbindt AI met externe tools en data
**Waarom MCP?**
- AI kan nu "tools gebruiken"
- Toegang tot je filesystem
- Database queries uitvoeren
- Web searches doen
- En meer...
**Hoe werkt het:**
```
**Environment variable:**
```bash
# .env.local
OPENAI_API_KEY=sk-xxxxx
Jij → vraag → AI → MCP → Tool → resultaat → AI → antwoord → Jij
```
---
### Core Hooks
### MCP in de Praktijk
#### useChat - Voor Conversaties
**Cursor gebruikt MCP onder de hood:**
- `@file` mentions = file context via MCP
- `@codebase` = codebase search via MCP
- `@Docs` = documentation lookup via MCP
- `@Web` = web search via MCP
```tsx
'use client'
import { useChat } from 'ai/react'
**Claude Desktop met MCP:**
- Kan tools uitvoeren
- Filesystem access
- Terminal commands
- Database queries
export function ChatComponent() {
const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat()
---
return (
<div className="flex flex-col h-screen">
<div className="flex-1 overflow-y-auto p-4">
{messages.map(m => (
<div key={m.id} className={m.role === 'user' ? 'text-right' : 'text-left'}>
<span className="inline-block p-2 rounded-lg bg-gray-100">
{m.content}
</span>
</div>
))}
</div>
### Context Management Strategieën
<form onSubmit={handleSubmit} className="p-4 border-t">
<input
value={input}
onChange={handleInputChange}
placeholder="Type a message..."
className="w-full p-2 border rounded"
/>
<button type="submit" disabled={isLoading}>
{isLoading ? 'Sending...' : 'Send'}
</button>
</form>
</div>
)
}
**1. Expliciete Context**
Geef context direct in je prompt:
```
Context: Next.js 14 project met TypeScript en Supabase.
Dit is een e-commerce app voor verkoop van boeken.
Vraag: Hoe implementeer ik een winkelwagen?
```
#### useCompletion - Voor Single Completions
**2. File Context**
Gebruik @ mentions om relevante files toe te voegen:
```
@src/types/product.ts
@src/lib/supabase.ts
Hoe maak ik een addToCart functie?
```
```tsx
import { useCompletion } from 'ai/react'
**3. Project Context**
Gebruik .cursorrules of Claude Project instructions:
```
# In .cursorrules
Dit project is een e-commerce platform.
Alle prices zijn in cents (niet euros).
```
export function SummaryComponent() {
const { completion, input, handleInputChange, handleSubmit, isLoading } = useCompletion()
**4. Fresh Context**
Begin nieuwe chat voor nieuw onderwerp:
- Voorkomt context vervuiling
- AI raakt niet in de war met oude info
return (
<div>
<form onSubmit={handleSubmit}>
<textarea
value={input}
onChange={handleInputChange}
placeholder="Paste text to summarize..."
/>
<button type="submit">Summarize</button>
</form>
{completion && <p>{completion}</p>}
</div>
)
}
---
### @ Mentions Strategisch Gebruiken
**Cursor @ mentions:**
| Mention | Wanneer | Voorbeeld |
|---------|---------|-----------|
| `@file.tsx` | Specifieke file context | `@Button.tsx hoe voeg ik loading toe?` |
| `@folder/` | Hele folder context | `@components/ welke patterns gebruik ik?` |
| `@codebase` | Zoeken in project | `@codebase waar handle ik auth?` |
| `@Docs` | Officiële documentatie | `@Docs Next.js App Router` |
| `@Web` | Live web search | `@Web Supabase RLS policies` |
**Best practice:** Combineer mentions voor rijke context:
```
@src/components/auth/LoginForm.tsx
@src/lib/supabase.ts
@Docs Supabase Auth
Hoe voeg ik Google OAuth toe aan mijn login?
```
---
### API Routes
### Claude Projects voor Persistente Context
**app/api/chat/route.ts:**
```typescript
import { openai } from '@ai-sdk/openai'
import { streamText } from 'ai'
**Wat kun je toevoegen aan een Project:**
- Instructies (system prompt)
- Files (code, docs, schema's)
- Kennis die over sessies heen blijft
export async function POST(req: Request) {
const { messages } = await req.json()
**Project Instructions Template:**
```markdown
# Project: [Naam]
const result = streamText({
model: openai('gpt-4o-mini'),
system: 'You are a helpful cooking assistant. Suggest recipes based on ingredients.',
messages,
})
## Tech Stack
- Next.js 14 met App Router
- TypeScript strict
- Tailwind CSS
- Supabase
return result.toDataStreamResponse()
}
## Code Conventies
[jouw conventies]
## Database Schema
[beschrijf je schema]
## Current Focus
[waar werk je nu aan]
```
**Met custom system prompt:**
```typescript
const result = streamText({
model: openai('gpt-4o-mini'),
system: `You are a recipe assistant for the AI Recipe Generator app.
When the user provides ingredients:
1. Suggest 2-3 recipes they could make
2. List required additional ingredients (if any)
3. Provide brief cooking instructions
Be concise and practical.`,
messages,
})
```
**Tip:** Upload je database schema, README, en belangrijke types files.
---
### Streaming Responses
### Context Windows en Limieten
**Waarom streaming?**
- Betere UX (user ziet direct resultaat)
- Snellere perceived performance
- Geen wachten op complete response
**Wat is een context window?**
- Maximum hoeveelheid tekst die AI kan "zien"
- Gemeten in tokens (±4 karakters per token)
**Hoe het werkt:**
1. Server stuurt tokens één voor één
2. Client rendert elke token direct
3. User ziet "typing" effect
**Limieten per model:**
| Model | Context Window |
|-------|---------------|
| GPT-4o | 128K tokens |
| Claude 3 Sonnet | 200K tokens |
| Claude 3 Opus | 200K tokens |
**Loading indicator:**
```tsx
{isLoading && (
<div className="flex items-center gap-2">
<div className="animate-pulse"></div>
<span>AI is thinking...</span>
</div>
)}
```
**Praktisch:**
- Lange conversaties → context vol
- Veel file mentions → context vol
- Start fresh chat wanneer nodig
**Signs van vol context:**
- AI vergeet eerdere instructies
- Antwoorden worden minder relevant
- AI herhaalt zichzelf
---
### Integratie met Supabase
### Context Hygiene
**Conversations opslaan:**
**Do's:**
- Geef alleen relevante context
- Wees specifiek in file mentions
- Start nieuwe chat voor nieuw onderwerp
- Gebruik project-level context voor consistentie
```typescript
// Maak tabel in Supabase:
// conversations: id, user_id, created_at
// messages: id, conversation_id, role, content, created_at
// Na elke message:
async function saveMessage(conversationId: string, role: string, content: string) {
await supabase.from('messages').insert({
conversation_id: conversationId,
role,
content
})
}
```
**In je component:**
```tsx
const { messages, input, handleSubmit } = useChat({
onFinish: async (message) => {
await saveMessage(conversationId, message.role, message.content)
}
})
```
**Don'ts:**
- Hele codebase als context geven
- Oude irrelevante chats voortzetten
- Te veel files tegelijk mentionen
- Context herhalen die AI al heeft
---
### Error Handling
### Debugging met Context
```tsx
const { messages, error, reload } = useChat()
**Wanneer AI verkeerde antwoorden geeft:**
{error && (
<div className="p-4 bg-red-100 text-red-700 rounded">
<p>Something went wrong. Please try again.</p>
<button onClick={reload}>Retry</button>
</div>
)}
1. **Check context:** Heeft AI de juiste files?
2. **Check instructies:** Zijn project rules geladen?
3. **Fresh start:** Begin nieuwe chat
4. **Explicieter:** Voeg meer context toe in prompt
**Debug prompt:**
```
Ik merk dat je antwoord niet klopt.
Heb je toegang tot @src/lib/auth.ts?
Dit is de huidige implementatie: [plak code]
Kun je opnieuw kijken?
```
---
### Cost Management
**Model keuze:**
| Model | Kosten | Gebruik voor |
|-------|--------|--------------|
| gpt-4o-mini | Goedkoop | Meeste taken |
| gpt-4o | Duur | Complexe reasoning |
| claude-3-haiku | Goedkoop | Simpele taken |
| claude-3-sonnet | Medium | Balans |
**Bespaartips:**
1. Gebruik gpt-4o-mini als default
2. Korte system prompts
3. Beperk conversation history
4. Caching waar mogelijk
---
## Tools
- Vercel AI SDK (`ai` package)
- Next.js API Routes
- OpenAI API / Anthropic API
- Cursor
- Supabase
- Cursor (@ mentions)
- Claude Projects
- ChatGPT
---
## Lesopdracht (2 uur)
### Bouw een AI Chat Component
### Context Management Oefenen
**Deel 1: Setup (20 min)**
1. `npm install ai @ai-sdk/openai`
2. Voeg `OPENAI_API_KEY` toe aan `.env.local`
3. Maak `app/api/chat/route.ts`
**Deel 1: @ Mentions Mastery (45 min)**
**Deel 2: Basic Chat (40 min)**
1. Maak `components/Chat.tsx`
2. Implementeer `useChat` hook
3. Bouw chat UI met Tailwind
4. Test streaming werkt
Voer deze taken uit in Cursor:
**Deel 3: System Prompt (30 min)**
1. Schrijf system prompt voor je eindproject:
- Recipe Generator: cooking assistant
- Budget Buddy: financial advisor
- Travel Planner: travel expert
2. Test met relevante vragen
1. **Single file context:**
- Open je TodoList component
- Vraag: "@TodoList.tsx Hoe kan ik infinite scroll toevoegen?"
- Noteer kwaliteit antwoord
**Deel 4: Supabase Integratie (30 min)**
1. Maak `messages` tabel
2. Sla berichten op met `onFinish`
3. Laad history bij page load
2. **Multi-file context:**
- Vraag: "@src/components/ @src/types/ Welke types mis ik?"
- Noteer hoe context helpt
3. **Docs context:**
- Vraag: "@Docs Supabase realtime Hoe voeg ik real-time updates toe aan mijn todo app?"
- Noteer of antwoord up-to-date is
4. **Codebase search:**
- Vraag: "@codebase Waar handle ik error states?"
- Noteer of het de juiste plekken vindt
**Deel 2: Claude Project Setup (30 min)**
1. Maak Claude Project voor je eindproject
2. Schrijf comprehensive instructions
3. Upload 3-5 belangrijke files:
- Database schema/types
- Main component
- Supabase client
4. Test met 3 vragen
**Deel 3: Context Vergelijking (45 min)**
Voer dezelfde taak uit met:
1. Geen context (nieuwe chat, geen mentions)
2. File context (@mentions)
3. Project context (Claude Project)
Taak: "Implementeer een search feature voor todos"
Noteer:
- Kwaliteit code
- Relevantie voor jouw project
- Hoeveel aanpassing nodig
### Deliverable
- Werkende AI chat met streaming
- Custom system prompt
- Messages opgeslagen in Supabase
- Notities over @ mentions effectiviteit
- Claude Project met instructions
- Context vergelijkingsnotities
---
## Huiswerk (2 uur)
### Bouw AI Feature voor Eindproject
### Optimaliseer Je Context Strategie
**Deel 1: Core AI Feature (1 uur)**
**Deel 1: .cursorrules Perfectioneren (30 min)**
Implementeer de AI chat die past bij je eindproject:
Update je .cursorrules met:
- Specifieke file structure info
- Naming conventions met voorbeelden
- Common patterns in je project
- DON'Ts specifiek voor jouw situatie
| Project | AI Feature |
|---------|-----------|
| Recipe Generator | "Wat kan ik maken met kip en rijst?" |
| Budget Buddy | "Analyseer mijn uitgaven deze maand" |
| Travel Planner | "Plan een weekend Barcelona" |
**Deel 2: Claude Project Uitbreiden (45 min)**
- Custom system prompt
- Context uit je database meegeven
1. Upload alle relevante project files
2. Test met complexe vragen:
- "Hoe implementeer ik feature X?"
- "Review mijn auth implementatie"
- "Wat ontbreekt er nog?"
3. Itereer op instructions
**Deel 2: UX Polish (30 min)**
**Deel 3: Context Documentation (45 min)**
Voeg toe:
- Streaming indicator
- Suggested prompts / quick actions
- Copy response button
- Clear chat button
- Error handling
Maak `docs/CONTEXT-GUIDE.md`:
```markdown
# Context Guide voor [Project]
**Deel 3: Documentatie (30 min)**
## Cursor @ Mentions
- Voor UI changes: @src/components/
- Voor data logic: @src/lib/ @src/hooks/
- Voor types: @src/types/
Maak `docs/AI-FEATURE.md`:
- Welke AI feature heb je gebouwd?
- Wat doet de system prompt?
- Hoe integreert het met Supabase?
- Welke model keuzes heb je gemaakt?
## Claude Project
- Project URL: [link]
- Uploaded files: [lijst]
- Best practices: [jouw learnings]
## Common Prompts
[verzameling werkende prompts]
```
### Deliverable
- AI feature in eindproject
- Deployed preview
- AI-FEATURE.md documentatie
- Geoptimaliseerde .cursorrules
- Complete Claude Project
- docs/CONTEXT-GUIDE.md
---
## Leerdoelen
Na deze les kan de student:
- Vercel AI SDK installeren en configureren
- `useChat` en `useCompletion` hooks gebruiken
- Streaming responses implementeren
- API routes opzetten voor AI providers
- Custom system prompts schrijven
- Chat history opslaan in Supabase
- Error handling en loading states implementeren
- Kostenbewust omgaan met AI APIs
- Uitleggen wat context is en waarom het belangrijk is
- Model Context Protocol (MCP) begrijpen
- @ mentions strategisch gebruiken in Cursor
- Een Claude Project opzetten met effectieve instructions
- Context windows en limieten begrijpen
- Context management best practices toepassen
- Debuggen wanneer AI verkeerde antwoorden geeft door context issues

View File

@@ -1,227 +1,340 @@
# Les 16: Deployment & Production
# Les 16: Mastering Cursor
---
## Hoofdstuk
**Hoofdstuk 3: Advanced** (Les 10-18)
**Deel 4: Advanced AI Features** (Les 13-18)
## Beschrijving
Deploy je eindproject naar productie. Leer environment variables, Vercel deployment, en basis performance optimalisatie.
Verdieping in Cursor's geavanceerde features. Leer model keuze, Composer Mode, @ mentions, en .cursorrules optimaal gebruiken.
---
## Te Behandelen
### Vercel Deployment Flow
### Groepsdiscussie (15 min)
Bespreek klassikaal de context management ervaringen uit Les 15 - welke strategieën werkten het beste?
**Hoe Vercel werkt:**
1. Connect GitHub repository
2. Push naar main → automatische deploy
3. Push naar andere branch → preview URL
4. Alles automatisch (build, SSL, CDN)
### Model Keuze
**Waarom Vercel voor Next.js:**
- Gemaakt door dezelfde makers
- Zero-config deployment
- Gratis tier ruim voldoende
- Automatische HTTPS
- Global CDN
**Wanneer welk model?**
| Model | Gebruik voor | Kosten |
|-------|-------------|--------|
| **Haiku** | Simpele taken, autocomplete | Goedkoop |
| **Sonnet** | Dagelijks werk, de meeste taken | Medium |
| **Opus** | Complexe architectuur, multi-file | Duur |
**Vuistregels:**
- Tab completion: Haiku (automatisch)
- CMD+K: Sonnet (default)
- Composer: Sonnet of Opus
- Complexe debugging: Opus
---
### Environment Variables in Vercel
### Composer Mode Diepgaand
**Lokaal (.env.local) vs Productie (Vercel Dashboard):**
**Wat is Composer?**
Multi-file generatie in één keer. Cursor plant en voert wijzigingen uit over meerdere bestanden.
| Waar | Bestand/Locatie | Voorbeeld |
|------|-----------------|-----------|
| Lokaal | `.env.local` | Development |
| Vercel | Dashboard → Settings → Env Vars | Production |
**Wanneer Composer gebruiken:**
- Nieuwe feature met meerdere components
- Refactoring over meerdere files
- Boilerplate generatie
- Complexe wijzigingen
**Stap voor stap:**
1. Ga naar je Vercel project
2. Settings → Environment Variables
3. Voeg toe:
- `NEXT_PUBLIC_SUPABASE_URL`
- `NEXT_PUBLIC_SUPABASE_ANON_KEY`
- `OPENAI_API_KEY`
4. Selecteer environment (Production, Preview, Development)
5. Save & Redeploy
**Composer Workflow:**
1. CMD+I opent Composer
2. Beschrijf je doel duidelijk
3. Voeg context toe met @ mentions
4. Laat Cursor plannen
5. Review het plan
6. Accept of reject per file
7. Itereer met feedback
**Let op:**
- `NEXT_PUBLIC_` prefix = zichtbaar in browser
- Zonder prefix = alleen server-side (API routes)
**Voorbeeld prompt:**
```
Create a user profile page with:
- @components/ui/ style components
- Profile header with avatar
- Edit form with validation
- Save to @lib/supabase.ts
- Loading and error states
```
---
### Supabase Productie Setup
### @ Mentions Systeem
**Redirect URLs configureren:**
1. Ga naar Supabase → Authentication → URL Configuration
2. Voeg toe bij "Redirect URLs":
- `https://jouw-app.vercel.app/**`
- `https://jouw-app.vercel.app`
**Alle types:**
**Waarom:**
- Auth redirects werken alleen naar toegestane URLs
- Wildcards (`**`) voor sub-routes
| Mention | Wat het doet | Voorbeeld |
|---------|--------------|-----------|
| `@file.tsx` | Specifieke file | `@Button.tsx` |
| `@folder/` | Hele folder | `@components/` |
| `@codebase` | Zoek in codebase | `@codebase auth logic` |
| `@Docs` | Officiële docs | `@Docs Next.js routing` |
| `@Web` | Web zoeken | `@Web Supabase auth setup` |
**Best practices:**
- Wees specifiek met file mentions
- Gebruik folder mentions voor context
- @Docs voor up-to-date informatie
- Combineer mentions voor betere context
---
### Deployment Checklist
### .cursorrules Advanced
**Voor deployment:**
- [ ] `npm run build` werkt lokaal
- [ ] Geen TypeScript errors
- [ ] Environment variables gedocumenteerd in `.env.example`
- [ ] `.gitignore` bevat `.env*.local`
- [ ] README up-to-date
**Meerdere rules files:**
**Na deployment:**
- [ ] App laadt correct
- [ ] Auth werkt (login/logout)
- [ ] Data wordt opgehaald uit Supabase
- [ ] AI features werken (indien van toepassing)
- [ ] Geen console errors
```
.cursor/
└── rules/
├── general.mdc # Project-brede regels
├── components.mdc # Component conventies
├── api.mdc # API route regels
└── testing.mdc # Test conventies
```
**Effectieve rules schrijven:**
```markdown
# Component Rules
## Structure
Alle components moeten volgen:
1. Props interface bovenaan
2. Component function
3. Named export onderaan
## Example
\`\`\`tsx
interface ButtonProps {
label: string
onClick: () => void
variant?: 'primary' | 'secondary'
}
export function Button({ label, onClick, variant = 'primary' }: ButtonProps) {
return (
<button onClick={onClick} className={...}>
{label}
</button>
)
}
\`\`\`
## DON'Ts
- Geen default exports
- Geen inline styles
- Geen any types
```
---
### Performance Basics
### Codebase Indexing
**Lighthouse Audit:**
1. Open Chrome DevTools
2. Tab "Lighthouse"
3. Klik "Analyze page load"
4. Aim for score >80 in elke categorie
**Hoe Cursor indexeert:**
- Scant alle files in je project
- Bouwt semantic understanding
- Gebruikt voor autocomplete en context
**Quick wins:**
- Gebruik Next.js `Image` component (niet `<img>`)
- Lazy load components die niet direct nodig zijn
- Verwijder ongebruikte dependencies
**Optimaliseren:**
1. Goede `.cursorignore` (node_modules, .next, etc.)
2. Semantische naming
3. Duidelijke file structuur
4. Comments waar nodig
**Re-indexeren:**
CMD+Shift+P → "Reindex"
---
### Security Checklist
### Cost Management
**Belangrijk voor productie:**
- [ ] API keys nooit in client-side code
- [ ] Supabase RLS enabled (Row Level Security)
- [ ] Error messages geven geen gevoelige info
- [ ] HTTPS (automatisch via Vercel)
**Token gebruik monitoren:**
- Cursor toont token count in chat
- Check monthly usage in settings
**Bespaartips:**
1. Gebruik Haiku voor simpele taken
2. Beperk context (niet hele codebase)
3. Wees specifiek in prompts
4. Fresh chat voor nieuwe onderwerpen
**Free tier strategie:**
- Focus op Tab completion (onbeperkt)
- Gebruik CMD+K spaarzaam
- Composer alleen voor grote taken
---
### Monitoring Basics
### Debugging met Cursor
**Vercel Dashboard toont:**
- Deployments history
- Function logs
- Analytics (optioneel)
**AI-Assisted Debugging:**
**Supabase Dashboard toont:**
- Database usage
- Auth logs
- API requests
**Stap 1: Error identificeren**
```
@file-met-error.tsx
Ik krijg deze error: [plak error]
Wat gaat er mis?
```
**Stap 2: Context toevoegen**
```
@file-met-error.tsx
@gerelateerde-file.ts
De error treedt op wanneer ik X doe.
Console log toont: [data]
```
**Stap 3: Fix implementeren**
- Selecteer code met error
- CMD+K → "Fix this error: [beschrijving]"
- Review en test
---
### Refactoring met Cursor
**Pattern 1: Extract Component**
```
Selecteer JSX block → CMD+K
"Extract this into a separate component called ProductCard"
```
**Pattern 2: Extract Hook**
```
Selecteer state + useEffect → CMD+K
"Extract this into a custom hook called useProductData"
```
**Pattern 3: Improve Performance**
```
@Component.tsx
"Optimize this component:
- Add memoization waar nodig
- Fix unnecessary re-renders
- Improve loading performance"
```
---
## Tools
- Vercel
- GitHub
- Supabase
- Chrome DevTools (Lighthouse)
- Cursor
- Claude models (Haiku/Sonnet/Opus)
- .cursorrules
---
## Lesopdracht (2 uur)
### Deploy Je Eindproject
### Multi-Step Form Wizard
**Deel 1: Pre-Deployment Check (30 min)**
**Bouw met Composer:**
Run door de checklist:
1. `npm run build` - fix eventuele errors
2. Check TypeScript errors
3. Maak/update `.env.example`
4. Update README met project info
| Stap | Features |
|------|----------|
| 1 | Personal info (naam, email) |
| 2 | Preferences (theme, notifications) |
| 3 | Review & confirm |
| 4 | Success animation |
**Deel 2: Vercel Deployment (30 min)**
**Requirements:**
- Progress indicator
- Per-stap validatie
- localStorage persistence
- TypeScript strict
- Tailwind styling
- Mobile responsive
1. Ga naar [vercel.com](https://vercel.com)
2. "Add New Project"
3. Import je GitHub repository
4. Voeg environment variables toe
5. Deploy!
**Process:**
**Deel 3: Supabase Config (20 min)**
**Deel 1: Composer Setup (30 min)**
1. Open Composer (CMD+I)
2. Schrijf comprehensive prompt
3. Include @ mentions naar relevante files
4. Kies Sonnet of Opus
1. Voeg Vercel URL toe aan Supabase redirect URLs
2. Test auth in productie
3. Verifieer data access
**Deel 2: Generatie & Review (45 min)**
1. Laat Composer genereren
2. Review elke file
3. Accept wat goed is
4. Reject wat niet past
**Deel 4: Testing & Lighthouse (40 min)**
1. Test alle features in productie:
- Login/logout
- CRUD operaties
- AI chat (indien aanwezig)
2. Run Lighthouse audit
3. Fix issues tot score >80
4. Screenshot resultaat
**Deel 3: Refinement (45 min)**
1. Gebruik CMD+K voor kleine fixes
2. Chat voor vragen
3. Itereer tot het werkt
### Deliverable
- Werkende productie URL
- Lighthouse screenshot (score >80)
- Test rapport: wat werkt, wat niet
- Werkende form wizard
- Notities: welk model wanneer, hoeveel iteraties
---
## Huiswerk (2 uur)
### Polish & Documentatie
### Perfecte .cursorrules
**Deel 1: Bug Fixes (1 uur)**
**Deel 1: Research (30 min)**
- Zoek 3-5 .cursorrules voorbeelden online
- Analyseer wat ze effectief maakt
1. Test je app grondig in productie
2. Fix gevonden bugs
3. Test edge cases:
- Lege states
- Error states
- Loading states
4. Redeploy
**Deel 2: Write Comprehensive Rules (1 uur)**
**Deel 2: Performance Optimization (30 min)**
Maak complete .cursorrules voor je eindproject:
1. Run Lighthouse opnieuw
2. Fix top 3 performance issues
3. Document wat je hebt verbeterd
```markdown
# [Project Naam]
**Deel 3: Documentatie Afronden (30 min)**
## Tech Stack
[Jouw stack]
Update je `README.md`:
- Werkende productie URL
- Features lijst
- Tech stack
- Setup instructies
- Screenshots
## Code Conventions
[Jouw conventies]
Update `docs/`:
- PROMPT-LOG.md (minimaal 10 entries)
- AI-DECISIONS.md (minimaal 5 entries)
## File Naming
[Jouw regels]
## Component Structure
[Jouw patterns]
## Styling
[Tailwind regels]
## API Routes
[Route conventies]
## Error Handling
[Error patterns]
## DON'Ts
[Wat te vermijden]
```
**Deel 3: Test (30 min)**
1. Start nieuw component
2. Vraag Cursor om het te bouwen
3. Check: volgt Cursor je regels?
4. Itereer indien nodig
### Deliverable
- Geoptimaliseerde productie app
- Complete documentatie
- Lighthouse score >85
- Complete .cursorrules file
- Screenshot van Cursor die regels volgt
- Korte analyse: wat werkt goed, wat niet
---
## Leerdoelen
Na deze les kan de student:
- Een Next.js app deployen naar Vercel
- Environment variables configureren in Vercel
- Supabase redirect URLs instellen voor productie
- Een deployment checklist doorlopen
- Lighthouse gebruiken voor performance audit
- Basis security checks uitvoeren
- Productie monitoring begrijpen
- Het juiste Claude model kiezen per taak
- Composer Mode effectief gebruiken voor multi-file features
- @ mentions strategisch inzetten voor context
- Geavanceerde .cursorrules files schrijven
- Codebase indexing optimaliseren
- Token gebruik monitoren en kosten beheren
- AI-assisted debugging toepassen
- Refactoring uitvoeren met Cursor

View File

@@ -1,187 +1,332 @@
# Les 17: Eindopdracht Kickoff
# Les 17: Vercel AI SDK - AI Features in je App
---
## Hoofdstuk
**Hoofdstuk 3: Advanced** (Les 10-18)
**Deel 4: Advanced AI Features** (Les 13-18)
## Beschrijving
Bespreking van de eindopdracht requirements, planning maken, en laatste vragen beantwoorden voordat studenten zelfstandig verder werken.
Bouw AI-powered features in je apps met de Vercel AI SDK. Leer hoe je chat interfaces, streaming responses en AI-gegenereerde content implementeert.
---
## Te Behandelen
### Eindopdracht Overview
### Groepsdiscussie (15 min)
Bespreek klassikaal de Cursor .cursorrules ervaringen uit Les 16 - welke regels zorgen voor betere AI output?
**Wat is de eindopdracht?**
- Bouw een AI-powered web applicatie
- Gebruik alle tools die je hebt geleerd
- Vrije keuze in implementatie
### Waarom Vercel AI SDK?
**Drie voorbeeldprojecten:**
1. **AI Recipe Generator** - Recepten op basis van ingrediënten
2. **Smart Budget Buddy** - Financieel overzicht met AI insights
3. **Travel Planner AI** - Reisplanning met AI suggesties
**Het probleem:** Direct API calls naar OpenAI/Anthropic zijn complex:
- Streaming handmatig implementeren
- Error handling
- State management
**Of:** Eigen idee (met goedkeuring docent)
**De oplossing:** Vercel AI SDK
- Simpele React hooks
- Built-in streaming
- Provider-agnostic (OpenAI, Anthropic, etc.)
- Edge-ready
---
### Requirements Doorlopen
### Installatie & Setup
**Technische vereisten:**
- Next.js 14 met App Router
- TypeScript
- Tailwind CSS
- Supabase (database + auth)
- Vercel AI SDK (chat of completion feature)
- Deployed op Vercel
```bash
npm install ai @ai-sdk/openai
# of voor Anthropic:
npm install ai @ai-sdk/anthropic
```
**Documentatie vereisten:**
- `docs/PROJECT-BRIEF.md` - Project beschrijving
- `docs/PROMPT-LOG.md` - Minimaal 10 prompts
- `docs/AI-DECISIONS.md` - Minimaal 5 beslissingen
- Complete README met setup instructies
**Environment variable:**
```bash
# .env.local
OPENAI_API_KEY=sk-xxxxx
```
---
### Beoordelingscriteria
### Core Hooks
| Criterium | Weging |
|-----------|--------|
| Technische uitvoering | 40% |
| AI integratie | 25% |
| Documentatie (PROMPT-LOG, AI-DECISIONS) | 20% |
| Code kwaliteit & organisatie | 15% |
#### useChat - Voor Conversaties
**Minimale vereisten:**
- App werkt in productie
- Auth + CRUD werkt
- AI feature werkt
- Documentatie compleet
```tsx
'use client'
import { useChat } from 'ai/react'
export function ChatComponent() {
const { messages, input, handleInputChange, handleSubmit, isLoading } = useChat()
return (
<div className="flex flex-col h-screen">
<div className="flex-1 overflow-y-auto p-4">
{messages.map(m => (
<div key={m.id} className={m.role === 'user' ? 'text-right' : 'text-left'}>
<span className="inline-block p-2 rounded-lg bg-gray-100">
{m.content}
</span>
</div>
))}
</div>
<form onSubmit={handleSubmit} className="p-4 border-t">
<input
value={input}
onChange={handleInputChange}
placeholder="Type a message..."
className="w-full p-2 border rounded"
/>
<button type="submit" disabled={isLoading}>
{isLoading ? 'Sending...' : 'Send'}
</button>
</form>
</div>
)
}
```
#### useCompletion - Voor Single Completions
```tsx
import { useCompletion } from 'ai/react'
export function SummaryComponent() {
const { completion, input, handleInputChange, handleSubmit, isLoading } = useCompletion()
return (
<div>
<form onSubmit={handleSubmit}>
<textarea
value={input}
onChange={handleInputChange}
placeholder="Paste text to summarize..."
/>
<button type="submit">Summarize</button>
</form>
{completion && <p>{completion}</p>}
</div>
)
}
```
---
### Timeline
### API Routes
**Nu tot deadline:**
- Les 17: Kickoff, planning maken
- Les 18: Werksessie met docent support
- Daarna: Zelfstandig afronden
**app/api/chat/route.ts:**
```typescript
import { openai } from '@ai-sdk/openai'
import { streamText } from 'ai'
**Tips:**
- Focus eerst op werkende MVP
- Dan pas polish
- Documenteer TIJDENS het bouwen
export async function POST(req: Request) {
const { messages } = await req.json()
const result = streamText({
model: openai('gpt-4o-mini'),
system: 'You are a helpful cooking assistant. Suggest recipes based on ingredients.',
messages,
})
return result.toDataStreamResponse()
}
```
**Met custom system prompt:**
```typescript
const result = streamText({
model: openai('gpt-4o-mini'),
system: `You are a recipe assistant for the AI Recipe Generator app.
When the user provides ingredients:
1. Suggest 2-3 recipes they could make
2. List required additional ingredients (if any)
3. Provide brief cooking instructions
Be concise and practical.`,
messages,
})
```
---
### Veel Voorkomende Vragen
### Streaming Responses
**Q: Mag ik een ander project doen dan de voorbeelden?**
A: Ja, met goedkeuring. Bespreek je idee met de docent.
**Waarom streaming?**
- Betere UX (user ziet direct resultaat)
- Snellere perceived performance
- Geen wachten op complete response
**Q: Moet ik alle AI tools gebruiken?**
A: Je moet minimaal Cursor en Vercel AI SDK gebruiken. De rest is optioneel.
**Hoe het werkt:**
1. Server stuurt tokens één voor één
2. Client rendert elke token direct
3. User ziet "typing" effect
**Q: Wat als ik vastloop?**
A: Documenteer het probleem in PROMPT-LOG, vraag hulp in Les 18.
**Q: Hoeveel prompts moet ik loggen?**
A: Minimaal 10, maar meer is beter. Focus op prompts waarvan je iets leerde.
**Loading indicator:**
```tsx
{isLoading && (
<div className="flex items-center gap-2">
<div className="animate-pulse"></div>
<span>AI is thinking...</span>
</div>
)}
```
---
### Planning Maken
### Integratie met Supabase
**Wat moet je nog doen?**
**Conversations opslaan:**
Maak checklist:
- [ ] Core features compleet
- [ ] AI feature werkt
- [ ] Auth werkt
- [ ] Design afgewerkt
- [ ] Edge cases gehandled
- [ ] Documentatie compleet
- [ ] Deployed en getest
```typescript
// Maak tabel in Supabase:
// conversations: id, user_id, created_at
// messages: id, conversation_id, role, content, created_at
**Prioriteer:**
1. Wat werkt nog niet?
2. Wat is kritiek vs nice-to-have?
3. Hoeveel tijd heb je?
// Na elke message:
async function saveMessage(conversationId: string, role: string, content: string) {
await supabase.from('messages').insert({
conversation_id: conversationId,
role,
content
})
}
```
**In je component:**
```tsx
const { messages, input, handleSubmit } = useChat({
onFinish: async (message) => {
await saveMessage(conversationId, message.role, message.content)
}
})
```
---
### Error Handling
```tsx
const { messages, error, reload } = useChat()
{error && (
<div className="p-4 bg-red-100 text-red-700 rounded">
<p>Something went wrong. Please try again.</p>
<button onClick={reload}>Retry</button>
</div>
)}
```
---
### Cost Management
**Model keuze:**
| Model | Kosten | Gebruik voor |
|-------|--------|--------------|
| gpt-4o-mini | Goedkoop | Meeste taken |
| gpt-4o | Duur | Complexe reasoning |
| claude-3-haiku | Goedkoop | Simpele taken |
| claude-3-sonnet | Medium | Balans |
**Bespaartips:**
1. Gebruik gpt-4o-mini als default
2. Korte system prompts
3. Beperk conversation history
4. Caching waar mogelijk
---
## Tools
- Vercel AI SDK (`ai` package)
- Next.js API Routes
- OpenAI API / Anthropic API
- Cursor
- Alle geleerde tools
- Supabase
---
## Lesopdracht (2 uur)
### Plan Je Afronding
### Bouw een AI Chat Component
**Deel 1: Status Check (30 min)**
**Deel 1: Setup (20 min)**
1. `npm install ai @ai-sdk/openai`
2. Voeg `OPENAI_API_KEY` toe aan `.env.local`
3. Maak `app/api/chat/route.ts`
Beantwoord voor jezelf:
1. Welke features werken al?
2. Welke features missen nog?
3. Wat is je grootste blocker?
4. Hoe staat je documentatie ervoor?
**Deel 2: Basic Chat (40 min)**
1. Maak `components/Chat.tsx`
2. Implementeer `useChat` hook
3. Bouw chat UI met Tailwind
4. Test streaming werkt
Maak een eerlijke inschatting.
**Deel 3: System Prompt (30 min)**
1. Schrijf system prompt voor je eindproject:
- Recipe Generator: cooking assistant
- Budget Buddy: financial advisor
- Travel Planner: travel expert
2. Test met relevante vragen
**Deel 2: Planning Maken (30 min)**
Maak gedetailleerde planning:
- Wat doe je vandaag?
- Wat doe je in Les 18?
- Wat doe je thuis?
- Wanneer ben je klaar?
**Deel 3: Begin Met Hoogste Prioriteit (1 uur)**
Start met de belangrijkste ontbrekende onderdelen:
- Werkt je AI feature? → Prioriteit 1
- Werkt auth? → Prioriteit 2
- Is het deployed? → Prioriteit 3
Vraag hulp als je vastloopt!
**Deel 4: Supabase Integratie (30 min)**
1. Maak `messages` tabel
2. Sla berichten op met `onFinish`
3. Laad history bij page load
### Deliverable
- Statusoverzicht: wat werkt, wat niet
- Planning voor afronden
- Voortgang op hoogste prioriteit
- Werkende AI chat met streaming
- Custom system prompt
- Messages opgeslagen in Supabase
---
## Huiswerk
## Huiswerk (2 uur)
### Werk aan je Eindopdracht
### Bouw AI Feature voor Eindproject
**Dit is geen nieuw huiswerk - gebruik deze tijd om je eindopdracht af te ronden.**
**Deel 1: Core AI Feature (1 uur)**
Focus op:
1. Features compleet maken
2. Bugs fixen
3. Documentatie bijwerken
4. Testen in productie
Implementeer de AI chat die past bij je eindproject:
**Bereid vragen voor:**
Schrijf op waar je hulp bij nodig hebt voor Les 18 (werksessie).
| Project | AI Feature |
|---------|-----------|
| Recipe Generator | "Wat kan ik maken met kip en rijst?" |
| Budget Buddy | "Analyseer mijn uitgaven deze maand" |
| Travel Planner | "Plan een weekend Barcelona" |
- Custom system prompt
- Context uit je database meegeven
**Deel 2: UX Polish (30 min)**
Voeg toe:
- Streaming indicator
- Suggested prompts / quick actions
- Copy response button
- Clear chat button
- Error handling
**Deel 3: Documentatie (30 min)**
Maak `docs/AI-FEATURE.md`:
- Welke AI feature heb je gebouwd?
- Wat doet de system prompt?
- Hoe integreert het met Supabase?
- Welke model keuzes heb je gemaakt?
### Deliverable
- Voortgang op eindopdracht
- Lijst met vragen voor Les 18
- AI feature in eindproject
- Deployed preview
- AI-FEATURE.md documentatie
---
## Leerdoelen
Na deze les kan de student:
- De eindopdracht requirements begrijpen
- Een realistische planning maken
- Prioriteiten stellen voor afronden
- Eigen voortgang eerlijk inschatten
- Hulp vragen waar nodig
- Vercel AI SDK installeren en configureren
- `useChat` en `useCompletion` hooks gebruiken
- Streaming responses implementeren
- API routes opzetten voor AI providers
- Custom system prompts schrijven
- Chat history opslaan in Supabase
- Error handling en loading states implementeren
- Kostenbewust omgaan met AI APIs

View File

@@ -1,152 +1,276 @@
# Les 18: Eindproject Werksessie
# Les 18: Deployment & Production + Eindopdracht
---
## Hoofdstuk
**Hoofdstuk 3: Advanced** (Les 10-18)
**Deel 4: Advanced AI Features** (Les 13-18)
## Beschrijving
Werksessie voor het afronden van je eindproject. Geen nieuwe theorie - focus op bouwen, vragen stellen, en hulp krijgen.
Deploy je eindproject naar productie. Leer environment variables, Vercel deployment, en basis performance optimalisatie. Bespreking van de eindopdracht requirements en afrondende werksessie.
---
## Opzet van de Les
## Te Behandelen
### Korte Standup (15 min)
### Groepsdiscussie (15 min)
Bespreek klassikaal de AI feature ervaringen uit Les 17 - welke system prompts werkten goed en welke challenges kwamen jullie tegen?
**Elke student deelt (max 1 minuut):**
1. Waar sta ik?
2. Wat is mijn grootste blocker?
3. Wat wil ik vandaag afronden?
### Vercel Deployment Flow
### Werktijd (1u 45min)
**Hoe Vercel werkt:**
1. Connect GitHub repository
2. Push naar main → automatische deploy
3. Push naar andere branch → preview URL
4. Alles automatisch (build, SSL, CDN)
**Studenten werken zelfstandig:**
- Docent loopt rond
- Vraag hulp wanneer nodig
- Peer support aangemoedigd
**Focus gebieden:**
- Features afronden
- Bugs fixen
- Documentatie completeren
- Deployment issues oplossen
**Waarom Vercel voor Next.js:**
- Gemaakt door dezelfde makers
- Zero-config deployment
- Gratis tier ruim voldoende
- Automatische HTTPS
- Global CDN
---
## Veelvoorkomende Problemen
### Environment Variables in Vercel
### AI Chat Werkt Niet
**Lokaal (.env.local) vs Productie (Vercel Dashboard):**
**Check:**
| Waar | Bestand/Locatie | Voorbeeld |
|------|-----------------|-----------|
| Lokaal | `.env.local` | Development |
| Vercel | Dashboard → Settings → Env Vars | Production |
**Stap voor stap:**
1. Ga naar je Vercel project
2. Settings → Environment Variables
3. Voeg toe:
- `NEXT_PUBLIC_SUPABASE_URL`
- `NEXT_PUBLIC_SUPABASE_ANON_KEY`
- `OPENAI_API_KEY`
4. Selecteer environment (Production, Preview, Development)
5. Save & Redeploy
**Let op:**
- `NEXT_PUBLIC_` prefix = zichtbaar in browser
- Zonder prefix = alleen server-side (API routes)
---
### Supabase Productie Setup
**Redirect URLs configureren:**
1. Ga naar Supabase → Authentication → URL Configuration
2. Voeg toe bij "Redirect URLs":
- `https://jouw-app.vercel.app/**`
- `https://jouw-app.vercel.app`
**Waarom:**
- Auth redirects werken alleen naar toegestane URLs
- Wildcards (`**`) voor sub-routes
---
### Deployment Checklist
**Voor deployment:**
- [ ] `npm run build` werkt lokaal
- [ ] Geen TypeScript errors
- [ ] Environment variables gedocumenteerd in `.env.example`
- [ ] `.gitignore` bevat `.env*.local`
- [ ] README up-to-date
**Na deployment:**
- [ ] App laadt correct
- [ ] Auth werkt (login/logout)
- [ ] Data wordt opgehaald uit Supabase
- [ ] AI features werken (indien van toepassing)
- [ ] Geen console errors
---
### Performance Basics
**Lighthouse Audit:**
1. Open Chrome DevTools
2. Tab "Lighthouse"
3. Klik "Analyze page load"
4. Aim for score >80 in elke categorie
**Quick wins:**
- Gebruik Next.js `Image` component (niet `<img>`)
- Lazy load components die niet direct nodig zijn
- Verwijder ongebruikte dependencies
---
### Security Checklist
**Belangrijk voor productie:**
- [ ] API keys nooit in client-side code
- [ ] Supabase RLS enabled (Row Level Security)
- [ ] Error messages geven geen gevoelige info
- [ ] HTTPS (automatisch via Vercel)
---
## Eindopdracht Overview
### Wat is de eindopdracht?
- Bouw een AI-powered web applicatie
- Gebruik alle tools die je hebt geleerd
- Vrije keuze in implementatie
**Drie voorbeeldprojecten:**
1. **AI Recipe Generator** - Recepten op basis van ingrediënten
2. **Smart Budget Buddy** - Financieel overzicht met AI insights
3. **Travel Planner AI** - Reisplanning met AI suggesties
**Of:** Eigen idee (met goedkeuring docent)
---
### Technische Vereisten
**Stack:**
- Next.js 14 met App Router
- TypeScript
- Tailwind CSS
- Supabase (database + auth)
- Vercel AI SDK (chat of completion feature)
- Deployed op Vercel
**Documentatie vereisten:**
- `docs/PROJECT-BRIEF.md` - Project beschrijving
- `docs/PROMPT-LOG.md` - Minimaal 10 prompts
- `docs/AI-DECISIONS.md` - Minimaal 5 beslissingen
- Complete README met setup instructies
---
### Beoordelingscriteria
| Criterium | Weging |
|-----------|--------|
| Technische uitvoering | 40% |
| AI integratie | 25% |
| Documentatie (PROMPT-LOG, AI-DECISIONS) | 20% |
| Code kwaliteit & organisatie | 15% |
**Minimale vereisten:**
- App werkt in productie
- Auth + CRUD werkt
- AI feature werkt
- Documentatie compleet
---
### Veelvoorkomende Problemen
**AI Chat Werkt Niet:**
1. API key correct in `.env.local`?
2. API key ook in Vercel env vars?
3. Correct model gekozen?
4. API route syntax correct?
### Auth Werkt Niet in Productie
**Check:**
**Auth Werkt Niet in Productie:**
1. Redirect URLs in Supabase toegevoegd?
2. Beide URLs: met en zonder trailing slash?
3. Wildcard (`**`) voor sub-routes?
### Deployment Faalt
**Check:**
**Deployment Faalt:**
1. `npm run build` lokaal succesvol?
2. Alle TypeScript errors gefixed?
3. Alle env vars in Vercel?
### Supabase Data Toont Niet
**Check:**
1. RLS policies correct?
2. Correct env vars?
3. Supabase client correct geïnitialiseerd?
---
## Documentatie Checklist
**PROMPT-LOG.md (minimaal 10 entries):**
- [ ] Prompts die goed werkten
- [ ] Prompts die NIET werkten (en wat je leerde)
- [ ] Verschillende tools gebruikt
**AI-DECISIONS.md (minimaal 5 entries):**
- [ ] Database schema beslissing
- [ ] UI/UX keuzes
- [ ] Technische trade-offs
- [ ] Problemen en oplossingen
**README.md:**
- [ ] Project beschrijving
- [ ] Features lijst
- [ ] Tech stack
- [ ] Setup instructies
- [ ] Productie URL
---
## Peer Review (optioneel)
**Als je klaar bent, help een klasgenoot:**
1. Test hun app
2. Geef feedback
3. Help met bugs
---
## Afsluiting (laatste 10 min)
**Check-out:**
- Wie is klaar?
- Wie heeft nog vragen?
- Deadline reminder
---
## Tools
- Vercel
- GitHub
- Supabase
- Chrome DevTools (Lighthouse)
- Cursor
- Alle geleerde tools
- Elkaar!
---
## Lesopdracht (2 uur)
### Werk aan je Eindproject
### Deploy Je Eindproject
**Dit is WERKTIJD.**
**Deel 1: Pre-Deployment Check (30 min)**
Er is geen specifieke opdracht behalve: werk aan je eindproject.
Run door de checklist:
1. `npm run build` - fix eventuele errors
2. Check TypeScript errors
3. Maak/update `.env.example`
4. Update README met project info
**Prioriteiten:**
1. ❌ Wat werkt nog niet? → Fix het
2. ✅ Wat werkt al? → Maak het af
3. 📝 Documentatie → Vul aan
**Deel 2: Vercel Deployment (30 min)**
**Vraag hulp:**
- Als je langer dan 15 minuten vastloopt
- Als je niet weet waar te beginnen
- Als je feedback wilt op je aanpak
1. Ga naar [vercel.com](https://vercel.com)
2. "Add New Project"
3. Import je GitHub repository
4. Voeg environment variables toe
5. Deploy!
**Aan het eind van de les:**
- App werkt in productie
- Of: je weet precies wat nog moet gebeuren
**Deel 3: Supabase Config (20 min)**
1. Voeg Vercel URL toe aan Supabase redirect URLs
2. Test auth in productie
3. Verifieer data access
**Deel 4: Testing & Lighthouse (40 min)**
1. Test alle features in productie:
- Login/logout
- CRUD operaties
- AI chat (indien aanwezig)
2. Run Lighthouse audit
3. Fix issues tot score >80
4. Screenshot resultaat
### Deliverable
- Voortgang op eindproject
- Duidelijk beeld van wat nog moet
- Werkende productie URL
- Lighthouse screenshot (score >80)
- Test rapport: wat werkt, wat niet
---
## Huiswerk
## Huiswerk (Eindopdracht Afronden)
### Rond Je Eindproject Af
**Dit is de laatste les. Alles wat nog moet, doe je zelfstandig.**
**Dit is de laatste les. Gebruik deze tijd om je eindopdracht af te ronden.**
**Deel 1: Bug Fixes (1 uur)**
1. Test je app grondig in productie
2. Fix gevonden bugs
3. Test edge cases:
- Lege states
- Error states
- Loading states
4. Redeploy
**Deel 2: Performance Optimization (30 min)**
1. Run Lighthouse opnieuw
2. Fix top 3 performance issues
3. Document wat je hebt verbeterd
**Deel 3: Documentatie Afronden (30 min)**
Update je `README.md`:
- Werkende productie URL
- Features lijst
- Tech stack
- Setup instructies
- Screenshots
Complete `docs/`:
- PROMPT-LOG.md (minimaal 10 entries)
- AI-DECISIONS.md (minimaal 5 entries)
**Checklist voor inleveren:**
- [ ] App werkt op productie URL
@@ -165,14 +289,20 @@ Er is geen specifieke opdracht behalve: werk aan je eindproject.
### Deliverable
- Complete eindopdracht
- Deployed en werkend
- Alle documentatie compleet
- Ingeleverd voor deadline
---
## Leerdoelen
Na deze les kan de student:
- Zelfstandig problemen oplossen
- Hulp vragen wanneer nodig
- Een Next.js app deployen naar Vercel
- Environment variables configureren in Vercel
- Supabase redirect URLs instellen voor productie
- Een deployment checklist doorlopen
- Lighthouse gebruiken voor performance audit
- Basis security checks uitvoeren
- De eindopdracht requirements begrijpen
- Een project afronden en inleveren
- Documentatie completeren
- Peer feedback geven en ontvangen
- Documentatie voltooien volgens de vereisten

524
readme.md
View File

@@ -2,7 +2,7 @@
Een 18-weekse cursus die studenten meeneemt van AI-beginner naar AI-powered developer.
**Totaal: 30 EC** verdeeld over 3 delen.
**Totaal: 30 EC** verdeeld over 4 delen.
---
@@ -13,39 +13,40 @@ Een 18-weekse cursus die studenten meeneemt van AI-beginner naar AI-powered deve
| 01 | [Introductie tot AI en Large Language Models](Samenvattingen/Les01-Samenvatting.md) | 1 | ✅ Uitgewerkt |
| 02 | [AI Code Assistants en OpenCode Desktop App](Samenvattingen/Les02-Samenvatting.md) | 1 | 📋 Samenvatting |
| 03 | [AI Ethics, Privacy & Security + WebStorm](Samenvattingen/Les03-Samenvatting.md) | 1 | 📋 Samenvatting |
| 04 | [Effectief Prompting, Iteratief Werken & Skills](Samenvattingen/Les04-Samenvatting.md) | 2 | 📋 Samenvatting |
| 05 | [AI Tool Selection & Workflows](Samenvattingen/Les05-Samenvatting.md) | 2 | 📋 Samenvatting |
| 06 | [Hands-on: Van Idee naar Prototype](Samenvattingen/Les06-Samenvatting.md) | 2 | 📋 Samenvatting |
| 07 | [Next.js Project Setup](Samenvattingen/Les07-Samenvatting.md) | 2 | 📋 Samenvatting |
| 08 | [Supabase Basics](Samenvattingen/Les08-Samenvatting.md) | 2 | 📋 Samenvatting |
| 09 | [AI Agents - Custom GPTs & Claude Projects](Samenvattingen/Les09-Samenvatting.md) | 2 | 📋 Samenvatting |
| 10 | [Introduction to Cursor](Samenvattingen/Les10-Samenvatting.md) | 3 | 📋 Samenvatting |
| 11 | [Project Setup & Repository Structure](Samenvattingen/Les11-Samenvatting.md) | 3 | 📋 Samenvatting |
| 12 | [MCP & Context Management](Samenvattingen/Les12-Samenvatting.md) | 3 | 📋 Samenvatting |
| 13 | [Mastering Cursor](Samenvattingen/Les13-Samenvatting.md) | 3 | 📋 Samenvatting |
| 14 | [Debugging & Code Review met AI](Samenvattingen/Les14-Samenvatting.md) | 3 | 📋 Samenvatting |
| 15 | [Vercel AI SDK - AI Features in je App](Samenvattingen/Les15-Samenvatting.md) | 3 | 📋 Samenvatting |
| 16 | [Deployment & Production](Samenvattingen/Les16-Samenvatting.md) | 3 | 📋 Samenvatting |
| 17 | [Eindopdracht Kickoff](Samenvattingen/Les17-Samenvatting.md) | 3 | 📋 Samenvatting |
| 18 | [Eindproject Werksessie](Samenvattingen/Les18-Samenvatting.md) | 3 | 📋 Samenvatting |
| 04 | [Effectief Prompting, Iteratief Werken & Skills](Samenvattingen/Les04-Samenvatting.md) | 1 | 📋 Samenvatting |
| 05 | [TypeScript Basics](Samenvattingen/Les05-Samenvatting.md) | 2 | 📋 Samenvatting |
| 06 | [Next.js Fundamentals 1: SSR & Routing](Samenvattingen/Les06-Samenvatting.md) | 2 | 📋 Samenvatting |
| 07 | [Next.js Fundamentals 2: API Routes & Data Fetching](Samenvattingen/Les07-Samenvatting.md) | 2 | 📋 Samenvatting |
| 08 | [Database Principles](Samenvattingen/Les08-Samenvatting.md) | 2 | 📋 Samenvatting |
| 09 | [Supabase Basics](Samenvattingen/Les09-Samenvatting.md) | 2 | 📋 Samenvatting |
| 10 | [AI Tool Selection & Workflows](Samenvattingen/Les10-Samenvatting.md) | 3 | 📋 Samenvatting |
| 11 | [Hands-on: Van Idee naar Prototype](Samenvattingen/Les11-Samenvatting.md) | 3 | 📋 Samenvatting |
| 12 | [Introduction to Cursor](Samenvattingen/Les12-Samenvatting.md) | 3 | 📋 Samenvatting |
| 13 | [AI Agents - Custom GPTs & Claude Projects](Samenvattingen/Les13-Samenvatting.md) | 4 | 📋 Samenvatting |
| 14 | [Project Setup & Repository Structure](Samenvattingen/Les14-Samenvatting.md) | 4 | 📋 Samenvatting |
| 15 | [MCP & Context Management](Samenvattingen/Les15-Samenvatting.md) | 4 | 📋 Samenvatting |
| 16 | [Mastering Cursor](Samenvattingen/Les16-Samenvatting.md) | 4 | 📋 Samenvatting |
| 17 | [Vercel AI SDK - AI Features in je App](Samenvattingen/Les17-Samenvatting.md) | 4 | 📋 Samenvatting |
| 18 | [Deployment & Production](Samenvattingen/Les18-Samenvatting.md) | 4 | 📋 Samenvatting |
---
## Tool Progressie
| Deel | Tools | Kosten |
|------|-------|--------|
| Deel 1 | ChatGPT, v0.dev, OpenCode, WebStorm | Gratis (WebStorm via school) |
| Deel 2 | OpenCode, Claude Desktop, Skills.sh | Gratis |
| Deel 3 | Cursor | Free tier beschikbaar |
| Deel | Lessen | Tools | Kosten |
|------|--------|-------|--------|
| Deel 1: AI Foundations | 1-4 | ChatGPT, v0.dev, OpenCode, WebStorm | Gratis (WebStorm via school) |
| Deel 2: Technical Foundations | 5-9 | TypeScript, Next.js, React Query, Supabase | Gratis |
| Deel 3: AI Tooling & Prototyping | 10-12 | ChatGPT, Claude, v0.dev, OpenCode, Cursor | Free tier beschikbaar |
| Deel 4: Advanced AI Features | 13-18 | Cursor, Claude Projects, Custom GPTs, Vercel AI SDK | Free tier beschikbaar |
**Eindopdracht:** Cursor (free tier voldoende)
---
# Deel 1: Fundamentals of AI-Driven Development
# Deel 1: AI Foundations
**3 lessen · 5 EC**
**4 lessen · 5 EC**
Kennismaking met AI, LLMs en de basis van AI-assisted development.
@@ -94,7 +95,10 @@ Kennismaking met AI, LLMs en de basis van AI-assisted development.
**Lesopdracht:** Installeer OpenCode, koppel gratis model, bouw responsive navbar component met AI assistance, experimenteer met verschillende prompts.
**Huiswerk:** Bouw landing page component library (hero, features, testimonial, CTA, footer), schrijf blog post over ervaring met OpenCode (300 woorden).
**Huiswerk:**
- Bouw landing page component library (hero, features, testimonial, CTA, footer)
- Schrijf blog post over ervaring met OpenCode (300 woorden)
- **Optioneel:** Heb je het gevoel dat je React-kennis wat is weggezakt? Gebruik de eerste twee weken ook om React Fundamentals op EdHub te herhalen.
[→ Ga naar Les 2](Samenvattingen/Les02-Samenvatting.md)
@@ -112,6 +116,7 @@ Kennismaking met AI, LLMs en de basis van AI-assisted development.
- WebStorm als professionele IDE
**Studenten doen:**
- **Groepsdiscussie:** Bespreek klassikaal de reflecties over AI van Les 1 - wat zijn de voor- en nadelen die jullie zien?
- Security workshop: identificeer problemen in AI-generated code
- Maak persoonlijke "AI Safety Checklist"
- WebStorm installeren met school licentie
@@ -125,16 +130,6 @@ Kennismaking met AI, LLMs en de basis van AI-assisted development.
---
# Deel 2: Intermediate AI-Driven Development
**6 lessen · 10 EC**
Verdieping in prompt engineering, hands-on bouwen, en introductie tot Supabase en AI agents.
---
## 2.1 Prompt Engineering & Consolidatie
### Les 4: Effectief Prompting, Iteratief Werken & Skills
**Tools:** OpenCode/WebStorm, Skills.sh
@@ -147,6 +142,7 @@ Verdieping in prompt engineering, hands-on bouwen, en introductie tot Supabase e
- Iteratief werken: start simpel → voeg complexiteit toe
**Studenten doen:**
- **Groepsdiscussie:** Bespreek klassikaal ervaringen met OpenCode - wat werkte, wat niet?
- Verschillende prompt technieken uitproberen
- Skills.sh installeren en eerste skill toevoegen
- Vergelijk output met/zonder skill
@@ -160,7 +156,191 @@ Verdieping in prompt engineering, hands-on bouwen, en introductie tot Supabase e
---
### Les 5: AI Tool Selection & Workflows
# Deel 2: Technical Foundations
**5 lessen · 10 EC**
Stevige technische basis: TypeScript, Next.js, databases en Supabase.
---
### Les 5: TypeScript Basics
**Tools:** OpenCode/WebStorm, TypeScript
**Docent vertelt:**
- Waarom TypeScript? Voordelen boven JavaScript
- Basic types: string, number, boolean, array, object
- Type inference: wanneer TypeScript types zelf raadt
- Interfaces en type aliases
- TypeScript met React: Props typen, useState met types
- Generics basics (Array<T>, Promise<T>)
- Veel voorkomende TypeScript errors en hoe ze op te lossen
**Studenten doen:**
- JavaScript file omzetten naar TypeScript
- Interfaces schrijven voor eigen data
- React component met typed props maken
- TypeScript errors debuggen
**Lesopdracht:**
1. Zet bestaand JS component om naar TypeScript
2. Maak interface voor User en Product data
3. Bouw typed React component met props
4. Fix 5 TypeScript errors in gegeven code
**Huiswerk:** Maak 3 nieuwe components volledig in TypeScript, schrijf interfaces voor je eindproject data, maak cheat sheet met TypeScript patterns.
[→ Ga naar Les 5](Samenvattingen/Les05-Samenvatting.md)
---
### Les 6: Next.js Fundamentals 1 - SSR & Routing
**Tools:** Next.js 14, OpenCode/WebStorm, Vercel
**Docent vertelt:**
- Wat is Next.js? React framework met superpowers
- Server-Side Rendering (SSR) vs Client-Side Rendering (CSR)
- Waarom SSR? SEO, performance, initial load
- App Router: file-based routing uitgelegd
- Folder structuur: app/, pages, layouts, loading, error
- Dynamic routes: [id], [...slug], [[...optional]]
- Link component en navigation
- Metadata en SEO basics
**Studenten doen:**
- Next.js project aanmaken met `npx create-next-app@latest`
- Pagina's maken met App Router
- Layout en nested layouts implementeren
- Dynamic routes bouwen
- Navigation met Link component
**Lesopdracht:**
1. `npx create-next-app@latest` met TypeScript + Tailwind + App Router
2. Maak 4 pagina's: home, about, products, contact
3. Maak root layout met Header en Footer
4. Maak `/products/[id]` dynamic route
5. Deploy naar Vercel
**Huiswerk:** Voeg nested layout toe voor products section, maak loading.tsx en error.tsx, experimenteer met metadata.
[→ Ga naar Les 6](Samenvattingen/Les06-Samenvatting.md)
---
### Les 7: Next.js Fundamentals 2 - API Routes & Data Fetching
**Tools:** Next.js 14, React Query (TanStack Query), OpenCode
**Docent vertelt:**
- Server Components vs Client Components
- 'use client' directive: wanneer en waarom
- Data fetching in Server Components (async/await)
- API Routes: Route Handlers in App Router
- GET, POST, PUT, DELETE requests
- React Query: waarom, installatie, basics
- useQuery en useMutation hooks
- Caching en revalidation basics
**Studenten doen:**
- Server Component met data fetching maken
- API route schrijven
- Client Component met React Query
- CRUD operations via API routes
**Lesopdracht:**
1. Maak `/api/products` route met GET en POST
2. Bouw Server Component die products fetcht
3. Installeer React Query, maak QueryClientProvider
4. Bouw Client Component met useQuery
5. Implementeer useMutation voor product toevoegen
**Huiswerk:** Voeg PUT en DELETE toe aan API, implementeer optimistic updates met React Query, bouw complete CRUD interface.
[→ Ga naar Les 7](Samenvattingen/Les07-Samenvatting.md)
---
### Les 8: Database Principles
**Tools:** Diagramming tool (draw.io/Excalidraw), Supabase (ter voorbereiding)
**Docent vertelt:**
- Wat is een relationele database?
- Tabellen, rijen (records), kolommen (fields)
- Primary Keys: unieke identificatie
- Foreign Keys: relaties tussen tabellen
- Relatie types: one-to-one, one-to-many, many-to-many
- Normalisatie basics: waarom data niet dupliceren
- Data types: text, integer, boolean, timestamp, uuid
- NULL values en defaults
- Indexen: waarom en wanneer
**Studenten doen:**
- Database schema tekenen voor simpel project
- Relaties identificeren en documenteren
- Normalisatie oefening: slechte structuur verbeteren
- Primary en Foreign Keys bepalen
**Lesopdracht:**
1. Teken database schema voor "Blog met Comments" (users, posts, comments)
2. Identificeer alle relaties en key types
3. Normaliseer een "slechte" database structuur (gegeven)
4. Schrijf data types en constraints op
5. Bereid voor: welke tabellen heeft jouw eindproject nodig?
**Huiswerk:** Maak volledig database schema voor je eindproject, documenteer alle relaties, bereid Supabase account aan voor volgende les.
[→ Ga naar Les 8](Samenvattingen/Les08-Samenvatting.md)
---
### Les 9: Supabase Basics
**Tools:** Supabase, Next.js, OpenCode
**Docent vertelt:**
- Wat is Supabase? (database + auth in één)
- Supabase project aanmaken (live demo)
- Table Editor: tabellen maken zonder SQL
- Je database schema van vorige les implementeren
- Environment variables: wat, waarom, hoe
- Supabase client setup
- CRUD operaties uitgelegd
- Auth UI component (plug & play login)
**Studenten doen:**
- **Groepsdiscussie:** Bespreek database schemas - wie heeft welke structuur gekozen en waarom?
- Supabase account en project aanmaken
- Tabellen maken via UI (gebaseerd op Les 8 schema)
- `.env.local` configureren
- Supabase client maken
- Data ophalen en tonen
- Auth toevoegen
**Lesopdracht:**
1. Maak Supabase project
2. Maak je tabellen via Table Editor (uit Les 8)
3. Configureer `.env.local`
4. Bouw Todo app: lijst tonen, toevoegen, afvinken, verwijderen
5. Voeg login toe met Auth UI
**Huiswerk:** Extend Todo app (filtering, user-specifieke todos), deploy naar Vercel met env vars, test in productie.
[→ Ga naar Les 9](Samenvattingen/Les09-Samenvatting.md)
---
# Deel 3: AI Tooling & Prototyping
**3 lessen · 5 EC**
AI tools effectief inzetten voor professionele development.
---
### Les 10: AI Tool Selection & Workflows
**Tools:** ChatGPT, Claude, v0.dev, OpenCode
@@ -188,11 +368,11 @@ Verdieping in prompt engineering, hands-on bouwen, en introductie tot Supabase e
**Huiswerk:** Maak je eigen "Tool Selection Cheat Sheet", test het op 2 nieuwe taken, reflecteer op je workflow (400 woorden).
[→ Ga naar Les 5](Samenvattingen/Les05-Samenvatting.md)
[→ Ga naar Les 10](Samenvattingen/Les10-Samenvatting.md)
---
### Les 6: Hands-on: Van Idee naar Prototype
### Les 11: Hands-on: Van Idee naar Prototype
**Tools:** OpenCode/WebStorm, ChatGPT (voor planning)
@@ -204,6 +384,7 @@ Verdieping in prompt engineering, hands-on bouwen, en introductie tot Supabase e
- Korte demo van het proces
**Studenten doen:**
- **Groepsdiscussie:** Bespreek Tool Selection reflecties - welke workflows werken het beste?
- Kiezen van een simpel project idee
- Met AI features breakdown maken
- Component structuur bedenken
@@ -217,122 +398,13 @@ Verdieping in prompt engineering, hands-on bouwen, en introductie tot Supabase e
**Lesopdracht:** Kies een mini-project, maak feature breakdown met AI, bouw werkend prototype. Documenteer je proces: welke prompts werkten, waar liep je vast, hoe loste je het op.
**Huiswerk:** Verbeter je prototype (styling, edge cases), schrijf "Lessons Learned" document (300 woorden), bereid je voor op Les 7 (Next.js).
**Huiswerk:** Verbeter je prototype (styling, edge cases), schrijf "Lessons Learned" document (300 woorden).
[→ Ga naar Les 6](Samenvattingen/Les06-Samenvatting.md)
[→ Ga naar Les 11](Samenvattingen/Les11-Samenvatting.md)
---
## 2.2 Next.js & Supabase
### Les 7: Next.js Project Setup
**Tools:** Next.js, OpenCode/WebStorm, Git, Vercel
**Docent vertelt:**
- Wat is Next.js en waarom gebruiken we het?
- `npx create-next-app` stap voor stap
- Project structuur uitgelegd (app/, components/, lib/)
- TypeScript basics voor React
- Tailwind CSS in Next.js
- Git basics: commits, push, .gitignore
**Studenten doen:**
- Eerste Next.js project aanmaken
- Project structuur verkennen
- Simpele pagina's maken
- Components maken en importeren
- Deployen naar Vercel
**Lesopdracht:**
1. Run `npx create-next-app@latest` met TypeScript + Tailwind
2. Maak 3 pagina's (home, about, contact)
3. Maak 2 herbruikbare components (Header, Footer)
4. Style met Tailwind
5. Deploy naar Vercel
**Huiswerk:** Voeg 2 extra pagina's toe, maak 3 extra components, experimenteer met Tailwind, push alles naar GitHub.
[→ Ga naar Les 7](Samenvattingen/Les07-Samenvatting.md)
---
### Les 8: Supabase Basics
**Tools:** Supabase, Next.js, OpenCode
**Docent vertelt:**
- Wat is Supabase? (database + auth in één)
- Supabase project aanmaken (live demo)
- Table Editor: tabellen maken zonder SQL
- Environment variables: wat, waarom, hoe
- Supabase client setup
- CRUD operaties uitgelegd
- Auth UI component (plug & play login)
**Studenten doen:**
- Supabase account en project aanmaken
- Eerste tabel maken via UI
- `.env.local` configureren
- Supabase client maken
- Data ophalen en tonen
- Auth toevoegen
**Lesopdracht:**
1. Maak Supabase project
2. Maak `todos` tabel via Table Editor
3. Configureer `.env.local`
4. Bouw Todo app: lijst tonen, toevoegen, afvinken, verwijderen
5. Voeg login toe met Auth UI
**Huiswerk:** Extend Todo app (filtering, user-specifieke todos), deploy naar Vercel met env vars, test in productie.
[→ Ga naar Les 8](Samenvattingen/Les08-Samenvatting.md)
---
## 2.3 AI Agents
### Les 9: AI Agents - Custom GPTs & Claude Projects
**Tools:** ChatGPT (Custom GPTs), Claude Desktop (Projects)
**Docent vertelt:**
- Wat zijn AI Agents? Verschil chatbot vs agent
- Custom GPTs: hoe maak je ze, wat kun je ermee
- Claude Projects: custom instructions + project knowledge
- Wanneer een agent vs gewoon chatten
- Best practices voor agent instructions
**Studenten doen:**
- Custom GPT maken voor code review
- Claude Project opzetten voor eigen project
- Agents testen en vergelijken
- Instructions itereren en verbeteren
**Lesopdracht:**
1. Maak Custom GPT "Code Reviewer" met specifieke checklist
2. Maak Claude Project voor je Todo app met project context
3. Test beide met dezelfde code
4. Documenteer: welke geeft betere feedback?
**Huiswerk:** Maak "Personal Dev Assistant" agent afgestemd op jouw workflow, test in echt werk, deel je beste agent config met de klas.
[→ Ga naar Les 9](Samenvattingen/Les09-Samenvatting.md)
---
# Deel 3: Advanced AI-Driven Development
**9 lessen · 15 EC**
Cursor als professionele tool, MCP, debugging, AI features bouwen, en het eindproject.
---
## 3.1 Cursor & Professional Workflow
### Les 10: Introduction to Cursor
### Les 12: Introduction to Cursor
**Tools:** Cursor
@@ -360,11 +432,49 @@ Cursor als professionele tool, MCP, debugging, AI features bouwen, en het eindpr
**Huiswerk:** Bouw complete mini-feature met Cursor, vergelijk ervaring met OpenCode, schrijf reflectie (400 woorden).
[→ Ga naar Les 10](Samenvattingen/Les10-Samenvatting.md)
[→ Ga naar Les 12](Samenvattingen/Les12-Samenvatting.md)
---
### Les 11: Project Setup & Repository Structure
### Les 13: AI Agents - Custom GPTs & Claude Projects
**Tools:** ChatGPT (Custom GPTs), Claude Desktop (Projects)
**Docent vertelt:**
- Wat zijn AI Agents? Verschil chatbot vs agent
- Custom GPTs: hoe maak je ze, wat kun je ermee
- Claude Projects: custom instructions + project knowledge
- Wanneer een agent vs gewoon chatten
- Best practices voor agent instructions
**Studenten doen:**
- **Groepsdiscussie:** Bespreek Cursor reflecties - hoe verschilt het van OpenCode?
- Custom GPT maken voor code review
- Claude Project opzetten voor eigen project
- Agents testen en vergelijken
- Instructions itereren en verbeteren
**Lesopdracht:**
1. Maak Custom GPT "Code Reviewer" met specifieke checklist
2. Maak Claude Project voor je Todo app met project context
3. Test beide met dezelfde code
4. Documenteer: welke geeft betere feedback?
**Huiswerk:** Maak "Personal Dev Assistant" agent afgestemd op jouw workflow, test in echt werk, deel je beste agent config met de klas.
[→ Ga naar Les 13](Samenvattingen/Les13-Samenvatting.md)
---
# Deel 4: Advanced AI Features
**6 lessen · 10 EC**
Professionele workflows, advanced Cursor, AI features bouwen en deployment.
---
### Les 14: Project Setup & Repository Structure
**Tools:** Cursor, Git, GitHub
@@ -392,11 +502,11 @@ Cursor als professionele tool, MCP, debugging, AI features bouwen, en het eindpr
**Huiswerk:** Voeg extra .cursorrules files toe, start PROMPT-LOG.md, maak eerste components met Cursor.
[→ Ga naar Les 11](Samenvattingen/Les11-Samenvatting.md)
[→ Ga naar Les 14](Samenvattingen/Les14-Samenvatting.md)
---
### Les 12: MCP & Context Management
### Les 15: MCP & Context Management
**Tools:** Cursor, Claude Desktop, MCP servers
@@ -424,11 +534,11 @@ Cursor als professionele tool, MCP, debugging, AI features bouwen, en het eindpr
**Huiswerk:** Voeg extra MCP server toe (naar keuze), optimaliseer je project voor AI context, documenteer in AI-DECISIONS.md.
[→ Ga naar Les 12](Samenvattingen/Les12-Samenvatting.md)
[→ Ga naar Les 15](Samenvattingen/Les15-Samenvatting.md)
---
### Les 13: Mastering Cursor
### Les 16: Mastering Cursor
**Tools:** Cursor, Claude models
@@ -450,39 +560,11 @@ Cursor als professionele tool, MCP, debugging, AI features bouwen, en het eindpr
**Huiswerk:** Research .cursorrules voorbeelden online, schrijf uitgebreide .cursorrules voor jouw eindproject, test en itereer.
[→ Ga naar Les 13](Samenvattingen/Les13-Samenvatting.md)
[→ Ga naar Les 16](Samenvattingen/Les16-Samenvatting.md)
---
## 3.2 Quality & AI Features
### Les 14: Debugging & Code Review met AI
**Tools:** Cursor, Browser DevTools, React DevTools
**Docent vertelt:**
- Waarom AI goed is in debugging
- Error messages lezen en begrijpen
- Debugging workflow: isoleer → context → vraag AI → begrijp
- Browser DevTools basics (Console, Network, Elements)
- Code review met AI: wat kun je vragen?
- Wanneer AI NIET te vertrouwen
**Studenten doen:**
- Debugging challenge: 6 bugs fixen met AI hulp
- Browser DevTools gebruiken
- Code review van eigen code met AI
- Refactoring met AI suggesties
**Lesopdracht:** Los 6 opzettelijke bugs op in gegeven project, documenteer per bug: error message, prompt aan AI, oplossing, wat je leerde.
**Huiswerk:** Code review 3 files uit je eindproject met AI, fix gevonden issues, maak persoonlijke debugging checklist.
[→ Ga naar Les 14](Samenvattingen/Les14-Samenvatting.md)
---
### Les 15: Vercel AI SDK - AI Features in je App
### Les 17: Vercel AI SDK - AI Features in je App
**Tools:** Vercel AI SDK, Cursor, OpenAI/Anthropic API
@@ -512,23 +594,26 @@ Cursor als professionele tool, MCP, debugging, AI features bouwen, en het eindpr
**Huiswerk:** Integreer AI feature in je eindproject (Recipe chat / Budget advisor / Travel planner), sla conversations op in Supabase.
[→ Ga naar Les 15](Samenvattingen/Les15-Samenvatting.md)
[→ Ga naar Les 17](Samenvattingen/Les17-Samenvatting.md)
---
## 3.3 Deployment & Eindproject
### Les 16: Deployment & Production
### Les 18: Deployment & Production
**Tools:** Vercel, GitHub, Supabase
**Eindopdracht kickoff (15 min):**
- Eindopdracht requirements doornemen
- Beoordelingscriteria uitleggen
- Timeline en deadlines
- Vragen beantwoorden
**Docent vertelt:**
- Vercel deployment flow
- Environment variables in Vercel
- Supabase productie setup
- Custom domains
- Performance basics (Lighthouse)
- Monitoring en error tracking
- Security checklist voor productie
**Studenten doen:**
@@ -545,61 +630,7 @@ Cursor als professionele tool, MCP, debugging, AI features bouwen, en het eindpr
4. Run Lighthouse, fix issues tot score >80
5. Doorloop security checklist
**Huiswerk:** Custom domain toevoegen (optioneel), performance optimaliseren, documentatie updaten met productie URL.
[→ Ga naar Les 16](Samenvattingen/Les16-Samenvatting.md)
---
### Les 17: Eindopdracht Kickoff
**Tools:** Cursor, alle geleerde tools
**Docent vertelt:**
- Eindopdracht requirements doorlopen
- Beoordelingscriteria uitleggen
- Timeline en deadlines
- Tips voor succesvol afronden
- Q&A over onduidelijkheden
**Studenten doen:**
- Eindopdracht document lezen
- Vragen stellen
- Planning maken voor komende weken
- Beginnen aan ontbrekende features
- Peer review setup
**Lesopdracht:** Maak gedetailleerde planning voor afronden eindproject, identificeer wat nog moet gebeuren, begin met hoogste prioriteit items.
**Huiswerk:** Werk aan eindproject volgens planning, documenteer voortgang, bereid vragen voor voor werksessie.
[→ Ga naar Les 17](Samenvattingen/Les17-Samenvatting.md)
---
### Les 18: Eindproject Werksessie
**Tools:** Cursor, alle geleerde tools
**Docent vertelt:**
- Korte standup: waar staat iedereen?
- Beschikbaar voor vragen en hulp
- Geen nieuwe theorie
**Studenten doen:**
- Werken aan eindproject
- Hulp vragen waar nodig
- Peer feedback geven
- Laatste features afronden
- Documentatie completeren
- PROMPT-LOG en AI-DECISIONS afronden
**Focus:** Dit is werktijd. De docent loopt rond, beantwoordt vragen, helpt bij problemen. Studenten werken zelfstandig aan hun eindproject.
**Deliverable eind van de les:**
- Werkende app deployed
- Documentatie compleet
- Klaar voor inleveren (of bijna)
**Huiswerk:** Custom domain toevoegen (optioneel), performance optimaliseren, documentatie updaten met productie URL, werk aan eindopdracht.
[→ Ga naar Les 18](Samenvattingen/Les18-Samenvatting.md)
@@ -607,8 +638,9 @@ Cursor als professionele tool, MCP, debugging, AI features bouwen, en het eindpr
## Tech Stack
- **Frontend:** React, Next.js, Tailwind CSS
- **Frontend:** React, Next.js, TypeScript, Tailwind CSS
- **Backend:** Supabase (Postgres database, Auth)
- **Data Fetching:** React Query (TanStack Query)
- **AI Tools:** ChatGPT, Claude Desktop, v0.dev, OpenCode, Cursor
- **AI SDK:** Vercel AI SDK voor AI features in apps
- **Deployment:** Vercel, GitHub