Files
novi-lessons/Les11-AI-SDK/Les11-Lesopdracht.md
2026-05-19 18:50:11 +02:00

6.0 KiB
Raw Blame History

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)

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:

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:

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!