Axonis

Rol

Solo end-to-end ⁠— productstrategie, UX, data-engineering, FastAPI-backend, React-frontend, Cytoscape.js-visualisatie, designsysteem, AI-integratie (Groq) en DevOps

Klant

Zelf-geïnitieerd product

Disciplines

Productdesign · UX · Datavisualisatie · Informatiearchitectuur · Prototyping

Jaar

2026

Typ een domein, zoals AI-tutoring of CSRD-rapportage, en krijg binnen een minuut een interactieve knowledge graph van de concepten, onderzoeksclusters en kansen voor producten, opgebouwd uit open data. Solo gebouwd nov. 2025 ⁠– mei 2026, in oktober 2026 herontworpen en omgedoopt tot Axonis; 254 geautomatiseerde tests, WCAG 2.2 AA, €0/maand

Probleem
Een domein leren kennen op dag één kost productmanagers uren versnipperd zoekwerk; de open data is er wel, maar geen enkele tool brengt ze samen tot een kaart
Inzicht
De ontbrekende laag is niet de visualisatie maar het redeneren over opportuniteiten ⁠— clusters scoren waar het onderzoek dicht is en producten schaars
Oplossing
Ik bouwde (solo, end-to-end) een tool die Wikidata + OpenAlex omzet in een interactieve graph, gescoorde opportunity-kaarten en een brief in minder dan een minuut
Resultaat
Live op axonis.app; 254 geautomatiseerde tests, WCAG 2.2 AA, €0/maand ⁠— portfolioproject, voorlopig nog geen externe gebruikers

Elk nieuw initiatief begint met dezelfde ongestructureerde zoektocht

Je weg vinden op dag één in een onbekend domein kost productmanagers en onderzoekers uren versnipperd zoekwerk. De data die je nodig hebt om de vraag ‘hoe zit dit domein in elkaar?’ te beantwoorden, bestaat al in open, vrij gelicentieerde datasets ⁠— Wikidata en OpenAlex ⁠— maar geen enkele tool brengt ze samen tot iets navigeerbaars. AI-assistenten antwoorden in lopende tekst; in een alinea zie je geen cluster en zie je niet waar in de markt nog niemand zit.

De ontbrekende laag is niet de visualisatie ⁠— dat is intussen de standaard. Het gaat om redeneren over opportuniteiten: clusters scoren waar het onderzoek dicht is en producten schaars

Het startpunt: open een kant-en-klare demokaart en zie binnen enkele seconden een gat, of typ een onderwerp en de pipeline start op de achtergrond. De letterbol rechts kun je vastpakken en laten draaien

Veertien tools onderzocht; geen enkele redeneert over kansen

Als zelfgestuurd project bestond de discovery uit een gestructureerde studie van het concurrentielandschap plus dogfooding ⁠— geen reeks externe gebruikersinterviews, en deze case is daar expliciet over. Ik nam veertien tools onder de loep, verdeeld over vier categorieën (citatiegraphs van papers, AI-onderzoeksassistenten, apps voor notitie- en relatiegraphs en marktintelligentieplatformen) en scoorde elke tool op vijf vlakken: automatisch inlezen van open data, entity-relationship-graphing, opportuniteitsdetectie, gestructureerde output en AI-synthese.

Het patroon was telkens hetzelfde: graphtools voor papers (Connected Papers, ResearchRabbit) hebben de graph, maar enkel over publicaties, en redeneren niet over opportuniteiten. AI-assistenten (Elicit, Consensus, Perplexity) vatten samen in geciteerde tekst ⁠— sterke output, maar geen navigeerbare entity-graph. Canvassen voor notitiegraphs (Obsidian, Roam, Kumu) tekenen prachtige graphs, maar vragen dat je elk knooppunt zelf aanmaakt, wat op dag één van een nieuw domein nutteloos is. Marktintelligentieplatformen (Crayon, Klue) volgen concurrenten, geen conceptdomeinen. Geen van de veertien combineerde alle drie: automatisch open data inlezen + een echte entity-relationship-graph + redeneren over productopportuniteiten.

Oriënteren ⁠→ structuur vinden ⁠→ kansen spotten ⁠→ overdragen

