Skip to content

--- title: Yappa Knowledge Hub - AI-gedreven Kennisdeelplatform description: Internship report (stagerapport) for the Yappa Knowledge Hub project at UCLL. lastUpdated: 2026-03-30

Yappa Knowledge Hub: AI-gedreven Kennisdeelplatform

Titelblad

TitelYappa Knowledge Hub: AI-gedreven Kennisdeelplatform
StudentMustafa Sarikaya
Studentennummerr0101943
OpleidingProfessionele Bachelor ICT
InstellingUC Leuven-Limburg (UCLL)
Academiejaar2025 – 2026
StagebedrijfYappa
BedrijfsadresEikaart 6, 3740 Bilzen
BedrijfspromotorDavy Dewit
StagebegeleiderMimi Willems
Stageperiode9 februari 2026 – mei 2026
Aantal stagedagenMinimum 56 werkdagen

Inhoudsopgave

  1. Hoofdstuk 1: Omgevingsanalyse & Ontwerp
  2. Hoofdstuk 2: Architectuur & Design Patterns
  3. Hoofdstuk 3: Module - Slack Ingestie & Interface
  4. Hoofdstuk 4: Module - Backend & Notion Sync
  5. Hoofdstuk 5: AI-integratie & Kennisbeheer
  6. Hoofdstuk 6: Kwaliteitsbewaking & DevOps
  7. Besluit & Reflectie
  8. Bijlage A: Logboek (Realisatie)
  9. Verklarende woordenlijst

Abstract

Projecttitel: Yappa Knowledge Hub / Yaphub / Yappa info hub

Yappa is een full-service digitaal agentschap gevestigd te Bilzen dat hoogwaardige digitale oplossingen ontwikkelt voor externe klanten. Intern hecht Yappa veel waarde aan kennisdeling en innovatie binnen hun multidisciplinaire teams, georganiseerd in gespecialiseerde hubs (Brand, OM, Flow en Support). De stageopdracht bestond uit het ontwerpen en ontwikkelen van de "YapHub": een centraal, AI-gedreven platform voor kennisbeheer. Het doel van dit platform is om verspreide informatie uit diverse kanalen, zoals Slack-berichten en externe URL's, te centraliseren en te categoriseren. Deze informatie wordt vervolgens via rolgerichte AI-samenvattingen en rapportages direct beschikbaar gemaakt binnen de specifieke teamomgevingen van de Yappanezen. Het project volgt een incrementele aanpak (Proof of Concept gevolgd door een Minimum Viable Product) en introduceert een bewust architecturaal onderscheid: Slack fungeert als het primaire invoerkanaal, terwijl het "Orakel" (de centrale Notion-workspace van Yappa) dienstdoet als het consumptieplatform. De backend, gebouwd met Symfony 7 en Doctrine ORM (een database abstraction layer), stuurt de Notion API aan om kennisitems, gegenereerde AI-samenvattingen en periodieke rapportages automatisch als Notion-pagina's te integreren. De Slack-ingestiemodule is ontwikkeld met TypeScript en de Bolt SDK (het officiële Slack framework). OpenAI-modellen verzorgen hierbij de tekstuele adaptatie per doelgroep. Het resultaat is een robuuste en schaalbare infrastructuur die medewerkers behoedt voor informatie-overload door relevante kennis naadloos binnen hun vertrouwde Notion teampagina's te presenteren.

Hoofdstuk 1: Omgevingsanalyse & Ontwerp

1.1 Voorstelling Bedrijf: Yappa

Yappa is een full-service digitaal agentschap gevestigd in Bilzen, opgericht met de ambitie om complexe digitale uitdagingen te vertalen naar menselijke oplossingen. Intern noemen medewerkers zichzelf "Yappanezen". De organisatie is opgebouwd rond vier gespecialiseerde Hubs, elk met een eigen discipline en dagelijkse informatiebehoeften:

  • Hub Flow: Het softwareontwikkelingsteam. Hier werken developers dagelijks met frameworks als Symfony en craft CMS. Dit is de hub waarbinnen deze stage plaatsvond.
  • Hub OM: Het online-marketingteam, verantwoordelijk voor SEO, SEA en performance-campagnes. Teamleden volgen voortdurend wijzigingen in Google- en Meta-algoritmes en moeten deze vertalen naar klantstrategieën.
  • Hub Brand: Het creatieve team voor branding, design en visuele communicatie. Zij delen voornamelijk inspiratiebronnen, tools en designtrends.
  • Hub Support: Nazorg en maintenance. Dit team onderhoudt opgeleverde projecten en heeft behoefte aan overzichtelijke kennisdatabases voor troubleshooting.

Yappa investeert actief in een cultuur van kennisdeling. De YappaWaDoeDa, een maandelijks intern event, is hiervan het vaandelstuk: elke medewerker presenteert iets wat hij of zij recent geleerd heeft. Daarnaast communiceert het team intensief via Slack (voor vluchtige, dagelijkse communicatie) en Notion (voor structurele langetermijn opslag). De centrale bedrijfs-workspace binnen Notion wordt intern het "Orakel" genoemd. Dit Orakel fungeert als het kloppend hart voor bedrijfsbrede documentatie en bevat specifieke teampagina's per discipline (zoals de "Developers", "Marketing Squad" en "Project Managers" pagina's) waar dagelijkse workflows zich afspelen.

1.2 Probleemanalyse: De Paradox van Kennisdeling

De aanleiding voor dit project ligt in een spanning die bij Yappa concreet voelbaar is: hoe meer kennis er wordt gedeeld, hoe moeilijker het wordt om die kennis terug te vinden en te benutten.

In de dagelijkse praktijk ziet dit er als volgt uit: een developer uit Hub Flow deelt een technisch blogartikel over een nieuwe Symfony-feature in het #devshed kanaal op Slack. Binnen enkele uren verdwijnt dat bericht onder een stroom van andere conversaties. Een week later zoekt een collega datzelfde artikel, maar kan het niet terugvinden. De link is verloren in de Slack-scrolgeschiedenis.

