Privacy

Accept optional first-party analytics or decline. Functional journey and sound preferences stay on this device.

Read the privacy notice

Open to talks and workshops

All projects
CMS & Webactive

Alex CMS

A Next.js CMS with a fully dynamic content-type registry — no hardcoded post models — plus a journey-based homepage, an orchestrator workflow, and per-item content scoring.

Alex CMS should feel like controlled complexity.

The problem

A hand-coded content model means every new kind of content needs a schema migration and new frontend code. That doesn't scale for a site that keeps changing shape.

My role

Design + build

Alex CMS

Content types are rows in a content_types table, not TypeScript models. The registry currently holds fifteen types: ten public (Projects, Signals, Proof, Thinking, Experiments, Connect, Alex OS, Expertise, Skills, Career), one internal (Notes), and four retired types kept as archived rows (Discoveries, Guides, Resources, Builds) — retiring a type is a data change, not a migration. Fields, validation, and display rules are also data. The homepage, navigation, and journey sections are resolved from that same data at request time — there's no code path that assumes a fixed set of content types.

Architecture

Next.js 15 app with a MySQL-backed dynamic registry (content_types, content_type_fields, content_items), a six-stage orchestrator (Create/Improve/Verify/Publish/Learn/Automate), and journey/homepage config also stored as data (journeys, section_settings).

Key decisions

Postgres, Redis and a vector DB are deliberately excluded from the CMS's own stack to keep the system of record simple — those live in Alex OS only, where embeddings genuinely need them.

The workflow-first rebuild kept every old route working: the nine-area admin and the six-stage orchestrator sit on top of the existing URLs instead of replacing them, so nothing bookmarked ever broke.

The in-editor AI panel is the clearest case of feedback beating the first design. It started as a toolbox of 22 actions, and using it made the problem plain — twenty-two equally weighted buttons is the same as no guidance. It was rebuilt around a page-health card, a single recommended next step, and four collapsible stages. The action labels were rewritten outcome-first as a display-only change, with routing still keyed to stable action keys, so renaming a button can never break the automation behind it.

Outcome

Fully dynamic content model with zero hardcoded types.

  • 15 registered content types — 10 public
  • Homepage fully CMS-driven

Limitations

Some content types created early on (Discoveries, Projects, Guides, Resources) were archived when the newer Experience types were introduced and had thin or empty field schemas until this content pass revived them.

Stack

Next.jsTypeScriptMySQLmysql2

Next

Keep building out real content across the revived types; tighten navigation to reflect all public content types.

Evidence

Published Last updated