De backend voert op aanvraag een pipeline van negen stappen uit: Groq breidt het onderwerp uit naar ~8 zoektermen; Wikidata en OpenAlex worden parallel bevraagd; rapidfuzz ontdubbelt entiteiten bij een gelijkenisdrempel van 88; NetworkX berekent degree- en betweenness-centraliteit; Louvain-gemeenschapsdetectie groepeert knopen in clusters; een opportuniteitsscoremodel weegt omvang, onderzoeksdichtheid, productgap en brugpotentieel af; Groq schrijft verhalende opportuniteitskaarten voor de vijf beste clusters, met een deterministische template-fallback. Papers worden eerst op relevantie en pas daarna op citaties gekozen, één modelaanroep zeeft naamgenoten eruit voor ze in de graph komen, en de instellingen van hun auteurs komen erbij als de spelers achter het onderzoek. Elke knoop krijgt een beschrijving van één regel uit OpenAlex of Wikidata. Tijdens het bouwen toont het bouwscherm het echte stadium, de aantallen en een log met tijdstempels zoals de server ze meldt, en tekent het de opgeslagen graph nog voor de AI-kaarten klaar zijn.

De vier weergaven ná de graph sluiten exact aan op de manier waarop je verkent: de physics-based graph om je te oriënteren (sleep een knoop en de hele graph reageert), Clusters om structuur te vinden (Louvain-gemeenschappen gerangschikt op opportuniteitsscore), Opportunities om kansen te spotten (kaarten met risicobadges, waarom het ertoe doet, een balk voor de bewijskracht en een uitsplitsing van hoe de score is opgebouwd), en een Research Brief met één klik om over te dragen ⁠— gerenderde HTML, te downloaden als .md, af te drukken naar PDF. Ask the map beantwoordt vragen over het domein met inline [n]-bronverwijzingen; ga er met de muis over en de bijbehorende knoop licht op in de graph.

axonis.app — live-voorbeeld
Live-demo
axonis.app
Openen

Live ⁠— typ een domein en verken de graph

Clusters

Opportunities

Research Brief

Bottom sheet op mobiel

Axonis: één accent, echte voortgang, een graph die je kunt bevragen

In oktober 2026 kreeg het product een eigen naam en domein, Axonis, en een nieuw designsysteem. Uit een moodboard van 162 beelden maakte ik acht concepten en koos er één: donker, één magenta accent, Martian Mono met Mona Sans, vierkante knoppen tussen haken. De spacing komt uit één opgemeten referentie, de Railway-app: haar ladder van 8, 16, 24, 32 en 48, een topbalk van 54 px en een inspector van 360 px. Elk element kreeg een referentie voor het getekend werd, en de Figma-bibliotheek is opgebouwd uit atomen, moleculen en organismen.

Het redesign repareerde ook iets wat de oude build stilletjes fout deed. De bouwchecklist schoof op een timer van 3,8 seconden door, dus een stap kon afgevinkt worden voor de server zover was. Nu meldt de server zijn echte stadium, aantallen en gebeurtenissen, en het scherm toont alleen die. Is er nog niets gemeld, dan staan de stappen er als de gebruikelijke volgorde, zonder vinkjes.

Elk vinkje, elk getal en elke logregel komt van de server. De voorvertoning start pas als de nieuwe entiteiten zijn opgeslagen, zodat een rebuild nooit de oude kaart toont

⌘K: spring naar elke knoop of voer een actie uit

Ask: [n]-verwijzingen zijn aan knopen gekoppeld

De graph werd iets wat je kunt bevragen in plaats van alleen bekijken. Een TYPES-chip opent de legenda die types filtert, een Depth-knop toont alleen de één of twee stappen rond een knoop, de randen van de geselecteerde knoop lichten op en labels blijven beperkt tot de acht best verbonden buren. Een lijstweergave spiegelt het canvas als sorteerbare tabel, zodat de kaart ook werkt met toetsenbord en schermlezer.

De lijstweergave is de toegankelijke spiegel van het canvas: sorteerbaar, filterbaar, en elke naam opent de knoop in de inspector

Eén accent, gemeten spacing en leesbaarheid van dichte graphs

