Wexa AI Take-Home Assignment β Graph Database Application
Backed by CognoDB Cloud (openCypher over Bolt protocol) using the officialneo4j-driver.
AfroGraph is an interactive knowledge graph exploring the talent incubators (YBNL, Mavin, Starboy), sound architect producers, and multi-generational sample lineages powering the global Afrobeats phenomenon.
- Inspiration & Lineage: AfroGraph natively expands on OlamideVerse (GitHub), transforming an editorial cultural archive into a living, multi-label, multi-producer graph ecosystem.
- Live Hosted Demo: afrograph.vercel.app
- GitHub Repository: github.com/ajibolagenius/afrograph
Music ecosystems are deeply interconnected networks. Relational databases require complex joins and recursive CTEs that struggle with variable-depth relationships:
| Capability | Relational (SQL) | Graph (CognoDB / openCypher) |
|---|---|---|
| Shortest Path (Degrees of Separation) | Expensive recursive CTEs (WITH RECURSIVE), cycle prevention logic, full table scans. |
Native shortestPath() traversal via pointer-chasing in constant hop time. |
| Incubation Trees & Blast Radius | Joining 5+ normalized tables with composite GROUP BY and LEFT JOINs. |
Single pattern match: (:RecordLabel)<-[:SIGNED_TO]-(:Artist)-[:MENTORED]->(:Artist). |
| Multi-Hop Sample Lineage | Hierarchical parent-child lookups across heterogeneous entities are slow. | Seamless variable-length jump: (:Sample)<-[:SAMPLED*1..4]-(:Track)<-[:RELEASED]-(:Artist). |
| Circular Cliques (Triangles) | 3-way self-joins on dense tables with expensive inequality filters. | Expressive declarative pattern: (a)-[:COLLABORATED_WITH]->(b)-[:COLLABORATED_WITH]->(c)-[:COLLABORATED_WITH]->(a). |
- Nodes:
:Artist,:Producer,:RecordLabel,:Track,:Sample - Edges:
[:FOUNDED],[:SIGNED_TO],[:MENTORED],[:RELEASED],[:FEATURED_ON],[:PRODUCED],[:SAMPLED],[:INFLUENCED_BY],[:COLLABORATED_WITH]
graph LR
Artist["π¨ :Artist"] -->|"FOUNDED / SIGNED_TO"| Label["ποΈ :RecordLabel"]
Artist -->|"MENTORED / COLLABORATED_WITH"| Artist
Artist -->|"RELEASED / FEATURED_ON"| Track["π΅ :Track"]
Producer["π§ :Producer"] -->|"PRODUCED"| Track
Track -->|"SAMPLED / INFLUENCED_BY"| Sample["π» :Sample"]
MATCH (start:Artist {id: $startId}), (target:Artist {id: $targetId})
MATCH path = shortestPath((start)-[:COLLABORATED_WITH|FEATURED_ON|RELEASED|PRODUCED|MENTORED*1..8]-(target))
RETURN path, nodes(path) AS nodes, relationships(path) AS relationships, length(path) AS lengthMATCH (label:RecordLabel {id: $labelId})
OPTIONAL MATCH (label)<-[:FOUNDED]-(founder:Artist)
OPTIONAL MATCH (artist:Artist)-[s:SIGNED_TO]->(label)
OPTIONAL MATCH (artist)-[m:MENTORED]->(mentee:Artist)
OPTIONAL MATCH (artist)-[rel:RELEASED]->(t:Track)
OPTIONAL MATCH (guest:Artist)-[f:FEATURED_ON]->(t)
RETURN label, founder, collect(DISTINCT artist) AS artists, collect(DISTINCT mentee) AS mentees, collect(DISTINCT t) AS tracksMATCH (sample:Sample {id: $sampleId})
OPTIONAL MATCH (t:Track)-[s:SAMPLED|INFLUENCED_BY]->(sample)
OPTIONAL MATCH (creator)-[r:RELEASED|PRODUCED]->(t)
RETURN sample, collect(DISTINCT t) AS tracks, collect(DISTINCT creator) AS creatorsMATCH (p:Producer)-[:PRODUCED]->(t:Track)
OPTIONAL MATCH (a:Artist)-[:RELEASED]->(t)
WITH p, count(DISTINCT t) AS trackCount, count(DISTINCT a) AS artistCount,
collect(DISTINCT a.name) AS artists
RETURN p.name AS producer, p.signatureTag AS tag, trackCount, artistCount, artists
ORDER BY artistCount DESC, trackCount DESCMATCH (a:Artist)-[:COLLABORATED_WITH]->(b:Artist)
MATCH (b)-[:COLLABORATED_WITH]->(c:Artist)
MATCH (c)-[:COLLABORATED_WITH]->(a)
WHERE a.id < b.id AND b.id < c.id
RETURN a.name AS artist1, b.name AS artist2, c.name AS artist3AfroGraph was defensively hardened and audited via Vibe Secure Me:
- Unauthenticated DB Mutation Guard (CWE-306 / OWASP A01): Protected
POST /api/seedwithADMIN_SEED_SECRETbearer validation. - Cypher Injection & Exhaustion Defense (CWE-89 / OWASP A03): Enforced Read-Only execution (blocking
CREATE,MERGE,DELETE,SET,DROP) with auto-appendedLIMIT 100in/api/query. - Label Whitelist Validation (CWE-89): Sanitized
/api/graphinputs against a strictALLOWED_LABELSenum. - Information Disclosure Prevention (CWE-200 / OWASP A05): Masked internal CognoDB instance IDs in public health endpoints.
- HTTP Security Headers & Image Isolation (CWE-693): Configured
X-Frame-Options: DENY,nosniff, and restricted image sources to trusted CDN domains.
- Create a free instance on console.cognodb.com.
- Copy your Bolt URI and generated password.
COGNODB_URI=bolt+s://<instance-id>.databases.cognodb.cloud
COGNODB_USERNAME=cognodb
COGNODB_PASSWORD=<your-password>npm install
npm run seed # Seeds realistic Afrobeats dataset into CognoDB
npm run dev # Starts Next.js app on http://localhost:3000βββ scripts/
β βββ seed.ts # CLI dataset seeder with index constraints
βββ src/
β βββ app/
β β βββ api/
β β β βββ graph/route.ts # Neighborhood & category filtering API
β β β βββ health/route.ts # Database connection health & latency API
β β β βββ lineage/route.ts # Talent tree & sample lineage API
β β β βββ path/route.ts # Shortest path / Degrees of separation API
β β β βββ query/route.ts # Parameterized Cypher query runner API
β β β βββ seed/route.ts # Admin database seed endpoint
β β β βββ stats/route.ts # Graph analytics & producer centrality API
β β βββ cypher/page.tsx # Interactive Cypher Studio & SQL benchmark
β β βββ labels/page.tsx # Record label talent trees & blast radius
β β βββ paths/page.tsx # Degrees of separation shortest path finder
β β βββ samples/page.tsx # Musical DNA & sample heritage lineage
β β βββ page.tsx # Main interactive ecosystem graph canvas
β βββ components/graph/
β β βββ GraphCanvas.tsx # High-DPI D3 force-directed canvas with pan/zoom/drag
β β βββ NodeDetailsModal.tsx # Node inspection slide-over drawer
β βββ lib/
β βββ neo4j.ts # CognoDB Bolt driver singleton & session pool
β βββ cypher.ts # openCypher query catalog & documentation
β βββ seed-data.ts # Realistic Afrobeats dataset
In alignment with the assignment guidelines, AI agent assistance was used during development for troubleshooting tricky canvas rendering/simulation race conditions, benchmarking parameterized queries, and refining documentation structure.
MIT β Built by Ajibola Akelebe for Wexa AI.