We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
Interactive Academy: Learning Intelligence Engineering
Inside Prismatic Academy: self-registering learning topics, hands-on labs, ETS-backed topic registry, and how we built an interactive education system within a production platform.
Tomas Korcak (korczis)
Prismatic Platform
Prismatic Academy is an interactive learning system built directly into the platform. Instead of separate documentation sites and external training tools, the Academy provides hands-on exercises alongside the production tools they teach. This post explains how we built it.
Self-Registering Topics
Academy topics register themselves at compile time, similar to OSINT adapters:
defmodule PrismaticAcademy.Topics.OsintFundamentals do
use PrismaticAcademy.Topic
@impl true
def metadata do
%{
title: "OSINT Fundamentals",
slug: "osint-fundamentals",
category: :intelligence,
difficulty: :beginner,
estimated_time: "45 min",
prerequisites: [],
description: "Learn the basics of Open Source Intelligence gathering"
}
end
@impl true
def lessons do
[
%{title: "What is OSINT?", content: &lesson_1/0},
%{title: "Source Categories", content: &lesson_2/0},
%{title: "Your First Query", content: &lesson_3/0, exercise: true}
]
end
end
The use PrismaticAcademy.Topic macro registers the topic in an ETS-backed registry at compile time. No manual registration is needed -- add a topic module, and it appears in the Academy automatically.
ETS-Backed Topic Registry
The TopicRegistry uses the same ETS pattern as the OSINT adapter registry:
defmodule PrismaticAcademy.TopicRegistry do
@table :academy_topics
def register(topic_module) do
ensure_table()
metadata = topic_module.metadata()
:ets.insert(@table, {metadata.slug, topic_module, metadata})
end
def list_topics do
ensure_table()
:ets.tab2list(@table)
|> Enum.map(fn {_slug, _module, metadata} -> metadata end)
|> Enum.sort_by(& &1.category)
end
def get_topic(slug) do
ensure_table()
case :ets.lookup(@table, slug) do
[{^slug, module, metadata}] -> {:ok, module, metadata}
[] -> {:error, :not_found}
end
end
end
Lookups are sub-microsecond. The registry supports the same patterns as the platform's other registries: concurrent reads, lazy initialization, and compile-time loading.
Interactive Exercises
Unlike static documentation, Academy exercises execute real platform code:
Exercises run in a sandboxed context that prevents modifications to production data while providing realistic results.
LiveView-Powered Interface
The Academy interface uses five LiveView components:
|-----------|-------|---------|
/academy/academy/:slug/academy/:slug/:lesson/academy/:slug/:lesson/exercise/academy/progressThe lesson view renders markdown content with embedded interactive components. When a lesson includes an exercise, the ExerciseLive component provides a form-based interface for executing the exercise and comparing results.
Topic Categories
Current Academy topics span four categories:
|----------|--------|-------|
Each topic includes theory lessons, practical exercises, and knowledge checks. Topics are designed to be completed in 30-60 minutes.
Integration with Platform
The Academy links bidirectionally with other platform features:
This creates a learning mesh: wherever you are in the platform, relevant learning resources are one click away.
Building New Topics
Adding a new Academy topic requires a single Elixir module:
lib/prismatic_academy/topics/your_topic.ex2. Implement the Topic behaviour (metadata + lessons)
3. Compile -- the topic appears automatically
No routing changes, no configuration files, no database entries. The self-registration pattern eliminates the ceremony of adding new content.
Conclusion
The Academy demonstrates a pattern that applies beyond education: self-registering modules that appear in the system automatically at compile time. Whether it is OSINT adapters, Academy topics, or blog articles, the pattern is the same -- define a behaviour, implement it, and let the registry handle discovery.
Start learning at [Academy](/academy/) or browse the [Glossary](/glossary/) for quick reference on platform concepts.