B² is per definitie donker: vier grijzen, één tekstkleur en één magenta accent, dat selectie, bronverwijzingen en live status markeert en verder niets. Lopende tekst haalt AA op elk oppervlak. Het donkerste grijs haalt het contrast voor tekst niet, dus een vastgelegde regel reserveert het voor decoratieve en inactieve elementen. De radius is overal nul. Op een telefoon wordt het zijpaneel een bottom sheet, en elke knop krijgt een aanraakdoel van 44 px.

De leesbaarheid van dichte graphs vroeg om eigen oplossingen. De vorm van een knoop codeert het type, zodat kleur vrij blijft voor status. Labels staan op een eigen vlak, zodat randen nooit door de letters lopen, alleen de drie grootste hubs zijn fel, en uitlichten zoomt nooit verder dan 1,2× in zodat een handvol knopen geen reclameborden worden. De tweefasige cola-layout houdt elke knoop in live physics, dus de graph reageert op elke sleepbeweging.

Spotlight-tour zonder dependencies: opent via de Tour-knop of ⌘K, bedienbaar met het toetsenbord en houdt rekening met prefers-reduced-motion. Ze start niet meer vanzelf: de eerste blik op een kaart is voor de gaten

Een gestructureerde review ving twee productiebugs op nog voor gebruikers ze konden tegenkomen

Voor ik het MVP als klaar bestempelde, voerde ik een gestructureerde codereview uit. Die legde twee echte productiebugs bloot: DELETE /projects/{id} verwijderde entiteiten en relaties, maar geen clusters/opportunities, wat een foreign-key-schending veroorzaakte die delete op productie-Postgres brak; en een stored XSS in het printvenster van de brief, waarbij door het LLM gegenereerde Markdown en de van de gebruiker afgeleide bestandsnaam via document.write werden weggeschreven met enkel < geëscaped. Allebei opgelost en vastgezet achter tests.

De geautomatiseerde testsuite draait tegen een wegwerp-SQLite-database met AI uitgeschakeld ⁠— ze raakt nooit de productiedatabase of Groq aan. 167 pytest-tests dekken project-CRUD, brief-gating, de delete-cascade-regressie, de model-fallback, bouwvoortgang, bronverwijzingen, de score-uitsplitsing, de bescherming van demo’s, rate limiting, eigenaarstokens, het dagelijkse AI-budget, invoer- en verzoeklimieten, uploads, de relevantiefilter, clusternamen, knoopbeschrijvingen, echte 404’s en caching, en de linkvoorbeelden per demo. 87 Vitest / Testing Library-tests dekken de toestandsschermen en meldingen, het Ask-paneel en zijn verwijzingen, de command palette, de lijstweergave, de gap-kaarten, de tour, het telefoonpaneel, eigenaarstokens, toestemming voor analytics en het veilig renderen van de brief. Alle 254 slagen, in CI bij elke pull request.

De review verdiende zichzelf al terug met die ene delete-bug ⁠— stilletjes kapot in productie, en een bug die geen enkele handmatige doorklik had gevonden

Reviews bleven ook na het redesign lonen. Zonder accounts kon iedereen de demokaarten verwijderen of opnieuw bouwen, dus die zijn nu alleen-lezen en de dure acties zijn per IP begrensd. Een securityreview van die begrenzer ontdekte dat hij de eerste X-Forwarded-For-waarde vertrouwde, die de client zelf bepaalt, zodat een vervalste header hem kon omzeilen. Nu leest hij het adres dat de proxy toevoegde, en zijn geheugen is begrensd.

Een tweede ronde in oktober richtte zich op wat de demokaarten echt lieten zien. Een kaart over locaties voor zonneparken bevatte een cluster over een Marsrover, een kaart over een langer leven bevatte sterrenhopen: OpenAlex matchte losse woorden, en elk paper met dezelfde naam trok zijn onderwerpen en instellingen mee. Eén modelaanroep zeeft de papers nu, met het onderzoeksveld van elk paper erbij, voor er iets in de graph komt, en op de herbouwde kaarten bleven geen clusters buiten het onderwerp over. Prompts worden niet meer op het oog bijgesteld: met de hand gelabelde sets van 89 kandidaat-papers en 62 echte clusters scoren elke promptwijziging, en het aandeel clusternamen dat alleen uit woorden van hun leden bestaat, steeg van ongeveer 0,6 naar ongeveer 0,9. Dezelfde ronde maakte kaarten van vóór de eigenaarstokens alleen-lezen, zette het dagelijkse AI-budget in de database en zorgde ervoor dat Ask niet meer in het Engels antwoordt op een vraag in een andere taal.

