Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/aurora-borealis/llms.txt

Use this file to discover all available pages before exploring further.

The Case Studies page presents a single long-form project breakdown under the Project Nebula theme. The page is laid out with a sticky sidebar that lists the six major sections of the case study — Problem, Goal, Process, Design Decisions, Dev Decisions, and Result — allowing readers to jump directly to any section or track their reading progress as they scroll. The content is written as a technical narrative that goes significantly deeper than the one-line descriptions in the Mission Catalog.
All page components for this portfolio are inlined inside assets/main.js, which is the compiled Vite production bundle. Do not edit main.js directly. Instead, make changes to the source files before running the Vite build. Editing the pre-built bundle will be overwritten on the next build.

What the Page Displays

The /case-studies route contains:
  1. Sticky sidebar navigation — a fixed-position list of internal anchor links that highlight the currently visible section as the user scrolls.
  2. Six content sections — each section is an <article> element with an id that the sidebar links target.
  3. Project header — the case study opens with the project name, a one-sentence thesis statement, and the tech stack as badges.

The Six Sections

The default case study covers Nebula DB, a distributed Rust key-value database. The six sections are:

Problem

Describes the specific pain point or gap in the ecosystem that the project was built to address.

Goal

Defines the success criteria — what a working solution needed to achieve, stated as measurable outcomes.

Process

Chronicles the development journey: research, prototyping, iteration, and pivots made along the way.

Design Decisions

Explains the key architectural and UX choices — why certain approaches were selected over the alternatives.

Dev Decisions

Covers language choice, library selection, performance trade-offs, and implementation details.

Result

Documents outcomes: performance benchmarks, lessons learned, and what you would do differently.

Content Data Structure

Each section is stored as an object in a CASE_STUDY object in main.js:
// main.js
const CASE_STUDY = {
  projectName: "Nebula DB",
  thesis: "Building a write-optimized distributed key-value store from scratch in Rust.",
  tech: ["Rust", "Tokio", "LMDB", "gRPC", "Docker"],
  sections: [
    {
      id: "problem",
      heading: "Problem",
      content: `Existing key-value stores in the team's stack were tuned for read-heavy workloads.
        Under write amplification from the analytics pipeline, p99 latency spiked past 400 ms.
        We needed a purpose-built store that could absorb burst writes without sacrificing read consistency.`,
    },
    {
      id: "goal",
      heading: "Goal",
      content: `Achieve sub-10 ms p99 write latency at 50,000 writes/second on commodity hardware,
        with a Redis-compatible client interface so the existing application layer needed no changes.`,
    },
    {
      id: "process",
      heading: "Process",
      content: `Started with a spike in Go to validate the protocol layer, then pivoted to Rust after
        benchmarking showed a 3× throughput advantage. Iterated through three storage engine designs
        before settling on an LMDB backend with a custom write-ahead log.`,
    },
    {
      id: "design-decisions",
      heading: "Design Decisions",
      content: `Chose gRPC over REST for internal service communication to reduce serialization overhead.
        Kept the client-facing API Redis-compatible to avoid a migration burden. Decided against
        a leader-election consensus algorithm in v1 to reduce operational complexity.`,
    },
    {
      id: "dev-decisions",
      heading: "Dev Decisions",
      content: `Tokio async runtime handled the connection pool. Unsafe Rust was used in exactly two
        places — both profiled and documented with safety invariants. The Docker image was kept under
        18 MB by building a statically linked binary against musl libc.`,
    },
    {
      id: "result",
      heading: "Result",
      content: `Shipped to staging after 11 weeks. p99 write latency dropped to 7 ms at 50k writes/sec.
        The Redis-compatible interface meant zero application-layer changes. Identified two improvements
        for v2: a proper replication protocol and a Prometheus metrics endpoint.`,
    },
  ],
};

The sidebar renders an anchor list from the sections array. The active section is tracked with an IntersectionObserver:
// main.js — sticky sidebar
function CaseStudySidebar({ sections, activeId }) {
  return (
    <nav className="case-study-sidebar">
      {sections.map((section) => (
        <a
          key={section.id}
          href={`#${section.id}`}
          className={activeId === section.id ? "sidebar-link active" : "sidebar-link"}
        >
          {section.heading}
        </a>
      ))}
    </nav>
  );
}
The activeId state updates whenever a section’s <article> element crosses the 30% viewport threshold — the corresponding sidebar link receives the active class and a highlight style.
The sidebar is position: sticky with a top: 2rem offset. On mobile viewports (below 768 px), the sidebar collapses into a horizontal tab strip at the top of the page instead of a vertical rail.

Replacing with Your Own Project

1

Update the project header

Change CASE_STUDY.projectName, CASE_STUDY.thesis, and CASE_STUDY.tech to match your project.
2

Rewrite each section's content

Replace the content string in each section object. Use backtick template literals to allow multi-paragraph text with natural line breaks.
3

Keep section IDs stable

The sidebar links use the id values as anchor hrefs. Keep the six IDs (problem, goal, process, design-decisions, dev-decisions, result) unless you rename the headings — if you do rename them, update both the id and heading fields together.
4

Add images or diagrams (optional)

Each section object accepts an optional image field. Set it to a path string (e.g., "/images/architecture-diagram.png") and the section component will render it below the text block.
5

Update the route title

If you want the page title to reflect the new project, also update the <title> meta tag in the page’s <Head> component near the top of the page component in main.js.

Adding Additional Case Studies

The current implementation supports one case study at a time. To display multiple case studies:
  1. Convert CASE_STUDY into an array: const CASE_STUDIES = [{ ...nebulaDb }, { ...yourNewProject }].
  2. Add a project selector (tabs or a card grid) at the top of the page that sets a selectedCaseStudy state variable.
  3. Pass CASE_STUDIES[selectedIndex] to the case study renderer.

Projects

The Mission Catalog where Nebula DB appears as an interactive orb.

Writing

The Transmission Archive — shorter-form technical writing.

Build docs developers (and LLMs) love