Skip to content

MVP: Devil's Dictionary Phoenix Rebuild - Hierarchical Knowledge Platform #48

Description

@holden

MVP: Devil's Dictionary Phoenix Rebuild

Overview

Building a fresh Phoenix/Elixir application that showcases the hierarchy of knowledge—from aristocratic dead intellectuals to the plebeian chaos of social media. This is a complete restart, distilling the vision from #45, #46, #47 and technical foundation from #44 into a focused MVP.

Why This Matters

Every dictionary pretends to objectivity. Social media embraces chaos. Devil's Dictionary makes the hierarchy explicit and visible:

  • Dead intellectuals at the top (gilded, authoritative)
  • Institutional sources in the middle (clean, aspirational)
  • Social media at the bottom (chaotic, democratic)

The layout itself is the argument.


Core Concept: The Three Tiers

Tier Sources Visual Treatment
👑 Aristocracy Ambrose Bierce, Samuel Johnson, Classical Philosophers Gilded frames, serif fonts, aged paper texture
📚 Middle Class Wikipedia, WikiQuotes, The Verge, TMDB, Unsplash Clean borders, sans-serif, white backgrounds
📱 The Plebs Urban Dictionary, Twitter/X, Reddit, Memes, GIFs Minimal borders, emoji-heavy, social feed aesthetic

MVP Scope

✅ In Scope (Phase 1)

Core Infrastructure

  • Phoenix 1.7+ project with LiveView
  • PostgreSQL with simple BIGSERIAL IDs + slugs
  • Clerk authentication via clerk_elixir
  • Tailwind CSS with tier-specific styling
  • Basic admin for seeding content

ID Strategy (KISS Principle)

Table ID Type Public Identifier Rationale
users BIGSERIAL Never exposed Internal only
topics BIGSERIAL slug /topics/truth - SEO, shareable
people BIGSERIAL slug /people/ambrose-bierce - memorable
definitions BIGSERIAL Never exposed Referenced by topic
expressions BIGSERIAL Never exposed Quotes, lyrics, poems

Database Schema

# Topics - Core content organization
schema "topics" do
  field :title, :string
  field :slug, :string                    # URL identifier, unique
  field :type, Ecto.Enum, values: [:concept, :thing, :place, :event, :action, :person, :organization, :other]
  field :pronunciation, :string           # Optional phonetic
  field :part_of_speech, :string          # noun, verb, etc.
  field :definition_count, :integer, default: 0  # Cached counter
  timestamps()
end

# People - Authors, creators, notable figures
schema "people" do
  field :name, :string
  field :slug, :string
  field :birth_date, :date
  field :death_date, :date                # nil = living
  field :bio, :string
  field :photo_url, :string
  field :tier, Ecto.Enum, values: [:aristocracy, :middle, :plebs]
  timestamps()
end

# Definitions - Multi-source definitions per topic
schema "definitions" do
  belongs_to :topic, Topic
  belongs_to :author, Person              # nullable
  field :content, :string                 # The definition text
  field :source_name, :string             # "The Devil's Dictionary"
  field :source_url, :string
  field :source_year, :integer            # 1911
  field :tier, Ecto.Enum, values: [:aristocracy, :middle, :plebs]
  field :position, :integer               # Display order within tier
  timestamps()
end

# Expressions - Quotes, lyrics, poems
schema "expressions" do
  field :type, Ecto.Enum, values: [:quote, :lyric, :poem]
  field :content, :text
  field :attribution_text, :string        # "Oscar Wilde"
  belongs_to :author, Person              # Resolved author
  field :source_title, :string            # "The Importance of Being Earnest"
  field :source_url, :string
  field :tier, Ecto.Enum, values: [:aristocracy, :middle, :plebs]
  timestamps()
end

# Expression-Topic join (many-to-many)
schema "expression_topics" do
  belongs_to :expression, Expression
  belongs_to :topic, Topic
  timestamps()
end

# Topic Relationships - Semantic connections
schema "topic_relationships" do
  belongs_to :topic, Topic
  belongs_to :related_topic, Topic
  field :relationship_type, :string       # "synonym", "antonym", "related"
  field :weight, :float
  timestamps()
end

Seed Data (Foundation Sources)

Source Type Data Priority
Ambrose Bierce 👑 Aristocracy ~1000 satirical definitions 🔴 Critical
Samuel Johnson 👑 Aristocracy Historical definitions 🔴 Critical
The Verge New Devil's Dictionary 📚 Middle Tech satire 🟡 Medium

