Repository Overview
Last Updated: February 2026
Purpose: Comprehensive codebase documentation for developers and AI systems.
Table of Contents
- High-Level Architecture
- Code Organization
- Main Components & Workflows
- Data Models & Relationships
- Frameworks & Dependencies
- Test Status
- Conventions & Patterns
- Architectural Notes
High-Level Architecture
Stack Overview
| Layer |
Technology |
| Framework |
Ruby on Rails 7.1.5.1 |
| Language |
Ruby 3.2.3+ |
| Database |
PostgreSQL |
| Frontend |
Tailwind CSS + TailwindUI, Turbo/Hotwire |
| JavaScript |
Import Maps (no bundler), 87 Stimulus controllers |
| Authentication |
Devise + OmniAuth (Google SSO) |
| Search |
PgSearch (PostgreSQL full-text with unaccent) |
| Rich Text |
ActionText (Trix editor) |
| File Storage |
ActiveStorage + Cloudinary |
| Background Jobs |
Solid Queue |
| Pagination |
Kaminari |
| Email |
Mailgun (transactional + digests) |
| Hosting |
Heroku (1 worker, 3 threads) |
Application Purpose
A two-portal platform for Belmont University alumni engagement:
| Portal |
Domain |
Namespace |
Users |
| Alumni Lookup |
alumnilookup.com |
Root, settings/, champions/, api/, tools/ |
Staff (Admin, Portal Admin, Staff) |
| Alumni Network |
belmontalum.com |
cp/ |
Alumni (Member, Champion, Community Leader) |
Both portals share a single Rails app and PostgreSQL database. Domain-based routing directs requests to the appropriate controllers.
Code Organization
Directory Structure
alumni_lookup/
├── app/
│ ├── controllers/ # 99 controllers across 6 namespaces
│ │ ├── *.rb # ~15 root controllers (Lookup core)
│ │ ├── api/ # ~8 internal API controllers
│ │ ├── champions/ # ~20 champion admin controllers (staff)
│ │ ├── cp/ # ~35 Alumni Network controllers (external)
│ │ ├── settings/ # ~10 reference data management
│ │ └── tools/ # ~4 utility tools
│ ├── models/ # 76 models
│ │ ├── *.rb # ~20 Lookup Portal models
│ │ └── cp/ # ~55 Alumni Network models (Cp:: namespace)
│ ├── views/ # ERB templates with Turbo support
│ │ ├── shared/ # Shared partials
│ │ ├── components/ # Reusable UI components
│ │ ├── champions/ # Champion admin views
│ │ └── cp/ # Alumni Network views
│ ├── services/ # 49 service objects
│ │ ├── *.rb # Lookup Portal services
│ │ ├── cp/ # Alumni Network services
│ │ ├── csv/ # Import/export services
│ │ ├── engagement_stats/ # Analytics services
│ │ └── onboarding_insights/ # Onboarding metrics
│ ├── helpers/ # 25 view helpers
│ ├── javascript/ # 87 Stimulus controllers
│ ├── mailers/ # 12 mailer classes
│ │ └── cp/ # Alumni Network mailers
│ ├── jobs/ # 17 background jobs
│ │ └── cp/ # Alumni Network jobs
│ ├── decorators/ # Decorator objects
│ └── assets/ # CSS (Tailwind)
├── config/
│ ├── routes.rb # Domain-based routing
│ ├── database.yml # PostgreSQL config
│ ├── importmap.rb # JavaScript import maps
│ └── initializers/ # App initialization
├── db/
│ ├── migrate/ # 169 migrations
│ ├── schema.rb # Current schema
│ └── seeds/ # Seed data
├── docs/ # Documentation
│ ├── development/ # Developer guides
│ ├── features/ # Feature documentation
│ ├── planning/ # Planning documents
│ │ └── champion-portal/ # Alumni Network planning
│ ├── PRODUCT_OVERVIEW.md # Product-level reference
│ └── REPO_OVERVIEW.md # This file
├── lib/
│ ├── tasks/ # Custom Rake tasks
│ └── middleware/ # Custom middleware
├── test/ # Minitest test suite (210 tests)
│ ├── controllers/ # 85 controller tests
│ ├── models/ # 60 model tests
│ ├── services/ # 38 service tests
│ ├── integration/ # 3 integration tests
│ ├── helpers/ # 4 helper tests
│ ├── fixtures/ # Test fixtures (including cp/ namespace)
│ ├── jobs/ # Job tests
│ └── mailers/ # Mailer tests
├── CLAUDE.md # Core AI development patterns
└── AGENTS.md # Detailed AI guidance
Controllers by Namespace (99 total)
Root Controllers (~15) — Lookup Portal Core
| Controller |
Purpose |
AlumniController |
Alumni CRUD & search |
EngagementStatsController |
Analytics dashboard (6 tabs) |
PeopleController |
People search interface |
ChampionSignupsController |
Champion signup management |
AlumniAffinitiesController |
Alumni affinity management |
StatisticsController |
Statistics views |
PublicController |
Public-facing pages |
ApplicationController |
Base controller |
settings/ Namespace (~10) — Reference Data
| Controller |
Purpose |
Settings::AlumniController |
Alumni record management |
Settings::CollegesController |
College reference data |
Settings::MajorsController |
Major reference data |
Settings::DistrictsController |
District management |
Settings::AffinitiesController |
Affinity management |
Settings::EngagementActivitiesController |
Activity imports/management |
Settings::UsersController |
User CRUD |
Settings::CurrentStudentsController |
Current student data |
Settings::AffinaquestController |
CRM integration |
Settings::SettingsController |
Settings dashboard |
champions/ Namespace (~20) — Champion Admin (Staff)
| Controller |
Purpose |
Champions::ChampionsController |
Champion account management |
Champions::VerificationsController |
Verification queue |
Champions::CommunityLeadersController |
CL assignment |
Champions::CommunitiesController |
Community management |
Champions::DiscussionsController |
Discussion admin |
Champions::EventsController |
Event management |
Champions::NewsPostsController |
News management |
Champions::ContentSubmissionsController |
Submission review queue |
Champions::CareerResourcesController |
Career resource admin |
Champions::RoleIdeasController |
Daily idea management |
Champions::SeededQuestionsController |
Seeded question admin |
Champions::PhotoAlbumsController |
Photo album management |
Champions::StatsController |
Champion analytics |
Champions::InsightsController |
Onboarding insights |
Champions::RoadmapController |
Phase status source of truth |
Champions::EmailLogsController |
Email log viewer |
Champions::FeedbacksController |
Feedback management |
Champions::SupportThreadsController |
Support thread admin |
cp/ Namespace (~35) — Alumni Network (External)
| Controller |
Purpose |
Cp::DashboardController |
Alumni dashboard |
Cp::DirectoryController |
Alumni directory search |
Cp::ProfileController |
Profile viewing |
Cp::ProfileWizardController |
Multi-step profile setup |
Cp::CommunitiesController |
Community pages |
Cp::ConnectionsController |
Connection management |
Cp::ConnectionRequestsController |
Connection requests |
Cp::MessagesController |
Direct messaging |
Cp::BoardsController |
Discussion boards |
Cp::BoardCommentsController |
Discussion comments |
Cp::DiscussionsController |
Discussion views |
Cp::EventsController |
Event browsing |
Cp::EventSubmissionsController |
Alumni event submissions |
Cp::NewsController |
News feed |
Cp::NewsSubmissionsController |
Alumni news submissions |
Cp::SubmissionsController |
Content submissions |
Cp::CareersController |
Career center |
Cp::RolesController |
Champion role pages |
Cp::NotificationsController |
Notification bell/center |
Cp::CommunityNotificationsController |
Community notification settings |
Cp::PhotoAlbumsController |
Photo gallery |
Cp::SettingsController |
Account settings |
Cp::HelpController |
FAQ and help |
Cp::FlagsController |
Content flagging |
Cp::FeedbackController |
User feedback |
Cp::LeadershipController |
CL tools |
Cp::ModerationController |
Moderation interface |
Cp::LandingController |
Landing/marketing pages |
Cp::ImpersonationController |
Admin impersonation |
Cp::InvitesController |
Invite system |
Cp::RegistrationsController |
Account registration |
Cp::SessionsController |
Login/logout |
Cp::PasswordsController |
Password management |
Cp::ConfirmationsController |
Email confirmation |
Cp::OmniauthCallbacksController |
Google OAuth |
api/ Namespace (~8) — Internal APIs
| Controller |
Purpose |
Api::AlumniController |
Alumni data API |
Api::CommunitiesController |
Community data API |
Api::DistrictsController |
District lookup API |
Api::MajorsController |
Major lookup API |
Api::AffinitiesController |
Affinity lookup API |
Api::ActivityDescriptionsController |
Activity description API |
Api::AiController |
AI integration endpoints |
Api::V1::AlumniSearchController |
Versioned search API |
| Controller |
Purpose |
Tools::BatchSearchController |
Bulk alumni matching |
Tools::EventConverterController |
Event RSVP converter |
Tools::ToolsController |
Tools dashboard |
Models by Namespace (76 total)
Lookup Portal Models (~20)
| Model |
Table |
Purpose |
Alumni |
alumnis |
Core alumni records |
Degree |
degrees |
Academic degrees |
Major |
majors |
Academic majors |
College |
colleges |
Academic colleges |
EngagementActivity |
engagement_activities |
Individual activities |
EngagementType |
engagement_types |
Activity type definitions |
ChampionSignup |
champion_signups |
Champion pipeline |
User |
users |
System users (Devise) |
Affinity |
affinities |
Interest/club categories |
AlumniAffinity |
alumni_affinities |
Alumni-affinity join |
District |
districts |
Geographic districts |
Region |
regions |
Internal geographic regions |
ZipCode |
zip_codes |
ZIP → city/district mapping |
ApiKey |
api_keys |
API authentication |
AffinaquestImportBatch |
affinaquest_import_batches |
CRM import tracking |
AffinaquestImportConflict |
affinaquest_import_conflicts |
CRM import conflicts |
CrmDataChange |
crm_data_changes |
CRM data audit |
CrmDataExportBatch |
crm_data_export_batches |
CRM export tracking |
CurrentStudentImportBatch |
current_student_import_batches |
Student import tracking |
StaffNotification |
staff_notifications |
Staff notification system |
PushSubscription |
push_subscriptions |
Web push subscriptions |
Alumni Network Models (Cp::, ~55)
| Model |
Table |
Purpose |
Cp::Champion |
cp_champions |
Alumni accounts |
Cp::Community |
cp_communities |
Community groups (7 types) |
Cp::ChampionCommunity |
cp_champion_communities |
Membership join |
Cp::Connection |
cp_connections |
Established connections |
Cp::ConnectionRequest |
cp_connection_requests |
Pending connection requests |
Cp::BoardPost |
cp_board_posts |
Discussion posts |
Cp::BoardComment |
cp_board_comments |
Discussion replies |
Cp::BoardReaction |
cp_board_reactions |
Post/comment reactions |
Cp::Event |
cp_events |
Events |
Cp::EventCommunity |
cp_event_communities |
Event-community targeting |
Cp::NewsPost |
cp_news_posts |
News announcements |
Cp::NewsPostCommunity |
cp_news_post_communities |
News targeting |
Cp::NewsPostCollege |
cp_news_post_colleges |
News college targeting |
Cp::NewsPostChampion |
cp_news_post_champions |
News author attribution |
Cp::NewsPostImage |
cp_news_post_images |
News images |
Cp::NewsPostLike |
cp_news_post_likes |
News likes |
Cp::NewsPostView |
cp_news_post_views |
News view tracking |
Cp::Message |
cp_messages |
Direct messages |
Cp::MessageThread |
cp_message_threads |
Conversation threads |
Cp::MessageThreadParticipant |
cp_message_thread_participants |
Thread membership |
Cp::MessageReaction |
cp_message_reactions |
Message reactions |
Cp::Notification |
cp_notifications |
In-app notifications |
Cp::NotificationPreference |
cp_notification_preferences |
Per-type email prefs |
Cp::CommunityNotification |
cp_community_notifications |
Community email prefs |
Cp::CareerResource |
cp_career_resources |
Career center resources |
Cp::ContentSubmissionThread |
cp_content_submission_threads |
News/event submissions |
Cp::ContentSubmissionMessage |
cp_content_submission_messages |
Submission dialogue |
Cp::RoleIdea |
cp_role_ideas |
Daily engagement ideas |
Cp::RoleIdeaPack |
cp_role_idea_packs |
Daily idea packs |
Cp::RoleIdeaPackItem |
cp_role_idea_pack_items |
Pack-idea join |
Cp::SeededQuestion |
cp_seeded_questions |
Discussion starters |
Cp::SeededQuestionExposure |
cp_seeded_question_exposures |
Question exposure tracking |
Cp::ClcAssignment |
cp_clc_assignments |
CL-community assignment |
Cp::Photo |
cp_photos |
Photo records |
Cp::PhotoAlbum |
cp_photo_albums |
Photo albums |
Cp::PhotoAlbumCommunity |
cp_photo_album_communities |
Album-community targeting |
Cp::ActivityEvent |
cp_activity_events |
Activity audit log |
Cp::OnboardingEvent |
cp_onboarding_events |
Onboarding tracking |
Cp::ChampionContact |
cp_champion_contacts |
Migrated contact records |
Cp::ChampionRecommendation |
cp_champion_recommendations |
“Like me” recommendations |
Cp::Feedback |
cp_feedbacks |
User feedback |
Cp::SupportThread |
cp_support_threads |
Support conversations |
Cp::SupportMessage |
cp_support_messages |
Support messages |
Cp::EmailLog |
cp_email_logs |
Email delivery tracking |
Cp::Affinity |
cp_affinities |
Network affinities |
Cp::AffinitySuggestion |
cp_affinity_suggestions |
Affinity suggestions |
Cp::CommunitySuggestion |
cp_community_suggestions |
Community suggestions |
Cp::JoinRequest |
cp_join_requests |
Community join requests |
Cp::PostFlag |
cp_post_flags |
Content flagging |
Cp::HiddenContent |
cp_hidden_contents |
User-hidden content |
Cp::ModerationAction |
cp_moderation_actions |
Moderation audit log |
Cp::UserBlock |
cp_user_blocks |
User blocking |
Cp::ProfileChange |
cp_profile_changes |
Profile change audit |
Services (49 total)
Lookup Portal Services
| Service |
Purpose |
EngagementScoreCalculator |
Core scoring algorithm with activity caps |
TopEngagedAlumniService |
Ranking with time period filtering |
AlumniFilterService |
Complex filtering for stats/exports |
AlumniLookupService |
Bulk matching, nickname-aware lookup |
AlumniMatcher |
Alumni record matching |
ChampionQuizService |
Champion quiz logic |
ChampionRoleService |
Champion role management |
ChampionSignupMerger |
Signup merge/dedup |
ActionItemsService |
Action item generation |
AiContentService |
AI content generation |
ManifestStore |
Data manifest caching |
CurrentStudentManifestStore |
Student manifest caching |
PhotoFromUrlService |
Photo import from URL |
WebPushService |
Web push notifications |
CSV Services
| Service |
Purpose |
Csv::AlumniImporter |
Bulk alumni CSV import |
Csv::AlumniExporter |
Alumni CSV export |
Csv::BannerImporter |
Banner system import |
Csv::AffinaquestContactImporter |
CRM contact import |
Csv::ChampionSignupExporter |
Champion signup export |
Csv::CurrentStudentImporter |
Student import |
Csv::EventRsvpConverter |
Event RSVP conversion |
Engagement Stats Services
| Service |
Purpose |
EngagementStats::OverviewService |
Summary statistics |
EngagementStats::AnalyticsService |
Trend analysis |
EngagementStats::BreakdownService |
Activity breakdown |
EngagementStats::DemographicsService |
Demographic analysis |
EngagementStats::MatrixService |
Quadrant analysis |
EngagementStats::ActivityPairsService |
Activity correlation |
EngagementStats::DiscussionBoardsService |
Discussion analytics |
EngagementStats::BaseService |
Base service class |
Alumni Network Services (Cp::)
| Service |
Purpose |
Cp::ActivityRecorder |
Activity event tracking |
Cp::AlumniLikeMeService |
“Champions Like You” recommendations |
Cp::CareerConnectService |
Career connection logic |
Cp::CommunityDetectionService |
Dynamic community creation |
Cp::CommunityMatchingService |
Community auto-assignment |
Cp::ConnectionRequestService |
Connection request workflow |
Cp::EngagementScoreService |
Network-side engagement scoring |
Cp::MessagingService |
Message delivery |
Cp::MetricsService |
Champion program metrics |
Cp::MetricsCsvExporter |
Metrics CSV export |
Cp::NotificationService |
Notification dispatch + digest scheduling |
Cp::QuestionInterpolator |
Dynamic question text |
Cp::RoleIdeaPackService |
Daily idea pack generation |
Cp::SeededQuestionPublisher |
Question publishing workflow |
Cp::SeededQuestionSelector |
Question selection algorithm |
Cp::SyncChampionToAlumni |
Champion ↔ Alumni sync |
Cp::WelcomeContentGenerator |
Onboarding content |
Onboarding Insights Services
| Service |
Purpose |
OnboardingInsights::OnboardingMetricsService |
Onboarding funnel metrics |
OnboardingInsights::SeededQuestionMetricsService |
Seeded question metrics |
OnboardingInsights::BaseService |
Base service class |
Main Components & Workflows
1. Engagement Tracking System (Lookup)
Activities are scored at levels 0–4 with per-type caps:
Level 0 → 0 pts | Level 1 → 1 pt | Level 2 → 3 pts | Level 3 → 7 pts | Level 4 → 10 pts
Distance formula: √((score × 1.5)² + (capped_activity_count × 1.0)²)
2. Import/Export Pipeline (Lookup)
CSV → Header Mapping → Preview → Validation → Commit. Supports alumni, degrees, engagement activities, Affinaquest contacts, current students.
3. Alumni Network User Flow
Registration → Email Verification → Profile Wizard → Community Auto-Assignment → Dashboard. Trust-first access: community browsing before verification.
4. Connection System (Network)
Request (3 intent types) → Recipient Accepts/Declines → Connection → Connection-gated Messaging.
5. Content Submission Flow (Network)
Alumni submits news/event → Staff review queue → Approve/Decline → Published with attribution (or revision conversation).
6. Notification Pipeline (Network)
Trigger event → Cp::NotificationService.record() → In-app notification → Optional email digest (daily/weekly per preference).
Frameworks & Dependencies
Core Dependencies
| Gem |
Purpose |
rails 7.1.5.1 |
Web framework |
pg |
PostgreSQL adapter |
puma |
Web server |
devise |
Authentication |
omniauth-google-oauth2 |
Google SSO |
pundit |
Authorization policies |
kaminari |
Pagination |
pg_search |
Full-text search |
tailwindcss-rails |
CSS framework |
turbo-rails |
Hotwire Turbo |
stimulus-rails |
Hotwire Stimulus |
importmap-rails |
JavaScript imports |
solid_queue |
Background jobs |
propshaft |
Asset pipeline |
action_text |
Rich text (Trix) |
active_storage |
File uploads |
image_processing |
Image variants |
Development / Testing
| Gem |
Purpose |
minitest |
Test framework (Rails default) |
byebug / pry |
Debugging |
web-console |
Browser debugging |
Test Status
Framework: Minitest (210 tests)
test/
├── controllers/ 85 tests (champions/, cp/, settings/, tools/, api/)
├── models/ 60 tests (including cp/ namespace)
├── services/ 38 tests (cp/, csv/, engagement_stats/, onboarding_insights/)
├── helpers/ 4 tests
├── integration/ 3 tests
├── jobs/ Job tests (cp/)
├── mailers/ Mailer tests (cp/)
└── fixtures/ Test fixtures (including cp/)
Test Run Command
bin/test # Run all tests — 0 failures, 0 errors required before commits
Conventions & Patterns
Naming Conventions
| Pattern |
Example |
Usage |
buid |
B12345678 |
Alumni unique identifier (Belmont University ID) |
contact_id |
C-000000000 |
CRM-compatible identifier (BQID) |
*_id |
list_id, user_id |
Foreign keys (standard) |
*_code |
major_code, activity_code |
Lookup/classification keys |
pref_* |
pref_email, pref_phone |
Preferred contact fields |
*_date |
degree_date, engagement_date |
Date columns |
starts_at |
Event datetime |
NOT starts_on |
cp_* |
cp_champions, cp_communities |
Alumni Network tables |
Critical Join Pattern
# ✅ CORRECT - College filtering requires nested joins through major
EngagementActivity.joins(alumni: { degrees: { major: :college } })
# ❌ WRONG - Degrees don't directly associate with colleges
EngagementActivity.joins(alumni: { degrees: :college })
# ✅ CORRECT - Association name is :alumni (NOT :alumnus)
EngagementActivity.joins(:alumni)
Service Object Pattern
class SomeService
def initialize(params)
@params = params
end
def call
# Business logic
end
end
Controller Patterns
- RESTful actions with Turbo responses
before_action for authentication (ensure_staff!, ensure_portal_admin!, ensure_admin!)
- Alumni Network uses
Cp::BaseController with authenticate_cp_champion!
- Admin tools use
Champions::BaseController with ensure_portal_admin!
View Patterns
- Partials prefixed with
_
- Shared partials in
app/views/shared/
- Component partials in
app/views/components/
- Turbo frames and streams for partial updates
- TailwindUI component patterns
Architectural Notes
Strengths
- Clean namespace separation — Lookup (
root), Admin (champions/), Network (cp/), Settings (settings/), API (api/)
- Rich service layer — 49 services isolating business logic from controllers
- Modern stack — Rails 7.1, Hotwire, Tailwind, Solid Queue
- Comprehensive testing — 210 Minitest tests covering controllers, models, services
- Domain-based routing — Clean separation between internal and external portals
- Activity event tracking —
Cp::ActivityRecorder provides audit trail
- Well-documented — CLAUDE.md, AGENTS.md, and extensive docs/ directory
Known Patterns to Follow
- Alumni is singular AND plural (model:
Alumni, association: :alumni)
@alum = single record, @alumni = collection
major.major_desc (NOT major.description)
- Degrees have NO description field — only
degree.degree_code
- Display format:
"#{degree.degree_code} in #{degree.major.major_desc}"
- District (user-facing) vs Region (internal only)
- Events use
starts_at (datetime) NOT starts_on
- Route helpers:
cp_directory_path(champion) NOT cp_champion_path
- JSONB: Normalize keys with
deep_stringify_keys
- CSS truncation in flex:
min-w-0 on every flex parent
Heroku Constraints
- 1 worker, 3 threads — memory-optimized for Heroku
- 15-second timeout — all requests must complete quickly
- Avoid
.to_a on large queries — stream instead
- Batch processing — 50 records per batch
- Release service objects — call
service.clear! after use
Quick Reference
Common Commands
bin/dev # Start development server
bin/test # Run all tests
echo "Alumni.count" | bin/rails console # Quick console query
bin/rails routes | rg route_name # Find routes
tail -n 50 log/development.log # Recent logs
Key Files for New Developers
CLAUDE.md — Core AI development patterns
AGENTS.md — Detailed guidance, debugging, phase processes
config/routes.rb — All application routes (domain-based)
app/models/alumni.rb — Core alumni model
app/models/cp/champion.rb — Core Alumni Network model
app/services/engagement_score_calculator.rb — Scoring logic
docs/development/MODEL_RELATIONSHIPS.md — Association reference
docs/planning/champion-portal/README.md — Alumni Network overview
This document reflects the codebase as of February 2026. Update when significant features are added.