Build journal
APPAdmin 4 min read

Admin Console

Published Jul 6, 2026

A full console to build curriculum, generate content, moderate discussions, manage users, and read analytics.

The admin console at /admin is where Praxis924's curriculum actually gets built. It is the control room for anyone with the admin role: you define what learners can study, turn a bare syllabus into fully written lessons, decide what goes live, keep discussions healthy, manage the people on the platform, and read the numbers that tell you whether any of it is working. This walkthrough takes you from an empty catalog to a published lesson and the day-to-day moderation that follows.

What you'll need

Every route under /admin is guarded server-side by require_admin, so you need an account with the admin role. Admins are auto-seeded at startup from ADMIN_EMAIL / ADMIN_PASSWORD and are redirected to the console on login. You also want at least one working LLM provider key configured (priority order NVIDIA → Groq → Gemini → Hugging Face) — without a key, generation falls back to deterministic placeholder text, which is fine for testing the flow but not for real content.

Step 1 — Build the structure

The curriculum is a three-level hierarchy: Technology → Framework → Lesson. Start at the top.

  1. In the console, create a Technology (the broad subject, e.g. "Python").
  2. Open it and add one or more Frameworks underneath (e.g. "FastAPI").
  3. Optionally attach a dataset to a framework. If you do, Praxis924 chunks it, embeds it with Hugging Face into pgvector, and every lesson generated under that framework is grounded in it via cosine-similarity retrieval — and cites its sources.

Tip: attach the dataset before you generate. Grounding pulls the top-K chunks into the lesson's source; without a dataset, generation falls back to the lesson's raw content. Retrieval also has keyword (ILIKE) and first-N fallbacks, so partial matches still return something.

Step 2 — Draft the syllabus

You do not hand-write every lesson. Inside a framework, kick off syllabus generation and the LLM designs an ordered, basics-to-advanced outline and creates a lesson draft (ContentItem) for each entry. Each draft starts at generation_status: pending and status: draft.

Step 3 — Generate lesson content

Open any lesson at content/[id] and click Generate. This starts the durable DBOS workflow, and the lesson moves to generating. The pipeline:

  1. Builds a grounded source (top-K dataset chunks, or raw content), capped at ~3000 characters so it doesn't blow your tokens-per-minute budget on every prompt.
  2. Generates all four sectionsmain_explanation, practical_explanation, key_principles, summary — each through a review loop: if the AI score is below 7, it rewrites, up to two rounds.
  3. Generates the exercises (mcq, fill_blank, calculation).
  4. Persists everything with citations and flips the lesson to generated.

Because the workflow is durable, a crash or restart resumes from the last completed step rather than starting over. If a provider is down or quota-limited, generation raises LLMUnavailableError and leaves the lesson re-runnable — just click Generate again once the provider recovers.

Step 4 — Fill gaps instead of regenerating

If a lesson came out partial — a missing section, or one exercise kind absent — use Fill Gaps rather than a full regenerate. It regenerates only what's missing, makes zero LLM calls when the lesson is already complete, and filters out placeholder junk so an outage never persists garbage. It's the token-frugal way to top off a lesson.

Step 5 — Publish

When the content looks right, publish it. That flips status from draft to published, and only then does the lesson appear in /learn for learners to read, practice, and discuss. Nothing you're still working on leaks out early.

Step 6 — Moderate and manage

The console isn't only a factory — it's ongoing operations:

  • Discussion moderation — review and act on lesson-scoped threads and issue reports learners file.
  • Contribution review — learners can submit their own lessons; approve or reject them here before they enter the catalog.
  • User management — manage the accounts and roles on the platform.
  • Analytics dashboard — read completion, accuracy, and engagement so you know which lessons land and which need a Fill Gaps pass.

When it goes wrong

Warning: deleting a lesson is a soft-delete to trash with an in-progress guard — Praxis924 won't let you silently pull a lesson out from under learners who are mid-way through it. Heed the guard rather than forcing it.

SymptomLikely causeFix
Lesson stuck generating then failedProvider quota/outage (LLMUnavailableError)Re-run Generate; the lesson stays re-runnable
Content is bland/genericNo dataset on the frameworkAttach a dataset, then Fill Gaps
Placeholder-looking textNo LLM key configuredSet a provider key and regenerate
Lesson not visible in /learnStill draftPublish it
One section or exercise missingPartial generationUse Fill Gaps, not full regenerate

What you get

By the end you have a structured catalog, AI-generated and self-reviewed lessons grounded in your own data, a clean draft-to-published gate, and the moderation and analytics tools to run the platform day to day. Natural next steps: export your published lessons to the git-friendly content pool to share them across instances, and watch the analytics dashboard to decide where the next Fill Gaps pass pays off.

Published in build journal