MVP focuses on Bierce as the foundation. Other sources added progressively.

Public Pages

  • Landing Page: Featured topics, search, introduction to hierarchy concept
  • Topic Detail Page:
    • Tiered definition display (Aristocracy → Middle → Plebs)
    • Visual hierarchy with distinct styling per tier
    • Related expressions (quotes) organized by tier
    • Topic relationships sidebar
    • "Completeness" indicator showing which tiers are populated
  • Browse by Letter: Classic dictionary A-Z navigation
  • Person Page: /people/ambrose-bierce with their definitions and bio
  • Mobile-responsive design (critical for sharing)

Topic Page Layout (Visual Hierarchy)

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃  TRUTH                                          noun ┃
┃  /truːθ/                                            ┃
┃  Related: honesty • reality • fact                  ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

┌─────────────────────────────────────────────────────┐
│  👑 THE ARISTOCRACY                                 │
│  ═══════════════════                                │
│                                                     │
│  ╔═══════════════════════════════════════════════╗ │
│  ║ "An ingenious compound of desirability        ║ │
│  ║  and appearance."                             ║ │
│  ║                                               ║ │
│  ║              — AMBROSE BIERCE, 1911           ║ │
│  ╚═══════════════════════════════════════════════╝ │
│                                                     │
│  ┌───────────────────────────────────────────────┐ │
│  │ "Conformity of notion to reality."            │ │
│  │              — SAMUEL JOHNSON, 1755           │ │
│  └───────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│  📚 THE SCHOLARLY                                   │
│  ─────────────────                                  │
│                                                     │
│  Wikipedia summary...                               │
│  [Read more →]                                      │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│  📱 THE PLEBS SPEAK                                 │
│  ──────────────────                                 │
│                                                     │
│  Urban Dictionary: "when ur girl asks where u      │
│  were and u actually tell her lmaooo"              │
│                                   👍 2.3k  👎 234   │
└─────────────────────────────────────────────────────┘

Topic Completeness: ██████░░░░ 3 of 5 layers

Admin Features

  • Seed Bierce definitions from Gutenberg text
  • Add/edit topics and definitions
  • Manage people (authors)
  • View topic completeness metrics

❌ Out of Scope (Phase 2+)

  • External API integrations (WikiQuotes, Genius, TMDB, Giphy, etc.)
  • User-submitted definitions
  • Voting system and bot curators
  • AI-generated "dead author" definitions
  • Media layer (movies, photos, GIFs, art)
  • Social media integrations (Twitter, Reddit)
  • Real-time features beyond basic LiveView

Technical Implementation

Phoenix Generators

# Create project
mix phx.new devils_dictionary --database postgresql

# Contexts and schemas
mix phx.gen.context Content Topic topics \
  title:string slug:string:unique type:enum:concept:thing:place:event:action:person:organization:other \
  pronunciation:string part_of_speech:string definition_count:integer

mix phx.gen.context Content Person people \
  name:string slug:string:unique birth_date:date death_date:date \
  bio:text photo_url:string tier:enum:aristocracy:middle:plebs

mix phx.gen.context Content Definition definitions \
  topic_id:references:topics author_id:references:people \
  content:text source_name:string source_url:string source_year:integer \
  tier:enum:aristocracy:middle:plebs position:integer

mix phx.gen.context Content Expression expressions \
  type:enum:quote:lyric:poem content:text attribution_text:string \
  author_id:references:people source_title:string source_url:string \
  tier:enum:aristocracy:middle:plebs

mix phx.gen.context Content ExpressionTopic expression_topics \
  expression_id:references:expressions topic_id:references:topics

mix phx.gen.context Content TopicRelationship topic_relationships \
  topic_id:references:topics related_topic_id:references:topics \
  relationship_type:string weight:float

Key LiveView Components