Dit probleem manifesteert zich op drie niveaus:

  1. Verlies van context en vindbaarheid: Waardevolle kennis die in Slack wordt gedeeld, is gebonden aan het moment van delen. Er is geen centrale index, geen zoekfunctie over kanalen heen, en geen manier om content te taggen of te categoriseren op het moment dat het gedeeld wordt.

  2. Information overload door gebrek aan filtrering: Wanneer een marketeer uit Hub OM zich abonneert op een breed kanaal, ontvangt zij zowel deep-dive technische analyses (die voor haar irrelevant zijn) als strategische marktanalyses (die juist wél relevant zijn). Er is geen mechanisme om content rolgebaseerd te filteren of samen te vatten.

  3. De synchronisatie-kloof tussen Slack en Notion: Veel medewerkers weten dat Notion de juiste plek is om kennis langdurig vast te leggen, maar de drempel om dit handmatig te doen is te hoog. Het gevolg is een groeiende kloof: snelle kennis leeft in Slack, formele documentatie staat in Notion, maar de brug ontbreekt.

1.3 Stakeholderanalyse & User Personas

De kern van de YapHub is dat Slack dient als invoerkanaal/dashboard en Notion als consumptieplatform. Elk kennisitem dat via Slack wordt ingediend, wordt automatisch gesynchroniseerd als volwaardige Notion-pagina, inclusief de volledige inhoud als embedded content blocks. Hetzelfde geldt voor AI-samenvattingen en digest-rapporten: elk van deze entiteiten wordt een eigen Notion-pagina met relationele links naar de bijbehorende categorie, doelgroep en het bronitem.

Dit maakt Notion de plek waar medewerkers kennis raadplegen, doorzoeken en beheren, terwijl Slack de laagdrempelige plek blijft waar kennis binnenkomt. De Slack App Home fungeert als een lightweight dashboard voor snelle navigatie en abonnementenbeheer, maar is niet bedoeld als vervanging voor de Notion-workspace.

Het TargetGroup-mechanisme zorgt ervoor dat hetzelfde bronmateriaal door de AI anders wordt samengevat per doelgroep. Hieronder volgen drie representatieve profielen:

Profiel 1: De Developer (Hub Flow)

  • Context: Werkt dagelijks met PHP/Symfony en het Craft CMS. Deelt regelmatig technische artikelen, changelogs en security-advisories in het #devshed Slack-kanaal.
  • Hoe zij kennis invoeren: Vindt een relevant artikel op een tech-blog → deelt de link in #devshed → de YapHub-bot detecteert de URL automatisch en biedt via een ephemeral bericht de optie "Opslaan" aan → bij klik opent een modal waar categorie en doelgroepen geselecteerd worden → na bevestiging wordt het item opgeslagen in de backend en direct gesynchroniseerd als Notion-pagina.
  • Hoe zij kennis consumeren: Binnen de algemene Notion-workspace (het "Orakel") navigeert de developer naar de eigen [Developers] teampagina. Op deze pagina is een Linked Database View van de centrale Kennishub geplaatst, vooraf gefilterd op items relevant voor development. Daar vindt hij het artikel direct terug in zijn eigen vertrouwde werkomgeving. Indien gegenereerd, leest hij hier de test- en architectuur-gefocuste AI-samenvatting.
  • Wat de YapHub oplost: Artikelen die voorheen na een dag verdwenen in de Slack-scroll, worden nu permanent vastgelegd in Notion en zijn doorzoekbaar, gecategoriseerd en voorzien van rolspecifieke samenvattingen gepresenteerd in de eigen werkomgeving.

Profiel 2: De Online Marketeer (Hub OM)

  • Context: Beheert Google Ads- en Meta-campagnes voor klanten. Moet op de hoogte blijven van platformwijzigingen en deze vertalen naar klantadviezen.
  • Hoe zij kennis invoeren: Vindt een artikel over een Google Core Update → gebruikt de Global Shortcut "Snel Kennis Toevoegen" (⚡-menu in Slack) → vult de URL in, de metadata wordt automatisch gescrapt → wijst de categorie "Marketing & Growth" toe met doelgroep "Marketeers" → bevestigt.
  • Hoe zij kennis consumeren: Raadpleegt primair Notion. Ze navigeert naar de [Marketing Squad] teampagina binnen het Orakel. Via de Linked View staan de relevante opgeslagen kennisitems en gegenereerde AI-samenvattingen (met focus op campagne-impact in plaats van technische details) netjes gepresenteerd. Zij ontvangt daarnaast periodiek een digest, een overzichtsrapport dat direct beschikbaar is op deze specifieke teampagina.
  • Wat de YapHub oplost: Hoeft niet langer zelf technische artikelen door te spitten of in een externe database te zoeken. De AI vertaalt complexe bronnen en injecteert deze naadloos in de eigen vertrouwde Notion teampagina.

Profiel 3: De Projectmanager / Teamlead (Leadership)

  • Context: Coördineert sprints, bewaakt scope en rapporteert aan klanten. Heeft een breed overzicht nodig over trends in de verschillende hubs, maar geen tijd om elk artikel te lezen.
  • Hoe zij kennis consumeren: Raadpleegt de actuele kennis via de [Project Managers] teampagina in het Orakel. In een specifieke sectie worden AI-samenvattingen gefilterd getoond voor de doelgroep "Management". Dit levert korte, strategische overzichten op gericht op business value, direct naast lopende projectdocumentatie. Ook de wekelijkse digest verschijnt hier inline ter voorbereiding voor o.a. klantmeetings.
  • Hoe zij het Slack-dashboard gebruikt: De App Home van de YapHub-bot biedt een compact overzicht van categorieën en recente items. Hier kan de projectmanager zich abonneren op relevante lijsten en via het overflow-menu snel acties uitvoeren (een samenvatting regenereren voor een andere doelgroep, een item bewerken, of naar de Notion-pagina navigeren).
  • Wat de YapHub oplost: Krijgt via de eigen Notion teampagina een gefilterd, samenvattend overzicht gepresenteerd zonder van tool of workspace context te hoeven wisselen.

1.4 Use Case Catalogus

De YapHub hanteert een duidelijke scheiding: Slack is het invoerkanaal, Notion is het consumptieplatform. Hieronder worden de drie ingestiemethoden en drie consumptieworkflows beschreven.

Ingestie (via Slack)

UC1: Context-bewuste Berichtopslag (Message Shortcut)
  • Actor: Elke Yappanees.
  • Trigger: De gebruiker leest een waardevol bericht in een Slack-kanaal.
  • Flow:
    1. Gebruiker klikt met de rechtermuisknop op het bericht → selecteert "Opslaan in Kennishub".
    2. Een modal opent met de berichttekst reeds vooringevuld. Categorie en doelgroepen worden als dropdown-opties aangeboden.
    3. Gebruiker selecteert de relevante categorie en doelgroepen, en bevestigt.
  • Post-conditie: Het kennisitem is opgeslagen in de backend. De NotionSyncKnowledge-service creëert automatisch een volwaardige Notion-pagina met de volledige content als embedded blocks, metadata-properties (titel, URL, tags, status) en relaties naar de Notion-databases voor categorieën en doelgroepen.
UC2: Snel Kennis Toevoegen (Global Shortcut / Quick Add)
  • Actor: Elke Yappanees.
  • Trigger: De gebruiker heeft extern een interessante URL of tekst gevonden (bijv. op een blog, in een e-mail).
  • Flow:
    1. Gebruiker opent het bliksemmenu (⚡) in Slack → selecteert "Snel Kennis Toevoegen".
    2. Een lege modal opent met velden voor titel, URL, beschrijving, categorie en doelgroepen.
    3. Bij het plakken van een URL scrapt de urlScraper-service automatisch de OpenGraph-metadata (titel, beschrijving, afbeelding) en vult de velden in.
    4. Gebruiker bevestigt.
  • Post-conditie: Het item is aangemaakt en als Notion-pagina gesynchroniseerd.
UC3: Automatische URL-detectie
  • Actor: Het systeem (de bot), getriggerd door een gebruiker die een URL deelt in een specifiek kanaal.
  • Trigger: De YapHub-bot is lid van het kanaal en detecteert een URL in een bericht.
  • Flow:
    1. De bot parseert binnenkomende berichten op URL-patronen en scrapt de OpenGraph-metadata.
    2. De bot stuurt een ephemeral bericht (alleen zichtbaar voor de afzender) met een compact preview en de knop "📥 Opslaan".
    3. Bij klik op "Opslaan" opent een vooringevulde modal (identiek aan UC1/UC2).
  • Post-conditie: Indien opgeslagen, wordt het item verwerkt en gesynchroniseerd naar Notion. Indien genegeerd, verdwijnt het ephemeral bericht.

Consumptie (via Notion + Slack)

UC4: Kennis Raadplegen via Team Notion Pagina's
  • Actor: Elke Yappanees.
  • Trigger: De gebruiker wil eerder opgeslagen kennis terugvinden of doorbladeren.
  • Flow:
    1. Gebruiker opent zijn vertrouwde teampagina (bv. Developers, Marketing Squad, Project Managers) binnen de "Orakel" Notion structuur.
    2. Op deze pagina is een Linked Database View geïntegreerd van de overkoepelende Knowledge Hub database, dynamisch voorgefilterd om uitsluitend items te tonen relevant voor dit specifieke team.
    3. Elk zichtbaar kennisitem kan geopend worden als een volwaardige Notion-pagina met eigenschappen (titel, bron-URL, Slack-metadata) en de volledige originele content als Notion-blocks, direct naast actieve projectdocumentatie.
    4. Gekoppelde AI-samenvattingen gericht op deze specifieke doelgroep (zoals de "Marketeers" of "Developers" focus) zijn met één klik doorklikbaar.
  • Post-conditie: De gebruiker heeft de kennis direct in de eigen context en werkruimte geraadpleegd zonder te hoeven doorklikken naar een ontkoppelde of abstracte databasetoepassing.
UC5: Rol-gebaseerde AI-samenvatting Raadplegen
  • Actor: Elke Yappanees.
  • Trigger: De gebruiker wil een samenvatting van een kennisitem, afgestemd op een specifieke doelgroep.
  • Flow:
    1. Via de Slack App Home of via een beheeractie wordt een AI-samenvatting gegenereerd voor een geselecteerde doelgroep (bijv. "Developers", "Marketeers", "Management").
    2. De AI genereert de samenvatting op basis van prompt-templates die per doelgroep en categorie geconfigureerd zijn in Notion (de "Prompt Templates"-database).
    3. De samenvatting wordt lokaal opgeslagen en vervolgens als een eigen Notion-pagina aangemaakt in de "AI Summaries"-database, met relaties naar het bronitem, de doelgroep, en de gebruikte template. De volledige samenvattingstekst wordt als embedded blocks in de pagina geplaatst.
    4. Op de Notion-pagina van het originele kennisitem verschijnt automatisch een relatie-link naar de nieuwe samenvatting.
  • Post-conditie: De AI-samenvatting is beschikbaar als aparte Notion-pagina, direct raadpleegbaar en bewerkbaar door niet-technische collega's. Metadata zoals AI-model, kosten, tokens en generatie-duur worden als properties opgeslagen.
