fix: add les 11

This commit is contained in:
2026-05-19 18:50:11 +02:00
parent b053fc7206
commit 634789e615
37 changed files with 7587 additions and 209 deletions

View File

@@ -0,0 +1,195 @@
# Les 11 — Lesopdracht
## Bouw je eigen AI + Supabase app
**Vak:** AI-Assisted Development
**Opleiding:** NOVI Hogeschool Utrecht
**Wanneer:** Thuis, vóór volgende les
**Inleveren:** GitHub URL + screenshot van werkende chat
---
## Doel
Bouw een complete versie van wat Tim live demonstreerde — **met je eigen thema**. Tim bouwde Polderfest 2027. Jij bouwt iets anders.
Je oefent end-to-end:
- Next.js project from scratch
- Nieuwe Supabase aanmaken + koppelen
- Eigen seed-script schrijven (mag AI bij helpen)
- Chat-route + chat-UI met `streamText` + `useChat`
- 3 vragen kunnen stellen die alleen via jouw data beantwoord kunnen worden
> **Belangrijk:** dit is **niet** dezelfde Polderfest-demo namaken. Je kiest een eigen thema. Anders leer je vooral kopiëren.
---
## Vereisten
### Jouw thema moet:
- [ ] **Volledig fictief zijn** — geen Spotify, geen restaurants in Amsterdam, geen Wikipedia-data
- [ ] Minstens 5 velden hebben (waarvan 1 categorisch, 1 numeriek, 1 tekstrijk)
- [ ] Minstens **100 records** bevatten
- [ ] Vragen oproepen die je écht niet aan ChatGPT kunt stellen zonder jouw data
### Verboden thema's (te bekend voor LLMs):
- Restaurants in een echte stad
- Films / muziek / boeken die echt bestaan
- Sport-statistieken uit de echte wereld
- Klimaat / financiële data uit publieke bronnen
### Geschikte thema-richtingen (kies of bedenk eigen):
- Fictief restaurant-aggregator in een verzonnen stad (bv. "Polderstad")
- Galactische bestuurders archief (sci-fi)
- Verzonnen scriptie-archief van NOVI (1000 nep-titels)
- Fictieve museumcollectie met verzonnen kunstenaars
- Fictief NPO-programma overzicht voor 2030
- Verzonnen mysteries / cryptid-sightings database NL
- D&D campagne-NPCs voor een fictieve wereld
- Fictieve nederlands ondernemers ecosysteem
---
## Stappenplan
### Stap 1 — Thema kiezen + schema ontwerpen (30 min)
- Bedenk thema
- Schrijf op papier (of in Notion): welke velden? Welke vragen wil je kunnen stellen?
- Vertaal naar Supabase SQL schema (zie `schema.sql` van Polderfest als voorbeeld)
### Stap 2 — Next.js project + Supabase (15 min)
```bash
npx create-next-app@latest mijn-thema \
--typescript --tailwind --app --eslint --no-src-dir --turbopack
cd mijn-thema
npm i @supabase/supabase-js ai @ai-sdk/openai zod
npm i tsx dotenv --save-dev
```
- Maak nieuwe Supabase project aan
- Run je schema in SQL Editor
- Vul `.env.local` met URL + keys + OpenAI key
### Stap 3 — Seed script (45 min)
Open `seed-polderfest.ts` (zie bijlage) als referentie. Je hebt twee opties:
**Optie A — Met de hand:**
- Kopieer de structuur
- Vervang Polderfest-bouwstenen (genres, stages, cities…) door jouw thema-bouwstenen
- Pas de `generateBand` functie aan naar `generateItem` voor jouw thema
**Optie B — Met AI hulp (aanbevolen):**
- Open OpenCode / Cursor met `seed-polderfest.ts` als context
- Vraag: "Pas dit seed-script aan voor [mijn thema]. Schema is [paste schema]. Genereer 100+ records."
- Review wat AI maakt — vragen om aanpassingen waar nodig
Run je seed:
```bash
npx tsx scripts/seed-mijn-thema.ts
```
Verifieer in Supabase Table Editor: 100+ records.
### Stap 4 — Chat route (20 min)
`app/api/chat/route.ts` — gebruik Polderfest-versie als template:
```typescript
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";
import { createClient } from "@supabase/supabase-js";
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
);
export async function POST(req: Request) {
const { messages } = await req.json();
const { data: items } = await supabase.from("items").select("*");
const context = items!.map((i) =>
`- ${i.name} (${i.category}, ${i.rating})`
).join("\n");
const system = `Je bent een assistent voor [thema-naam].
Hier is alle data:
${context}
Beantwoord vragen op basis van bovenstaande data. Verzin niets.
Antwoord in het Nederlands.`;
const result = streamText({
model: openai("gpt-4o-mini"),
system,
messages,
});
return result.toDataStreamResponse();
}
```
### Stap 5 — Chat UI (15 min)
`app/chat/page.tsx` — kopieer Polderfest UI, pas titel + placeholder aan.
### Stap 6 — Testen + 3 vragen (15 min)
Browse naar `/chat`. Stel deze 3 vragen aan jouw AI:
1. Een **filter-vraag** ("Welke X hebben Y?")
2. Een **aggregatie-vraag** ("Hoeveel X zijn er in totaal?" / "Wie heeft de hoogste Z?")
3. Een **samenvatting-vraag** ("Vat de Z-categorie samen in 3 zinnen")
Screenshots van werkende antwoorden bewaren — die heb je nodig.
---
## Inleveren (vóór volgende les)
1. **GitHub repo** met je code
2. **3 screenshots** van werkende chat-antwoorden in je README
3. **Eén alinea** onder de screenshots: waarom kan een gewone LLM deze vragen niet beantwoorden zonder jouw data?
---
## Veelvoorkomende problemen
| Probleem | Oplossing |
|----------|-----------|
| `OPENAI_API_KEY is not defined` | Dev server herstarten na `.env.local` aanpassen |
| Supabase insert: `permission denied` | Gebruik `SUPABASE_SERVICE_ROLE_KEY` in seed-script (geen anon) |
| AI verzint dingen | System prompt verstevigen: "Verzin niets. Gebruik alleen onze data." |
| AI antwoordt in Engels | Voeg toe aan prompt: "Antwoord in het Nederlands." |
| Chat hangt / streamt niet | API endpoint moet `result.toDataStreamResponse()` returnen |
| `tsx command not found` | `npm i tsx --save-dev`, run met `npx tsx ...` |
---
## Tijd-indicatie
| Stap | Tijd |
|------|------|
| Thema + schema bedenken | 30 min |
| Project + Supabase setup | 15 min |
| Seed script (met AI hulp) | 45 min |
| Chat route + UI | 35 min |
| Testen + screenshots | 15 min |
| **Totaal** | **~2,5 uur** |
Loop je vast? Vraag in Brightspace of plan korte 1-op-1 met Tim.
---
## Tips
- **Begin klein.** 100 records is genoeg. 500 als je extra wil.
- **AI laten helpen bij seed.** Schaal je productiviteit 10×.
- **System prompt is je hefboom.** Goede prompt = goede antwoorden. Slechte prompt = AI verzint.
- **Test met simpele vraag eerst** ("Hoeveel records zijn er?"). Dan opbouwen.
- **Token cost in de gaten houden** — onze hele les kostte <2 cent. Jouw test ook.
Succes!