# Tiered definition display
defmodule DevilsDictionaryWeb.Components.TieredDefinitions do
  use Phoenix.Component
  
  attr :definitions, :list, required: true
  
  def tiered_definitions(assigns) do
    aristocracy = Enum.filter(assigns.definitions, &(&1.tier == :aristocracy))
    middle = Enum.filter(assigns.definitions, &(&1.tier == :middle))
    plebs = Enum.filter(assigns.definitions, &(&1.tier == :plebs))
    
    assigns = assign(assigns, aristocracy: aristocracy, middle: middle, plebs: plebs)
    
    ~H"""
    <div class="space-y-8">
      <%= if @aristocracy != [] do %>
        <.aristocracy_section definitions={@aristocracy} />
      <% end %>
      
      <%= if @middle != [] do %>
        <.middle_section definitions={@middle} />
      <% end %>
      
      <%= if @plebs != [] do %>
        <.plebs_section definitions={@plebs} />
      <% end %>
    </div>
    """
  end
end

Tier-Specific CSS Classes

/* Aristocracy - Gilded, elevated */
.tier-aristocracy {
  @apply border-2 border-amber-600 bg-amber-50 shadow-lg;
  @apply font-serif;
}

.tier-aristocracy .definition-frame {
  @apply border-4 border-double border-amber-700 p-6;
  background: linear-gradient(to bottom, #fffef5, #f5f0e0);
}

/* Middle Class - Clean, professional */
.tier-middle {
  @apply border border-gray-200 bg-white shadow-sm;
  @apply font-sans;
}

/* Plebs - Raw, social media aesthetic */
.tier-plebs {
  @apply border-0 bg-gray-50;
  @apply font-sans text-sm;
}

.tier-plebs .social-card {
  @apply rounded-lg bg-white p-4 shadow-sm;
}

Slug Generation

defmodule DevilsDictionary.Content.Topic do
  # In changeset
  defp generate_slug(changeset) do
    case get_change(changeset, :title) do
      nil -> changeset
      title -> put_change(changeset, :slug, Slug.slugify(title))
    end
  end
end

User Stories

Visitor Journey

  1. As a visitor, I land on the homepage and see featured words with satirical definitions
  2. I search for "truth" and navigate to the topic page
  3. I see the aristocratic definition from Bierce prominently displayed at top
  4. I notice the visual hierarchy—gilded frames for dead intellectuals, plain boxes for others
  5. I scroll to see how different sources define the same word
  6. I understand viscerally that these sources are not equal
  7. I browse related words and explore the dictionary
  8. I share the topic page with friends

Admin Journey

  1. As an admin, I seed Bierce's complete Devil's Dictionary from Gutenberg
  2. I can add Samuel Johnson definitions for key words
  3. I can create author profiles with biographical info
  4. I can view which topics need more tier coverage

Success Metrics

Quantitative

  • Topics seeded (target: 1000 Bierce definitions)
  • Search usage and navigation patterns
  • Time on topic pages
  • Share/social engagement

Qualitative

  • Users understand the hierarchy concept
  • Visual design effectively communicates tier differences
  • Foundation solid for Phase 2 expansion

North Star

  • A complete, browsable Devil's Dictionary with clear visual hierarchy

Implementation Phases

Phase 1: Core MVP (This Issue)

  • Phoenix project setup with Clerk auth
  • Topic, Definition, Person schemas
  • Seed Bierce definitions
  • Public topic pages with tiered display
  • A-Z browse and search
  • Admin for content management

Phase 2: Content Expansion

  • Samuel Johnson definitions
  • WikiQuotes integration (quotes layer)
  • PoetryDB integration (poems layer)
  • Expression system fully operational

Phase 3: Plebeian Layer

  • Urban Dictionary integration
  • Social media aesthetic for pleb content
  • Visual contrast fully realized

Phase 4: Media Layer

  • Giphy/GIF integration
  • Unsplash photos
  • TMDB movies/TV
  • "How Culture Sees It" section

Phase 5: Community Features

  • User voting on definitions
  • Bot curators with personality influences
  • Canonization system (plebs can rise)

Phase 6: AI Layer

  • Dead author persona definitions
  • "What would Bierce say about NFTs?"
  • Clear AI-generated labeling

References


Open Questions

  1. How prominent should empty tier placeholders be?

    • Recommendation: Subtle "awaiting enrichment" with topic completeness bar
  2. Should we include "living" aristocrats?

    • Recommendation: Death is a credential; living authors go to middle tier
  3. Mobile tier display—accordion or tabs?

    • Recommendation: Vertical scroll with visual breaks, no hiding
  4. How to handle topics with only pleb definitions (e.g., "cryptocurrency")?

    • Recommendation: Show empty aristocracy section as commentary

"The dead know better. The living just have opinions."


Labels

mvp phoenix elixir rebuild phase-1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions