alumni_lookup

Status: ✅ COMPLETE (All Sub-Phases 3.1-3.11 Delivered)
Estimated Effort: 4-6 weeks
Prerequisites: Phase 2 Complete (Community Leadership)

Last Updated: January 17, 2026 (Phase 3 Wrap Complete)


Completion Summary: Sub-Phase 3.11 — Dashboard Redesign

Completed: January 2026
Test Results: 2267 tests, 0 failures, 0 errors

What Was Implemented

Component Details
Dashboard Google News layouts for Discussions (1+3) and News (1+3) sections
Events Section Date badge rows with community pills using _event_row partial
Communities Card Combined with CL indicator (⭐), Leadership Dashboard button for CLs
Community Show Restructured to match dashboard pattern, width aligned to max-w-7xl
Community Index Complete redesign as “Community Select” with My Communities, You’re Invited, Explore All
Layout Fixes Background opacity increased, footer visibility fixed, consistent max-w-7xl widths

Files Modified


Completion Summary: Sub-Phase 3.10 — Index Page Reorganization

Completed: January 2026
Test Results: 2267 tests, 0 failures, 0 errors

What Was Implemented

Component Details
News Index Google News-style layout (1 featured + 3 compact cards)
Events Index Upcoming events with Google News layout, Past Events page
Discussions Index Cross-community page at /discussions route
Partials _news_card_compact, _event_card_compact, _discussion_card_compact
Event Row _event_row partial with date badge styling

Files Created

Files Modified


Completion Summary: Sub-Phase 3.1 — Boards Infrastructure

Completed: January 15, 2026
Test Results: 2140 tests, 0 failures, 0 errors (112 new tests added)

What Was Implemented

Component Details
Migrations 8 total: cp_board_posts, cp_board_comments, cp_board_reactions, cp_post_flags, cp_user_blocks, cp_hidden_contents, cp_moderation_actions, allow_null_moderator
Models 7 new: BoardPost, BoardComment, BoardReaction, PostFlag, UserBlock, HiddenContent, ModerationAction
ActionText Rich text for posts (40K limit) and comments (2K limit)
Controller Cp::BoardsController with index/show actions (read-only for 3.1)
Views boards/index, boards/show, _comment partial, discussions section on community show
Activity Events board_view, post_view for analytics
National Community “Alumni Champions” created (ID: 47, national: true)
Fixtures 8 fixture files with sample data
Tests 96 model tests + 16 controller tests = 112 new

Key Design Decisions Implemented

Files Created

Migrations:

Models:

Controller & Views:

Tests:

Fixtures:

Seeds:

Deferred to Phase 3.2


Table of Contents

  1. Overview
  2. Why This Phase Exists
  3. Key Design Decisions
  4. Board Types
  5. Sub-Phases
  6. Data Model
  7. Surfacing & Discovery
  8. Definition of Success
  9. Tests to Create
  10. MVP vs Backlog
  11. Documentation Updates

1. Overview

Phase 3 introduces Discussion Boards — enabling Champions to have threaded conversations within their communities and across the national Champion network. The design prioritizes belonging and safety over engagement metrics, with robust moderation tools and clear community guidelines.

What This Phase Delivers

Feature Description
Per-Community Boards Every community auto-gets a discussion board (with on/off toggle)
National Board Single “Alumni Champions” board for cross-community discussions
Collapsible Threaded Comments Reddit-style nesting with collapse at depth 3+
Emoji Reactions Reuses existing MessageReaction pattern
Rich Text Formatting Bold, italic, bullets, numbered lists, links
User Safety Controls Report, hide content, block users
Moderation Tools Community Leaders can moderate their community’s board
Notification Integration Champions notified of replies

Architecture Decision

Every community automatically has a discussion board — no separate “board creation” step. When a community is created, its board exists. Admins can disable boards per-community via a toggle. This simplifies the model and ensures consistent coverage.


2. Why This Phase Exists

From JOBS-TO-BE-DONE.md:

Job C5: Stay in the Loop

“When I’m busy with life but want to stay connected to Belmont, I want to see what’s happening without active effort, so I can feel part of the community even when I’m not contributing.”

Job L3: Communicate with My Community

“When I have news or announcements for my community’s Champions, I want to reach them all at once, so I can keep everyone informed without individual emails.”

The Gap

Champions can find each other (Directory) and message privately (Messaging), but there’s no public forum for community-wide discussions, announcements, or Q&A. Discussion boards fill this gap.

Design Philosophy: Belonging Over Engagement

This is NOT Facebook, Reddit, or Quora. Our boards prioritize:

We explicitly avoid:


3. Key Design Decisions

These decisions were finalized in the January 2026 planning interview:

Decision Choice Rationale
Reactions Emoji reactions (mirror Messages) Reuse existing code, warmer than upvotes
Threading Collapsible deep nesting (Reddit-style) Enables rich conversation threads
Thread Display Show 2 levels, collapse at 3+ Clean UI with “View X more replies”
Post Sorting Latest activity (last_activity_at) Active threads rise to top
Comment Sorting Latest activity in thread Fresh conversation first
Rich Text Bold, italic, bullets, numbers, links Posts AND comments
Post Limit 40,000 characters With truncation + “See more”
Comment Limit 2,000 characters Keeps discussions clean
Images Single image per post MVP simplicity
Edit Window 30 minutes With “Edited” indicator
User Controls Report, Hide content, Block user Safety-first approach
CL Controls Hide, Lock, Pin, Escalate Current spec is sufficient
Anonymous Not allowed Everyone shows their name
Board Toggle Admin can disable per community Flexibility for edge cases
Time Decay 14 days (hardcoded constant) For popularity calculations
National Board Only global channel Single place for cross-community content
National Membership Auto-join, cannot leave, can mute Ensures announcements reach everyone
National Visibility Verified Champions only Maintains community trust

4. Board Types

Per-Community Boards

Every Cp::Community has an associated discussion board.

Community Type Example Board
District “Nashville District” board
College “College of Music” board
Major “Music Business Major” board
Affinity “Greek Life” board
Industry “Healthcare” board
Custom “Young Alumni” board

Access: Members of the community can view and post. Non-members can view but not post (configurable per community).

National Board: “Alumni Champions”

A single national board for all verified Champions.

Purpose:

Access: All verified Champions can view and post.

❌ Eliminated Boards

Based on scope decisions, the following are NOT separate boards:


5. Sub-Phases

Sub-Phase 3.1: Board Infrastructure ✅ COMPLETE

Goal: Create the database structure, base UI, and board on/off toggle.

Deliverables:

Key Decisions:


Completion Summary: Sub-Phase 3.2 — Posting & Commenting

Completed: January 15, 2026
Test Results: 2161 tests, 0 failures, 0 errors (20 new controller tests added)

What Was Implemented

Component Details
Post Creation New post form with title (100 char limit), rich text body (40K limit), optional single image upload
Comment System Full CRUD for comments with threaded replies (MAX_DEPTH=2), parent-child relationships
Edit/Delete 30-minute edit window with “Edited” indicator, delete anytime for authors
Character Limits Title: 100 chars, Post body: 40K chars, Comment body: 2K chars
Truncation Post body truncation with “See more” link on listing pages
Activity Tracking Events: post_created, post_edited, post_deleted, comment_created, comment_edited, comment_deleted
Community Guidelines Guidelines reminder in post composer with link to full FAQ
FAQ Updates 9 new FAQ entries for Discussions category in config/faq.yml
Communities Index Discussion section added to featured community cards with recent posts
Controller Tests 20 new tests for BoardCommentsController (create, edit, update, destroy)

Key Design Decisions

Files Created

Controller Tests:

Files Modified

Models:

Views:

Tests:

Configuration:

Deferred Items


Sub-Phase 3.2: Posting & Commenting ✅ COMPLETE

Goal: Champions can create posts and reply with threaded comments.

Deliverables:

Permissions: | Action | Who Can Do It | |——–|—————| | Create post | Community members | | Create comment | Community members | | Edit own post | Author (within 30 minutes) | | Delete own post | Author (anytime) | | Edit own comment | Author (within 30 minutes) | | Delete own comment | Author (anytime) |


Sub-Phase 3.3: Engagement & Reactions

Status: ✅ Complete (January 2026)
Test Results: 2173 tests, 0 failures, 0 errors

Goal: Enable engagement through reactions and smart sorting.

Deliverables:

What Was Implemented:

Component Details
Routes POST /discussions/:id/toggle_reaction, POST /discussions/:id/comments/:id/toggle_reaction
Models popularity_score method, by_popularity scope, reaction helpers on BoardPost/BoardComment
Views _reactions.html.erb partial (horizontal emoji bar), _post_card.html.erb partial with hot badge
Stimulus board_reactions_controller.js for AJAX toggle
Sorting Dashboard (top 5), Community index (top 2), Community show (top 3), Discussion index (hot 2 + chronological)
Activity reaction_added event type for analytics

Popularity Formula:

TIME_DECAY_DAYS = 14

def popularity_score
  age_in_days = (Time.current - created_at) / 1.day
  time_factor = [1.0 - (age_in_days / TIME_DECAY_DAYS), 0].max
  (reactions_count * 2) + (comments_count * 3) + (time_factor * 10)
end

Files Created:

Technical Note: by_popularity scope returns an Array (uses Ruby sort_by). Pattern: .includes().by_popularity.first(n) — never chain .limit() or .includes() after by_popularity.


Sub-Phase 3.4: User Safety Controls

Status: ✅ Complete (January 2026)

Goal: Champions can protect themselves from unwanted content.

What Was Implemented:

Feature Details
Flag content Button on posts and comments with reason selector
Flag reasons spam, inappropriate, harassment, off-topic, other + optional notes
PostFlag model cp_post_flags table with status enum (pending, resolved, dismissed)
Hide content Per-champion hiding via cp_hidden_contents table
Block users cp_user_blocks table, hides all their content and messaging
Notification filter Blocked user messages excluded from notification count/dropdown

Key Files:

Tests: Model and controller tests for all safety features


Sub-Phase 3.5: CL/Staff Moderation

Status: ✅ Complete (January 2026)

Goal: Community Leaders can moderate their community’s board effectively.

What Was Implemented:

Component Details
CLC Moderation Actions Hide/unhide content, lock/unlock posts, pin/unpin posts
Escalation CLCs can escalate flagged content to Engagement Team
ModerationAction model Full audit trail with actor, action, target, notes
CLC Moderation Queue Shows only PENDING flags (resolved/dismissed excluded)
Staff Discussions Admin /champions/discussions with tabs for all/escalated/hidden/deleted
Action Items Integration Flagged + Escalated counts in staff navbar dropdown
Count Synchronization Leadership index, community dashboard, queue all consistent

Moderation Actions Enum: | Action | Code | Effect | |——–|——|——–| | action_hide | 0 | Hide from all non-moderators | | action_unhide | 1 | Make visible again | | action_lock | 2 | Prevent new comments | | action_unlock | 3 | Allow comments again | | action_pin | 4 | Pin to top of board | | action_unpin | 5 | Remove pin | | action_escalate | 6 | Flag for Engagement Team | | action_delete | 7 | Soft delete (staff only) | | action_resolve_escalation | 8 | Mark escalation resolved |

Key Files:

Tests: 2243 tests passing (0 failures, 0 errors)


Sub-Phase 3.6: National Alumni Champions Board

Status: ✅ Complete (January 2026)
Test Results: 2310 tests, 0 failures, 0 errors

What Was Implemented

Component Details
National Community “Alumni Champions” (ID: 47) with national: true flag
Auto-Join Membership All verified Champions auto-join on verification, cannot leave
Mute Notifications Per-community notification muting in Settings → Notifications
Community List Hidden from non-verified Champions, visible to verified
Board Navigation Main nav link “Alumni Champions”, communities nav integration
Dashboard Integration Popular national board posts surfaced on dashboard
Content Defaults News/events without community assignment default to National Board
Staff Pinning Community Leaders can pin posts to national board

Key Files:


Sub-Phase 3.7: Notifications

Goal: Champions stay informed about board activity.

Notification Triggers: | Trigger | Who Gets Notified | |———|——————-| | Reply to your post | Post author | | Reply to your comment | Comment author | | Reaction on your post/comment | Post/comment author | | Post in community you lead | Community Leaders | | Pinned announcement | All community members (optional email) |

Notification Channels:

Deliverables:

What Was Implemented

| Status:** ✅ Complete (January 2026)
Test Results: 2350 tests, 0 failures, 0 errors

What Was Implemented

Component Details
Admin Dashboard /insights/discussion_boards with metrics and analytics
Key Metrics Total posts, comments, active discussers, pending flags
Trends Posts/comments per week with sparkline charts
Community Breakdown Top 5 communities by activity (posts + comments)
Moderation Stats Flags by status (pending/resolved/dismissed), action counts
Period Selector This Week, This Month, This Quarter, All Time
Service Layer EngagementStats::DiscussionBoardsService for metrics calculation
Links to Action Pending flags count links to moderation queue

Key Files:

Metrics Included:

Tests: 45+ tests for service and controller

Note: Advanced analytics (content trends, user engagement patterns, exportable reports) deferred to backlog.


Sub-Phase 3.9: Public Landing Pages ✅ Complete

Goal: Create public preview pages for events, discussions, and communities to support rich link sharing and convert visitors to signups.

Spec Document: 3.9-public-landing-pages.md

Summary:

Deliverables:


Sub-Phase 3.10: Google News-Style Index Pages ✅ Complete

Goal: Create dedicated index pages for News, Events, and Discussions with Google News-inspired layouts.

Summary:

Deliverables:


Sub-Phase 3.11: Dashboard Redesign 🚧 In Progress

Goal: Restructure dashboard with Google News-style content sections and improved layout.

Spec Document: 3.11-dashboard-redesign.md

Summary:

Deliverables:


6. Data Model

New Tables

cp_board_posts

Column Type Notes
id bigint
community_id bigint FK Required
author_id bigint FK Cp::Champion
title string Required, max 255 chars
body text ActionText rich text, max 40K chars
status integer 0: active, 1: hidden, 2: deleted
pinned boolean Default false
locked boolean Default false
comments_count integer Counter cache
reactions_count integer Counter cache
last_activity_at datetime Updated on new comments (for sorting)
edited_at datetime Null if never edited
created_at datetime
updated_at datetime

Indexes:

cp_board_comments

Column Type Notes
id bigint
post_id bigint FK Required
author_id bigint FK Cp::Champion
parent_id bigint FK Self-reference for threading (nullable = top-level)
body text ActionText rich text, max 2K chars
status integer 0: active, 1: hidden, 2: deleted
reactions_count integer Counter cache
replies_count integer Counter cache for direct replies
last_reply_at datetime For thread sorting (nullable)
depth integer Nesting level (0 = top-level, computed on save)
edited_at datetime Null if never edited
created_at datetime
updated_at datetime

Indexes:

cp_board_reactions

Column Type Notes
id bigint
reactable_type string “Cp::BoardPost” or “Cp::BoardComment”
reactable_id bigint
champion_id bigint FK Who reacted
emoji string Emoji character (e.g., “👍”, “❤️”, “😄”)
created_at datetime

Indexes:

cp_post_flags

Column Type Notes
id bigint
flaggable_type string “Cp::BoardPost” or “Cp::BoardComment”
flaggable_id bigint
reporter_id bigint FK Cp::Champion who flagged
reason integer 0: spam, 1: inappropriate, 2: off_topic, 3: harassment, 4: other
notes text Optional explanation
status integer 0: pending, 1: resolved, 2: dismissed
resolved_by_id bigint FK CL/Staff who resolved (nullable)
resolved_at datetime
created_at datetime

Indexes:

cp_user_blocks

Column Type Notes
id bigint
blocker_id bigint FK Champion who blocked
blocked_id bigint FK Champion who is blocked
created_at datetime

Indexes:

cp_hidden_content

Column Type Notes
id bigint
champion_id bigint FK Who hid the content
hideable_type string “Cp::BoardPost” or “Cp::BoardComment”
hideable_id bigint
created_at datetime

Indexes:

cp_moderation_actions

Column Type Notes
id bigint
moderator_id bigint FK CL/Staff who acted
target_type string “Cp::BoardPost” or “Cp::BoardComment”
target_id bigint
action integer 0: hide, 1: unhide, 2: lock, 3: unlock, 4: pin, 5: unpin, 6: escalate
notes text Optional moderator notes
created_at datetime

Community Table Addition

# Add to cp_communities
add_column :cp_communities, :discussion_board_enabled, :boolean, default: true

Model Associations

# app/models/cp/community.rb (additions)
class Cp::Community < ApplicationRecord
  has_many :board_posts, class_name: "Cp::BoardPost", dependent: :destroy
  
  def discussion_board_enabled?
    discussion_board_enabled
  end
end

# app/models/cp/board_post.rb
class Cp::BoardPost < ApplicationRecord
  belongs_to :community, class_name: "Cp::Community"
  belongs_to :author, class_name: "Cp::Champion"
  has_many :comments, class_name: "Cp::BoardComment", dependent: :destroy
  has_many :reactions, as: :reactable, class_name: "Cp::BoardReaction", dependent: :destroy
  has_many :flags, as: :flaggable, class_name: "Cp::PostFlag", dependent: :destroy
  
  has_rich_text :body
  has_one_attached :image
  
  enum status: { active: 0, hidden: 1, deleted: 2 }
  
  validates :title, presence: true, length: { maximum: 255 }
  validates :body, length: { maximum: 40_000 }
  
  scope :visible, -> { where(status: :active) }
  scope :by_activity, -> { order(pinned: :desc, last_activity_at: :desc) }
  
  # 30-minute edit window
  def editable?
    created_at > 30.minutes.ago
  end
  
  def edited?
    edited_at.present?
  end
  
  # Popularity score for surfacing (14-day decay)
  TIME_DECAY_DAYS = 14
  
  def popularity_score
    age_in_days = (Time.current - created_at) / 1.day
    time_factor = [1.0 - (age_in_days / TIME_DECAY_DAYS), 0].max
    (reactions_count.to_i * 2) + (comments_count.to_i * 3) + (time_factor * 10)
  end
  
  # Touch last_activity_at when comments added
  def touch_activity!
    update_column(:last_activity_at, Time.current)
  end
end

# app/models/cp/board_comment.rb
class Cp::BoardComment < ApplicationRecord
  belongs_to :post, class_name: "Cp::BoardPost", counter_cache: :comments_count
  belongs_to :author, class_name: "Cp::Champion"
  belongs_to :parent, class_name: "Cp::BoardComment", optional: true, counter_cache: :replies_count
  has_many :replies, class_name: "Cp::BoardComment", foreign_key: :parent_id, dependent: :destroy
  has_many :reactions, as: :reactable, class_name: "Cp::BoardReaction", dependent: :destroy
  has_many :flags, as: :flaggable, class_name: "Cp::PostFlag", dependent: :destroy
  
  has_rich_text :body
  
  enum status: { active: 0, hidden: 1, deleted: 2 }
  
  validates :body, presence: true, length: { maximum: 2_000 }
  
  before_create :set_depth
  after_create :update_parent_activity, :update_post_activity
  
  scope :visible, -> { where(status: :active) }
  scope :top_level, -> { where(parent_id: nil) }
  scope :by_activity, -> { order(last_reply_at: :desc, created_at: :desc) }
  
  def editable?
    created_at > 30.minutes.ago
  end
  
  def edited?
    edited_at.present?
  end
  
  private
  
  def set_depth
    self.depth = parent ? parent.depth + 1 : 0
  end
  
  def update_parent_activity
    parent&.update_column(:last_reply_at, Time.current)
  end
  
  def update_post_activity
    post.touch_activity!
  end
end

# app/models/cp/board_reaction.rb
class Cp::BoardReaction < ApplicationRecord
  belongs_to :reactable, polymorphic: true, counter_cache: :reactions_count
  belongs_to :champion, class_name: "Cp::Champion"
  
  ALLOWED_EMOJIS = %w[👍 ❤️ 😄 🎉 🙌 💯].freeze
  
  validates :emoji, presence: true, inclusion: { in: ALLOWED_EMOJIS }
  validates :champion_id, uniqueness: { scope: [:reactable_type, :reactable_id, :emoji] }
end

# app/models/cp/post_flag.rb
class Cp::PostFlag < ApplicationRecord
  belongs_to :flaggable, polymorphic: true
  belongs_to :reporter, class_name: "Cp::Champion"
  belongs_to :resolved_by, class_name: "Cp::Champion", optional: true
  
  enum reason: { spam: 0, inappropriate: 1, off_topic: 2, harassment: 3, other: 4 }
  enum status: { pending: 0, resolved: 1, dismissed: 2 }
  
  scope :pending, -> { where(status: :pending) }
end

# app/models/cp/user_block.rb
class Cp::UserBlock < ApplicationRecord
  belongs_to :blocker, class_name: "Cp::Champion"
  belongs_to :blocked, class_name: "Cp::Champion"
  
  validates :blocked_id, uniqueness: { scope: :blocker_id }
  validate :cannot_block_self
  
  private
  
  def cannot_block_self
    errors.add(:blocked_id, "cannot block yourself") if blocker_id == blocked_id
  end
end

# app/models/cp/hidden_content.rb
class Cp::HiddenContent < ApplicationRecord
  belongs_to :champion, class_name: "Cp::Champion"
  belongs_to :hideable, polymorphic: true
  
  validates :hideable_id, uniqueness: { scope: [:champion_id, :hideable_type] }
end

# app/models/cp/moderation_action.rb
class Cp::ModerationAction < ApplicationRecord
  belongs_to :moderator, class_name: "Cp::Champion"
  belongs_to :target, polymorphic: true
  
  enum action: { hide: 0, unhide: 1, lock: 2, unlock: 3, pin: 4, unpin: 5, escalate: 6 }
end

# app/models/cp/champion.rb (additions)
class Cp::Champion < ApplicationRecord
  has_many :board_posts, class_name: "Cp::BoardPost", foreign_key: :author_id
  has_many :board_comments, class_name: "Cp::BoardComment", foreign_key: :author_id
  has_many :board_reactions, class_name: "Cp::BoardReaction"
  has_many :post_flags, class_name: "Cp::PostFlag", foreign_key: :reporter_id
  has_many :hidden_contents, class_name: "Cp::HiddenContent"
  has_many :blocks_given, class_name: "Cp::UserBlock", foreign_key: :blocker_id
  has_many :blocks_received, class_name: "Cp::UserBlock", foreign_key: :blocked_id
  has_many :blocked_champions, through: :blocks_given, source: :blocked
  has_many :blocked_by_champions, through: :blocks_received, source: :blocker
  
  def blocked?(champion)
    blocks_given.exists?(blocked_id: champion.id)
  end
  
  def hidden?(content)
    hidden_contents.exists?(hideable: content)
  end
end

7. Surfacing & Discovery

Post Visibility Strategy

Different locations use different logic to balance discovery with engagement:

Location Logic Posts Shown
Community Board page Latest activity (last_activity_at desc) All posts, paginated
Community Show page Top 3-5 by popularity score “Popular Discussions” section
Dashboard Top 3 by popularity from user’s communities Compact preview

Popularity Score Algorithm

# Constants (hardcoded, can be adjusted in future)
TIME_DECAY_DAYS = 14

def popularity_score
  age_in_days = (Time.current - created_at) / 1.day
  time_factor = [1.0 - (age_in_days / TIME_DECAY_DAYS), 0].max
  (reactions_count * 2) + (comments_count * 3) + (time_factor * 10)
end

Score Components:

Example Scores: | Post Age | Reactions | Comments | Score | |———-|———–|———-|——-| | 1 day | 5 | 10 | 10 + 30 + 9.3 = 49.3 | | 7 days | 20 | 50 | 40 + 150 + 5.0 = 195.0 | | 14+ days | 100 | 200 | 200 + 600 + 0 = 800.0 |

Board Listing UI

┌─────────────────────────────────────────────────────────────────────────┐
│ 📋 Nashville District Discussions                        [New Post +]  │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│ 📌 [PINNED] Welcome to the Nashville District Board!                    │
│    Posted by Sarah Chen • 2 weeks ago • 5 reactions • 12 comments       │
│                                                                         │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│                                                                         │
│ Anyone know a good venue for a 50-person meetup?                        │
│ Posted by Mike Johnson • 2 hours ago • 8 reactions • 23 comments        │
│ "Hey everyone! I'm trying to plan our Q2 event and looking for..."      │
│ [See more]                                                              │
│                                                                         │
│ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│                                                                         │
│ Congrats to Jane on her promotion! 🎉                                   │
│ Posted by Tom Wilson • 1 day ago • 15 reactions • 8 comments            │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Community Show Page Section

┌─────────────────────────────────────────────────────────────────────────┐
│ 💬 Popular Discussions                                   [View All →]   │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Anyone know a good venue for a 50-person meetup?                    │ │
│ │ Mike Johnson • 23 comments                                          │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│                                                                         │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Congrats to Jane on her promotion! 🎉                               │ │
│ │ Tom Wilson • 8 comments                                             │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│                                                                         │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Tips for hosting your first Champion event                          │ │
│ │ Sarah Chen • 15 comments                                            │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Dashboard Widget

┌─────────────────────────────────────────────────────────────────────────┐
│ 💬 Active Discussions                                                   │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│ 📍 Nashville: Anyone know a good venue for...    [23 💬]                │
│ 🎓 Music Business: Industry trends for 2026     [12 💬]                │
│ 🏛️ Alumni Champions: Welcome new Champions!     [45 💬]                │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

8. Definition of Success

Functional Acceptance Criteria

Quality Criteria


9. Tests to Create

Model Tests

Controller Tests

Integration Tests

Admin Analytics Tests


10. MVP vs Backlog

✅ MVP (This Phase)

Feature Sub-Phase
Per-community boards with admin toggle 3.1
Posts (40K chars, single image, rich text) 3.2
Comments (2K chars, rich text) 3.2
Collapsible threaded comments (show 2 levels) 3.2
30-minute edit window with “Edited” indicator 3.2
Post truncation with “See more” 3.2
Community Guidelines reminder in composer 3.2
Emoji reactions (posts + comments) 3.3
Sort by latest activity 3.3
Popularity score for surfacing 3.3
Report/Flag content 3.4
Hide content (for self) 3.4
Block user 3.4
CL moderation (hide, lock, pin, escalate) 3.5
Moderation action log 3.5
National Alumni Champions board 3.6
Reply/reaction notifications 3.7
Admin discussion analytics dashboard 3.8

📋 Backlog (Future)

Feature Notes
@mentions Requires name resolution UI, notification integration
Search within boards Full-text search across posts/comments
Bookmarks/Save posts Save for later reading
Mute specific threads Stop notifications for a thread
Additional sort options Top, Controversial, etc.
Multiple images per post Currently MVP is single image
User temp bans 24hr, 7 day, permanent bans by CL
Advanced reporting analytics Content trends, user patterns, exportable reports (basic metrics in 3.8)

❌ Explicitly Not Planned

Feature Reason
Anonymous posting Against community trust principles
Upvote/downvote Feels like popularity contest
Algorithmic feed Prioritize chronological + activity over “engagement”
Jobs/Career board Separate Job Board feature
Mentorship board Separate Mentorship Center feature

11. Documentation Updates

After completing Phase 3:


Questions to Resolve

Question Status Decision
Board per community or separate model? ✅ Resolved Per community (no separate Board model)
National board implementation? ✅ Resolved Special community with national: true flag
Comment nesting depth? ✅ Resolved Unlimited, collapsible at depth 3+
Rich text editor? ✅ Resolved ActionText (bold, italic, bullets, numbers, links)
Edit time window? ✅ Resolved 30 minutes with “Edited” indicator
Reactions? ✅ Resolved Emoji reactions (mirror MessageReaction)
Sorting? ✅ Resolved By last_activity_at (fresh threads rise)
Content limits? ✅ Resolved Posts 40K, Comments 2K
Images? ✅ Resolved Single image per post (MVP)
User controls? ✅ Resolved Report, Hide content, Block user
CL controls? ✅ Resolved Hide, Lock, Pin, Escalate
Surfacing algorithm? ✅ Resolved Popularity = (reactions×2) + (comments×3) + time_decay
Time decay period? ✅ Resolved 14 days (hardcoded constant)
Dashboard posts? ✅ Resolved 3 posts (compact)
Community show posts? ✅ Resolved 3-5 popular posts section
@mention implementation? ⏸️ Deferred Backlog item

Document Purpose
../../JOBS-TO-BE-DONE.md Jobs C5, L3, L4
../phase-2/README.md Community Leadership (moderation queue)
../../development/DESIGN-GUIDELINES.md UI patterns
../../features/05-DISCUSSION-BOARDS.md Feature details
config/faq.yml Community Guidelines content

Appendix: Community Guidelines

A short reminder should appear in the post composer:

📋 Community Guidelines Reminder

• Be respectful and constructive
• Keep discussions relevant to the community
• No political or controversial content
• Celebrate wins, support struggles
• Report content that makes you uncomfortable

[Read full Community Guidelines →]

The full guidelines should be in the FAQ (Help page), covering:


This phase enables community-wide communication and marks a significant step toward building a thriving, safe Champion community.