UC6: Periodiek Digest Ontvangen
  • Actor: Een geabonneerde Yappanees.
  • Trigger: Een periodiek tijdvenster is verstreken (bijv. wekelijks) en er zijn nieuwe kennisitems beschikbaar.
  • Flow:
    1. Het systeem verzamelt alle kennisitems die binnen het tijdvenster zijn toegevoegd aan categorieën waarop de gebruiker geabonneerd is, inclusief de bijbehorende, reeds via prompt-templates gegenereerde AI-samenvattingen voor hún specifieke doelgroep (bijv. Developer of CEO).
    2. Een beknopt digest-rapport wordt gegenereerd: per gedeeld kennisitem bevat dit overzicht maximaal 3 tot 4 zinnen, bedoeld om op zeer korte tijd de kern te vatten.
    3. Het digest wordt aangemaakt als een Notion-pagina in de "Digests"-database. Onder elke 3-zinssamenvatting staan directe relationele links naar (1) de originele Notion-pagina van het volledige kennisitem en (2) de specifieke AI-samenvattingspagina('s) voor de betreffende doelgroep(en).
    4. Geabonneerde gebruikers worden genotificeerd via hun geconfigureerde afleverkanaal, en het digest wordt direct zichtbaar op hun eigen Notion teampagina.
  • Post-conditie: Het digest biedt een ultra-korte update die informatie-overload voorkomt, waarbij de lezer via de meegeleverde links selectief kan doorklikken naar de langere rolgerichte AI-samenvattingen of het bronitem.

Hoofdstuk 2: Architectuur & Design Patterns

2.1 De 10-Layer Architecture: Rationale

Om een schaalbaar en onderhoudbaar systeem te bouwen, is gekozen voor een strikte gelaagde architectuur. Deze "10-layer" aanpak is geïnspireerd op Clean Architecture en Domain-Driven Design (DDD), met als doel leaky abstractions te voorkomen.

LaagNaamTechnisch Framework / ToolRationale
Layer 1PresentationSymfony Controllers, Slack HandlersEnkel input validatie en dispatching.
Layer 2OrchestrationCustom Symfony ServicesCoördinatie van complexe flows (bijv. AI -> Sync -> Notify).
Layer 3Sync ServicesAbstractNotionSync (Custom)Isoleert de syncing-state van de business logica.
Layer 4Domain ServicesValidator, SerializerPure business logica zonder externe afhankelijkheden.
Layer 5PersistenceDoctrine Persistence LayerBeheert de lifecycle van lokale entiteiten.
Layer 6Repository ManagerRepositoryManagerFacadeVerbergt de complexiteit van "Local vs Remote" data.
Layer 7Data AccessDoctrine ORM / Notion SDKImplementeert de daadwerkelijke data-transfers.
Layer 8Data StorageSQLite (Cache) / PostgreSQLFysieke opslag van gepersisteerde data.
Layer 9Cross-CuttingMonolog, HealthChecksHorizontale zorgen zoals logging en monitoring.
Layer 10AI InfrastructureSymfony AI BundleAbstractie van AI-modellen en prompt engines.

2.2 Het Orchestrator Pattern & Result DTOs

Het meest cruciale design pattern in de YapHub is de Orchestrator. In plaats van business logica in controllers te plaatsen, delegeren we dit naar gespecialiseerde klassen. Een belangrijke toevoeging is het gebruik van Result DTOs.

In plaats van ruwe arrays of entiteiten terug te geven, retourneert elke orchestrator een Result object. Dit object bevat:

  • Een status (Success/Failure).
  • De data (DTO).
  • Een bericht (voor de eindgebruiker in Slack).
  • Optionele error codes voor debugging.

Dit zorgt ervoor dat de Slack-interface altijd een consistente reactie krijgt, ongeacht of de fout in de AI-laag, de sync-laag of de database-laag optreedt.

2.3 Technologie Stack: De Transitie

Gedurende de ontwikkeling is de stack geëvolueerd om betere abstracties te bieden:

  • Backend: Symfony 7 (PHP 8.3): Gebruik van de nieuwste features zoals readonly properties en constructor promotion.
  • Frontend: Slack Bolt (TypeScript): Volledig getypeerd voor betere ontwikkel-ervaring.
  • AI: Migratie van een custom OpenAI-client naar het Symfony AI Bundle.

2.4 Decoupling & Modularisatie: Van POC naar MVP

Een kritieke fase in de architectuur was het afbouwen van technische schuld ("tech debt") die tijdens de Proof of Concept (POC) fase was opgebouwd.

  • Elimineren van Magic Strings: Hardcoded waarden verspreid over de codebase zijn geëxtraheerd naar gespecialiseerde Constant-klassen (zoals RouteConstants, NotionConstants en EntityFields). Dit minimaliseert de kans op typefouten en centraliseert configuratiewijzigingen.
  • Service Decoupling & Controllers: De overgang van "Fat Controllers" naar de "Thin Controller / Fat Service" methodiek. De logica is opgedeeld in strikte Orchestrators, Services en Repositories (zo is de verouderde PromptTemplateRepository volledig gedeprecate ten faveure van dynamische queries).
  • Slack Modularisatie: De TypeScript-codebase is herschreven volgens Domain-Driven Design principes. De initiële monolithische scripts (20 bestanden) zijn opgesplitst in meer dan 80 bestanden, georganiseerd in /views, /actions, en /submissions. Dit maakt de Slack UI component-gebaseerd en oneindig schaalbaar.

Hoofdstuk 3: Slack Module & Interface

3.1 Keuze voor Bolt SDK & Socket Mode

De frontend van de YapHub is gerealiseerd als een Slack-applicatie gebruikmakend van het Bolt.js SDK in TypeScript. Een fundamentele architecturale beslissing was het gebruik van Socket Mode.

Voordelen van Socket Mode voor Yappa:

  • Beveiliging: De bot zet zelf een uitgaande WebSocket-verbinding op. Er hoeven geen inkomende poorten geopend te worden op de bedrijfsserver, en er is geen publieke URL (zoals Ngrok) nodig voor lokale ontwikkeling.
  • Eenvoud: Geen noodzaak voor complexe HTTPS-certificaat configuraties voor webhooks.
  • Real-time: Snelle verwerking van events zonder de overhead van HTTP handshakes bij elke request.

3.2 Structuur van de Slack Applicatie

De Slack module is modulair opgebouwd om onderhoudbaarheid te garanderen. De logica is verdeeld over:

  • src/app.ts: De entry-point waar de app wordt geconfigureerd met tokens (SLACK_BOT_TOKEN, SLACK_APP_TOKEN) en waar alle handlers worden geregistreerd.
  • src/handlers/: Bevat gespecialiseerde handlers voor:
    • Commands: Zoals /knowledge voor het doorzoeken van de hub.
    • Shortcuts: Voor het snel toevoegen van berichten of URLs ("Quick Add").
    • Events: Zoals app_home_opened voor het renderen van het dashboard.
    • Actions: Voor interactieve elementen zoals knoppen en menu's.

3.3 De Dynamische App Home: Technisch Ontwerp

De "App Home" is het visuele startpunt voor werknemers. In tegenstelling tot statische modals, wordt de Home-tab bij elke interactie opnieuw opgebouwd via de views registry.

Technisch overzicht van de Home-tab componenten:

  1. Statistieken-sectie: Haalt via een interne API-call naar de Symfony backend het aantal resources en actieve categorieën op.
  2. Gepagineerde Categorie-lijst: Om de Slack payload limieten (max 3000 karakters per block) te respecteren, implementeert de bot server-side paginering voor de lijst met categorieën.
  3. Navigatie State: Omdat Slack-interacties stateless zijn, gebruikt de bot een patroon van underscores in action_id's (bijv. browse_list_306e...) om de context van een klik door te geven aan de orchestrator.

3.4 Ingestie Workflows: Handlers in Detail

De bot ondersteunt complexe workflows voor het verzamelen van kennis:

3.4.1 Message Shortcuts (Context-Aware)

Wanneer een gebruiker "Save to Hub" kiest bij een bericht, ontvangt de bot een message_action payload.

  • Extractie: De handleSaveMessageShortcut haalt de tekst, auteur en timestamp van het bronebericht op.
  • UI: Een modal wordt geopend waarbij deze velden reeds gepre-vuld zijn, wat de drempel voor invoer enorm verlaagt.

3.4.2 Global Shortcuts & URL Scraper

De "Quick Add" shortcut maakt gebruik van een urlScraper service. Wanneer een gebruiker een URL plakt, probeert de bot asynchroon de OpenGraph metadata (titel, beschrijving, afbeelding) op te halen om de velden automatisch in te vullen.

typescript
// Voorbeeld van een Action Handler met Regex matching
app.action(/view_item_(.*)/, async ({ action, ack, client, body }) => {
  await ack();
  const itemId = (action as any).value;
  // Haal details op via backend en toon in modal
  const itemData = await knowledgeService.getById(itemId);
  await client.views.open({
    trigger_id: (body as any).trigger_id,
    view: buildItemViewModal(itemData)
  });
});

Hoofdstuk 4: Module - Backend & Notion Sync

4.1 Symfony 7 & Asynchrone Verwerking

De kern van de YapHub draait op Symfony 7. Om een vlotte gebruikerservaring in Slack te garanderen (waar een respons binnen 3 seconden vereist is), wordt zware logica zoals AI-generatie en Notion-synchronisatie asynchroon afgehandeld via de Symfony Messenger.

Messenger Architectuur:

  • Transports: Gebruik van Redis als message broker voor de async queue.
  • Handlers: Specifieke handlers (GenerateSummaryHandler, SyncNotionHandler) die de opdrachten uit de queue consumeren.
  • Retries: Automatische retry-strategie met exponential backoff voor het afhandelen van tijdelijke Notion API-fouten (zoals rate limits).

4.2 De Notion Sync Engine: Bidirectionele Consistentie

Een van de meest technische uitdagende onderdelen is de synchronisatie tussen de lokale PostgreSQL database en Notion. Dit is opgelost via een gespecialiseerde Sync Engine gebaseerd op het Template Method Pattern.

Het Sync-algoritme (AbstractNotionSync):

  1. Fetch: Ophalen van gewijzigde pagina's uit Notion via de filter API (gebaseerd op last_edited_time).
  2. Pagina-iteratie: De engine handelt automatisch de cursor-gebaseerde paginering van de Notion API af.
  3. Change Detection: Vergelijking van de notion_last_edited_at timestamp met de lokale last_sync waarde.
  4. Resolution: Bij conflicten (wijziging aan beide kanten) wint in de huidige implementatie de Notion-versie als "Source of Truth".

4.3 Markdown-to-Notion Block Conversion

Resources die via Slack binnenkomen (vaak in Markdown-formaat) moeten correct weergegeven worden in Notion. Omdat Notion geen platte tekst opslaat, maar een boomstructuur van Blocks, is de MarkdownBlockConverter ontwikkeld.

Implementatie-details: De converter doorloopt de content regel-voor-regel en gebruikt pattern matching om Markdown-elementen te identificeren:

  • #, ##, ###: Getransformeerd naar Heading1, Heading2 of Heading3 objecten uit de Notion SDK.
  • ```: Activeert een state-machine die de volgende regels buffert in een Code block.
  • - of 1.: Converteert naar BulletedListItem of NumberedListItem.
php
// Fragment uit de MarkdownBlockConverter
if (str_starts_with($trimmed, '# ')) {
    $blocks[] = Heading1::fromString(substr($trimmed, 2));
} elseif (preg_match('/^\d+\.\s/', $trimmed)) {
    $blocks[] = NumberedListItem::fromString(preg_replace('/^\d+\.\s/', '', $trimmed));
}

4.4 Notion Repository Manager (Facade Pattern)

Om de gelaagdheid te respecteren, mogen services niet direct weten of ze met een lokale database of de Notion API praten. De NotionRepositoryManager fungeert hier als een Facade:

  • Als een ID een UUID-formaat heeft, wordt de LocalKnowledgeRepository (Doctrine) gebruikt.
  • Indien het een Notion-specifiek ID-formaat betreft, schakelt de manager over naar de NotionKnowledgeRepository. Dit maakt de rest van de backend volledig agnostisch voor de onderliggende opslag-engine.

4.5 Rich Content Embedding: Van Properties naar de Page Body

In de MVP-fase is de synchronisatie-engine uitgebreid om niet alleen metadata properties via de Notion API te updaten, maar ook volledige pagina-content te integreren. Kennisitems, uitgebreide AI-samenvattingen en periodieke digest-rapporten worden via specifieke *EmbeddingService klassen (zoals de DigestNotionEmbeddingService) omgezet in gestructureerde Notion Blocks en rechtstreeks via een PATCH request in de page body geïnjecteerd. Dit voorkomt dat gebruikers in Notion op onoverzichtelijke properties moeten klikken en presenteert de kennis direct leesbaar als een traditioneel artikel of wekelijks overzicht.

Hoofdstuk 5: AI-integratie & Kennisbeheer

5.1 Prompt Engineering & Template Engine

De kernwaarde van de YapHub is de transformatie van ruwe informatie naar hapklare kennis. Dit wordt aangestuurd door de PromptBuilderService, die een custom Handlebars-style template engine implementeert.

Technische kenmerken van de Engine:

  • Placeholders: Ondersteunt variabelen zoals {{title}}, {{content}}, en {{url_content}}.
  • Conditionele Logica: Implementatie van conditionele blokken (bijv. if/endif statement), waardoor prompts zich aanpassen aan de beschikbaarheid van data (bijv. enkel een URL-sectie tonen als er een URL is gescraped).
  • Inheritance Chain: Templates worden opgezocht in een hiërarchie:
    1. Specifieke template voor de combinatie van Target Group + Categorie.
    2. Fallback naar de globale template van de Target Group.
    3. Systeem-brede default template.

5.2 Rol-gebaseerde Samenvattingen

Een uniek aspect van de YapHub is dat de AI de context van de lezer begrijpt. Via de TargetGroup entiteit wordt de samenvatting aangestuurd:

  • Developers: Focus op architectuur, code-voorbeelden en technische implicaties.
  • Marketeers: Focus op trends, klantwaarde en creatieve invalshoeken.
  • Management: Focus op ROI, strategische fit en high-level overzichten.

5.3 De Summary Lifecycle (De "Three Gates")

Om consistentie tussen de lokale database en Notion te garanderen, volgt de AiSummaryOrchestrator een strikt proces genaamd de "Three Gates":

  1. Gate 1 (Pre-condition): De resource moet eerst succesvol gesynchroniseerd zijn naar Notion en een notion_id hebben voordat een samenvatting gekoppeld kan worden.
  2. Gate 2 (Persistence): Na generatie door de AI-provider (OpenAI/OpenRouter) wordt de samenvatting lokaal opgeslagen. Pas na een succesvolle flush() van de database wordt de Notion-sync gestart.
  3. Gate 3 (Linking): Zodra de samenvatting ook in Notion bestaat, wordt er een back-link (Relation) aangemaakt op de oorspronkelijke kennispagina in Notion.

5.4 De Transitie naar Symfony AI Bundle

Een significante technologische sprong voorwaarts was de migratie van een custom OpenAI-integratie naar de (experimentele) Symfony AI Bundle.

Waarom deze overstap?

  • Unified Interface: De bundle biedt een ChatProviderInterface. Dit betekent dat de business logica van de YapHub niet langer afhankelijk is van de specifieke API van OpenAI. We kunnen nu met één configuratiewijziging overstappen naar Anthropic, Mistral of een lokaal Llama-model.
  • Structured Outputs: De bundle faciliteert het mappen van AI-responses naar PHP-klassen, wat de foutgevoeligheid van de "Three Gates" sync aanzienlijk vermindert.
  • Middleware Support: Native ondersteuning voor logging, caching en rate-limiting via de standaard Symfony HttpClient onder de motorkap.

5.5 Digest Generation: Van Items naar Inzichten

Naast individuele items ondersteunt de Hub Digests:

  • Aggregatie: De DigestGenerationOrchestrator verzamelt alle goedgekeurde resources binnen een tijdvenster (bijv. afgelopen week).
  • Overkoepelende Analyse: In plaats van losse samenvattingen onder elkaar te zetten, krijgt de AI de opdracht om patronen en trends te ontdekken over de verschillende items heen.
  • Distributie: De resulterende digest wordt via de DistributionService afgeleverd in Slack-kanalen of als een aparte pagina in Notion.
php
// Voorbeeld van de PromptBuilder logica voor Digests
public function buildDigestPrompt(string $context, TargetGroup $targetGroup): string {
    return "Je bent een trend-analist voor {$targetGroup->getName()}.
            Analyseer de volgende week-updates: {$context}";
}

5.6 Het Abonnementensysteem (Subscription Lifecycle)

Om information overload tegen te gaan, introduceert de MVP een robuust abonnementsmodel gestuurd via de Slack App Home.

  • Dynamische Categorieën: Werknemers zien alle beschikbare expertises ("Thematische lijsten") op hun dashboard.
  • Opt-in Distributie: Via interactieve knoppen in Slack kunnen gebruikers zich abonneren op specifieke themazones. De Slack handler activeert de SubscriptionOrchestrator op de backend.
  • Geautomatiseerde Levering: Zodra een Digest is gegenereerd, berekent de DistributionService welke medewerkers geabonneerd zijn op die specifieke categorie, en stuurt deze proactief via een Slack Direct Message en als een geïnjecteerde Notion pagina de samengevatte inzichten door. Dit garandeert dat niemand wordt afgeleid door ongewenste of irrelevante content.

Hoofdstuk 6: Kwaliteitsbewaking & DevOps

6.1 Testing Hiërarchie

Om de betrouwbaarheid van de YapHub te garanderen, is een gelaagde teststrategie toegepast die aansluit bij de architectuur:

  1. Unit Tests (PHPUnit): Focussen op de kleinste eenheden, zoals de MarkdownBlockConverter en de NotionPropertyMapper. Hierbij worden externen zoals de Notion API volledig gemockt.
  2. Integration Tests (Symfony): Verifiëren de samenwerking tussen services en de database (gebruikmakend van een aparte SQLite test-database).
  3. End-to-End (E2E) Tests (Playwright): Testen de volledige flow vanuit het perspectief van de gebruiker in Slack.

6.2 Playwright & Slack Mocking

Een innovatieve oplossing binnen dit project is de implementatie van een SlackMockServer voor E2E tests. Omdat echte Slack-interacties traag zijn en afhankelijk van netwerkverbindingen, simuleert de mock-server de Slack API:

  • Payload Simulation: De test verzendt JSON-payloads die identiek zijn aan de block_actions van Slack.
  • State Verification: De tests controleren of de bot reageert met de juiste "Blocks" (bijv. of een item correct wordt uitgevouwen zonder de paginering te resetten).
  • Isolation: Hiermee kan de UI-logica van de bot dagelijks honderden keren getest worden in de CI-pipeline zonder de rate-limits van de echte Slack API te raken.

6.3 CI/CD Pipeline (GitHub Actions)

Het deployment-proces is volledig geautomatiseerd via GitHub Actions, verdeeld over uitbreidende flows (bijv. de introductie van e2e-test.yml):

  • Pre-commit Hooks: Via .husky wordt lokale codekwaliteit gewaarborgd door statische analyses (PHPStan), code formattering (CS-Fixer voor PHP, Prettier voor TypeScript) en linting verplicht af te dwingen vóór elke commit. Tevens dwingen de hooks lokaal end-to-end testing (Playwright) af. Deze tijdige lokale detectie voorkomt dat falende testbare of onjuist geformatteerde code de cloud CI-pipeline bereikt.
  • PHP Checks: Draait bij elke Pull Request. Voert PHPStan (static analysis op level 7) en PHPUnit uit. Dit waarborgt dat de gelaagde architectuur en type-safety gerespecteerd blijven.
  • TypeScript Checks: Controleert de Slack-codebase op linting-fouten (ESLint) en formatting (Prettier).
  • Auto-Deployment: Zodra code wordt gemerged naar de main branch, wordt via een SSH-action de code gepusht naar de Yappa VPS. De pipeline herstart automatisch de Docker-containers of systemd services om de nieuwe versie live te zetten.

6.4 Documentatie & UI/UX als Basiswaarde (VitePress)

Documentatie vormde een cruciaal DevOps-vraagstuk. Om onboarding en adoptie soepel te laten verlopen, werden de documentatiesystemen sterk geüpgraded. Dit omvatte een ingrijpende UI/UX upgrade van het VitePress portaal.

6.5 Infrastructuur & Deployment

De YapHub draait op een professionele infrastructuur die redundantie en snelheid waarborgt:

  • VPS (Virtual Private Server): Beheerd via SSH-keys met een strikt firewall-beleid (UFW).
  • Redis (Cache & Message Broker): Redis vervult een dubbelrol. Het versnelt de categorie-lookups en dient als de transportlaag voor de Symfony Messenger. Hierdoor kunnen we zware AI-taken verwerken zonder de Slack-app te blokkeren.
  • PostgreSQL / SQLite: Hoewel SQLite ideaal is voor de snelle ontwikkel-cycli en caching, is de architectuur voorbereid op PostgreSQL voor grootschalige data-opslag.

6.6 Monitoring & Onderhoudbaarheid

Naast testen is er ingezet op proactieve monitoring:

  • Structured Logging: Gebruik van Monolog in de backend en een custom logger in de Slack-bot om fouten direct traceerbaar te maken naar de juiste Orchestrator of Handler.
  • Health Checks: Een /health endpoint op zowel de Symfony als de Node.js server die door externe monitoring-software (bijv. UptimeRobot) gepoold kan worden.

7. Besluit & Reflectie

7.1 Evaluatie van het project

De ontwikkeling van de Yappa Knowledge Hub ("YapHub") heeft zich succesvol door de fases van conceptie, Proof of Concept (POC), tot aan de uiteindelijke realisatie van het Minimum Viable Product (MVP) bewogen. Waar het project startte met een initieel doel om versnipperde kennisinvoer recht te trekken, evolueerde het tot een geavanceerd enterprise-ecosysteem. Het resultaat is een applicatie die feilloos de kloof dicht tussen Slack (snelle communicatie), Notion (statische kennisopslag), en de kracht van Artificiële Intelligentie (automatisering en samenvatting).

Een significant prestatiepunt van de afgelopen weken was de overkoepelende fusie en opschoning van de codebase via liefst 8 gerichte Pull Requests. Hiermee weefden we de snelle, maar kwetsbare code uit de POC-fase samen met de volwassen 10-layered architectuur van de MVP. Dankzij het introduceren van de DistributionService, asynchrone generatie via de Symfony Queue, en het gepersonaliseerde Subscription Lifecycle systeem beantwoordt en overtreft de huidige MVP alle vooropgestelde "Must-Have" requirements uit het originele concept. Het automatiseren van testing via E2E met Playwright garandeert bovendien dat het ontwikkelde fundament schaalbaar en future-proof blijft voor Team Flow.

7.2 Zelfreflectie

Terugkijkend op de stageperiode beschouw ik dit project als een ongeëvenaard leertraject dat de theorie onmiddellijk vertaalde naar een professionele realiteit.

Technisch gezien dwong de bouw van het project me uit mijn comfortzone:

  • Het ontwerpen en strikt implementeren van het Orchestrator pattern in een grote Symfony applicatie verscherpte sterk mijn begrip van 'Separation of Concerns'.
  • Transities naar volwassen ontwerppatronen, zoals Result DTO's (Data Transfer Objects) voor feilloze type-safety en het afbouwen van zogeheten magic strings door global constants, transformeerde mijn kijk op schaalbare software-engineering. Verder boden complexe test-paradigma's zoals de E2E Slack mock-server in Playwright onschatbare DevOps-bekwaamheden.

Daarnaast was de professionele begeleiding bij Yappa de absolute smeerolie op deze groei. Zaken, zoals het structureel verwerken van code-reviews afkomstig van collega's als Davy en Wesley, versnelden de leercurve. De integratie binnen "Team Flow" (het meelopen in wekelijkse scrums, het bijwonen van de sprint "wrap-ups" en bedrijfsbrede calls zoals de 'YappaWaDoeDa') legde de nadruk op project-awareness: snappen hoe scope management, iteraties en billable uren naadloos synchronizen met pure theorie. Doormiddel hiervan evolueerde ik van simpel coderen op een abstract leeg canvas, naar het doelbewust ontwikkelen tegen functionele business nodes in een teamverband.

7.3 Aanbevelingen

Hoewel het MVP stabiel en operationeel is, zijn er fundamentele pijlers gereed om hierop uit te breiden en het nut ervan te vergroten voor Yappa:

  1. Jira Integratie (Ticket-koppelingen): Als een "Won't-have" in de MVP is de integratie met Jira een van de meest impactvolle follow-ups. Door issue keys of bugreports automatisch aan kennisbank-items (Notion) of Slack-discussies te koppelen, automatiseer je cross-platform debugging.
  2. Volledige Onboarding van Beta-Gebruikers: Het openstellen van het abonnementensysteem voor niet-technische medewerkers bij de "Hub Brand" of "Hub Grow" zal essentiële feedback opleveren om de prompt-engineering van de gepersonaliseerde samenvattingen nauwkeuriger af te stellen.
  3. Migratie van Oude Sync-logica: Hoewel er momenteel veel technische schuld verholpen is door de vervangingslaag (zoals de PromptTemplateRepository), is het aangeraden om de afhankelijkheden en logische fallback mechanismes ten opzichte van Doctrine verder dicht te timmeren zodra productie-verkeer intensifeert.

Bijlage A: Logboek (Realisatie)

Hieronder volgt het chronologisch overzicht van de wekelijkse werkzaamheden.

Week 01: Opstart en fundament

Periode: 9 – 13 februari 2026

Gerealiseerd

  • Kennismaking met het Yappa-team en bedrijfsprocessen
  • Onderzoek naar gebruikte tools (Slack, Jira, Notion, Google Workspace)
  • Opzetten van de GitHub-repository en projectstructuur
  • VitePress-website geconfigureerd voor technische documentatie
  • Slack-app "YapHub" aangemaakt in het Slack API-portaal
  • 100 user stories opgesteld verdeeld over 13 epics
  • Project Requirements Document (PRD) opgesteld
  • Geautomatiseerd deploymentscript voor VPS-omgeving
  • Project definitief "KnowledgeHub" genoemd

Technische keuzes

  • POC-runtime: Node.js + @slack/bolt (Socket Mode): gekozen voor snelle validatie van Slack-interactiepatronen
  • MVP-backend: PHP 8.x + Symfony: conform bedrijfsstandardaarden van Yappa
  • Documentatie: VitePress + Mermaid: eenvoudige Markdown-based docs met diagrammen

Week 02: POC Slack & Notion Integratie

Periode: 16 – 20 februari 2026

Gerealiseerd

  • Ontwikkeling van Proof of Concept (POC) voor het koppelen van de Notion database aan de Slack bot.
  • Initiële demonstraties aan Project Managers en CEO.
  • Introductie tot de agile werkmethodiek (Jira board, sprints, daily standups) van het development team.
  • Omzetten van eerste user stories in bruikbare Jira tickets.
  • Documentatie website gemigreerd naar Cloudflare Pages.

Week 03: Multi-repo & Server Migratie

Periode: 23 – 27 februari 2026

Gerealiseerd

  • Bespreking en organisatie van de backlog (nu 250+ user stories).
  • Transitie naar een multi-repository structuur: een persoonlijke ontwikkeling-monorepo gesynchroniseerd met specifieke Yappa sub-repo's voor Slack, Symfony, en VitePress.
  • CI/CD pipelines gebouwd (GitHub Actions) inclusief geplande integraties met Jira.
  • Ontwikkel- en staging servers gemigreerd naar de eigen Yappa cloudhosting infrastructuur.

Week 04: Notion SDK & AI Summaries

Periode: 2 – 6 maart 2026

Gerealiseerd

  • Refactoring van alle Notion API web requests naar het officiële Notion-SDK pakket na codereview.
  • Verbeterde inrichting van ~20 verschillende dynamische Notion Database Views.
  • Ontwikkeling van de backend-infrastructuur voor AI-samenvattingen (op basis van Role & Category).
  • Integratie met Slack voltooid: Modal Views toegevoegd voor directe interactie met samenvattingen.

Week 05: App Home & MVP Structuur

Periode: 9 – 13 maart 2026

Gerealiseerd

  • UI-transitie: Overstap van tijdelijke Modal-views naar een interactieve Slack App Home interface voor een betere gebruikerservaring.
  • Implementatie van de volledige backend-logica voor het regenereren en bekijken van de historie van AI-samenvattingen.
  • Projectplanning verfijnd: Backlog opgesplitst in drie kern-PR's (Input, Process, Output) om de integratie naar de main branch te versnellen.

Week 06: Refactoring & Tests

Periode: 16 – 20 maart 2026

Gerealiseerd

  • Grootschalige refactoring: Verwijderen van "magic strings" en implementatie van een robuust Constants systeem.
  • Modularisering van de Slack (TypeScript) codebase van 20 naar 80+ bestanden voor betere schaalbaarheid.
  • Implementatie van End-to-End (E2E) testing met Playwright en integratie in de CI-pipeline (GitHub Actions).
  • Introductie van een subscription feature: gebruikers kunnen zich nu via Slack abonneren op categorie-specifieke rapportages.

Week 07: Architecturale Afronding, Testing & Documentatie

Periode: 23 – 27 maart 2026

Gerealiseerd

  • Implementatie van het Orchestrator Pattern en type-safe Result DTO's om complexe workflows te centraliseren en de foutafhandeling doorheen de gehele stack consistent te maken.
  • Aanpak van technische schuld door grootschalige refactoring van "magic strings" naar gecentraliseerde constanten en standaardisatie van het logger-gebruik.
  • Stabilisatie van het doelsysteem door middel van het oplossen van asynchrone E2E-test fouten, resulterend in een consistente 100% test pass-rate voor de MVP-oplevering.
  • Fundamentele oplossingen geïmplementeerd voor Slack App Home navigatie-bugs en het verbeteren van de UI-state.
  • Complexe UI/UX upgrade van de VitePress documentatie met een interactief dashboard, image carousel, QA & Testing-hub en de integratie van het nieuwe Yappa Knowledge Hub logo.

Week 08: POC Scoping & Kwaliteitshandhaving

Periode: 30 maart – 3 april 2026

Gerealiseerd

  • Scoping herzien: MVP features tijdelijk gestript om de primaire flow (Input, Process, Output) als gestroomlijnde Proof of Concept (POC) op te leveren en de code reviews te vereenvoudigen.
  • Bestaande monolithische pull requests (~5000 regels code) opgesplitst in kleinere, geïsoleerde architecturale commits.
  • Verdere refactoring toegepast door middel van abstracte baseservices (QueryServiceInterface, PersistenceServiceInterface) en type-safe, vloeiende builder patterns voor Data Transfer Objects (DTO's).
  • Lokale Codekwaliteit (Husky): Pre-commit hooks via Husky uitgebreid en structureel geïntegreerd, waardoor formattering (Prettier) en statische analyse (PHPStan, CS-Fixer) lokaal worden afgedwongen voordat code naar de CI-pipeline kan stromen.

Bijlagen

  • Project Overview
  • Product Requirements Document (PRD)
  • Backlog
  • User Stories Index
  • Roadmap
  • Weekrapporten

Verklarende woordenlijst

TermBeschrijving
OrchestratorDesign pattern voor het coördineren van complexe workflows over meerdere services.
DTO (Data Transfer Object)Object gebruikt om data over te dragen tussen lagen zonder business logica.
Result ObjectEen patroon waarbij een operatie een object teruggeeft met status en data/error.
Notion SDKSoftware Development Kit voor interactie met de Notion API.
Bolt.jsFramework van Slack voor het bouwen van interactieve bots.
ResourceEen enkel kennisitem (tekst, URL, PDF, audio)
DoelgroepRolgebaseerd publiek dat AI-samenvattingsstijl bepaalt
DigestPeriodiek gebundeld rapport per lijst
POC / MVPProof of Concept / Minimum Viable Product
SymfonyPHP-framework gebruikt voor de backend-API
VitePressStatic site generator voor deze documentatie