Eerste blik: de grootste gaten lichten vanzelf op, één keer per sessie

Zelfs de 404 is een gat op de kaart

AI die verrijkt maar nooit dragend is

De makkelijke versie van deze case zou een discovery-traject met externe gebruikersinterviews beschrijven. Dat was er niet. Het verzinnen ervan zou bij de eerste interviewvraag sneuvelen, dus zegt de case onomwonden wat discovery werkelijk was: een gestructureerde concurrentiestudie plus dogfooding. Dat werk leverde de daadwerkelijke positionering op ⁠— graphtools voor papers hebben de graph, maar alleen over publicaties en redeneren niet over opportuniteiten, terwijl marktintelligentieplatformen concurrenten volgen in plaats van conceptdomeinen. Visualisatie is de standaard, dus ging de inspanning naar de scorelaag.

De architectuurbeslissing die ik het hardst zou verdedigen is dat AI nooit dragend is. Elke Groq-aanroep heeft een deterministische fallback, en het product werkt volledig zonder Groq-sleutel. In een portfolio vol LLM-functies is dat de onmodieuze keuze. Het kost een tweede codepad voor elk verrijkt veld, en het betekent dat een storing op de gratis tier het product minder goed laat werken in plaats van het stil te leggen.

In oktober 2026 werd die beslissing echt getest. Groq haalde het model weg dat de app aanriep, en elke AI-functie viel terug op templates. Het product bleef werken, en dat was precies de bedoeling. Het verborg ook de storing, en dat was het niet: niets faalde luid tot de logs van een rebuild een muur van 404’s lieten zien. Graceful degradation heeft een signaal nodig. Aanroepen lopen nu via één module die een lijst modellen afloopt, een leeg antwoord als fout telt en elke fallback logt.

De testsuite ná de pipeline schrijven in plaats van ernaast was een fout, en daar is het bewijs van. De suite vond uiteindelijk twee echte productiebugs: een delete die entiteiten en relaties verwijderde, maar clusters niet, wat een foreign-key-schending op productie-Postgres veroorzaakte, en een stored XSS in het printvenster van de brief waar door een LLM gegenereerde Markdown en een van de gebruiker afgeleide bestandsnaam werden weggeschreven met alleen punthaken geëscaped. De delete-bug leefde meerdere commits lang. De tests kwamen te laat om hem eerder te vangen.

Live, dichtgetimmerd, gratis ⁠— en eerlijk over wat nog niet gevalideerd is

Live op axonis.app. Voor het eerst gelanceerd in juni 2026 en in oktober herontworpen. Solo gebouwd in zeven maanden naast ander werk. De stack is bewust saai en gratis: Wikidata + OpenAlex voor data (€0), de gratis tier van Groq voor AI (€0), networkx + python-louvain voor graph en metrics (€0), FastAPI + SQLAlchemy 2.0-backend, React + Vite + Cytoscape.js-frontend, Docker ⁠→ Coolify op een zelfgehoste Hetzner (€0 marginaal). Elke Groq-aanroep heeft een deterministische fallback ⁠— AI verrijkt, maar is nooit dragend; het product werkt volledig zonder Groq-sleutel.

Wat ik anders zou doen: tests schrijven naast de pipeline in plaats van erna (de delete-cascade-bug leefde meerdere commits lang), graph-knopen eerder beperken voor dichte onderwerpen (layout-tuning kwam achteraf), en de batch-vs-on-demand-afweging van tevoren benoemen zodat de polling-UX eerder vorm krijgt. Eerlijk bekeken levert de opportunity-scoring betrouwbaar een aannemelijke eerste kaart op, maar of de gescoorde kansen kloppen, kunnen alleen echte productmanagers zeggen die erop reageren ⁠— dat is de volgende prioriteit, vóór meer features.

De kaart: vorm codeert het type, de geselecteerde knoop laat zijn randen oplichten en de inspector toont zijn metrics en verbindingen

Bronnen

Volgend project
Tenderdex