Champion Portal Development Phase 1A
Estimated Effort: 1–2 weeks
Focus: Contact Button, Email Relay (Early Messaging)Prerequisites: Phase 1 complete (Profiles + Directory)
Related Documents:
- ../JOBS-TO-BE-DONE.md — Job C6: Connect Directly
- ../features/06-MESSAGING.md — Full messaging spec
- PHASE-4.md — Full messaging phase (builds on this)
Phase 1A adds a simple “Contact” button to Champion profiles that enables email relay messaging. This delivers immediate value on the directory feature by letting Champions actually connect with each other.
After Phase 1A, Champions can:
This is intentionally minimal. Full in-app messaging, notifications, and message history come in Phase 4. This phase validates the demand for direct messaging before building the full system.
From JOBS-TO-BE-DONE.md:
Job C6: Connect Directly
“When I find a Champion with shared interests or expertise, I want to reach out to them directly, so I can start a conversation without sharing my personal contact info publicly.”
Importance: 🔶 High
Current Satisfaction: ❌ Very Low
Opportunity Score: 🎯 High
The directory (Phase 1) is only valuable if Champions can act on what they find. Without a contact mechanism, finding someone creates frustration, not connection.
Why not wait for Phase 4?
Phase 1A has 2 sub-phases:
| Sub-Phase | Name | Est. Time |
|---|---|---|
| 1A.1 | Contact Button & Form | 1 day |
| 1A.2 | Email Relay System | 1–2 days |
Goal: Add “Contact” button to Champion profiles that opens a message form.
Deliverables:
UI Design Notes:
Form Fields: | Field | Type | Required | Validation | |——-|——|———-|————| | Subject | text | Yes | 5–100 characters | | Message | textarea | Yes | 10–2000 characters |
Goal: Messages are delivered via email, with reply-to set to sender’s email.
Deliverables:
Cp::ContactMessage model to log messagesContactMailer to send messagesEmail Template Structure:
Subject: [Champion Portal] {Subject from form}
Hi {Recipient First Name},
{Sender Full Name} ({City, Grad Year}) would like to connect with you:
---
{Message Body}
---
To reply, simply respond to this email—it will go directly to {Sender First Name}.
---
This message was sent through the Belmont Alumni Champion Portal.
{Sender's profile}: {Profile URL}
Not interested in receiving messages? Update your preferences: {Preferences URL}
Database Schema:
create_table :cp_contact_messages do |t|
t.references :sender, null: false, foreign_key: { to_table: :cp_champions }
t.references :recipient, null: false, foreign_key: { to_table: :cp_champions }
t.string :subject, null: false
t.text :body, null: false
t.datetime :sent_at
t.timestamps
end
| Metric | Measurement |
|——–|————-|
| Messages sent per week | Count of cp_contact_messages |
| Unique senders per week | Distinct sender_ids |
| Unique recipients per week | Distinct recipient_ids |
| Top senders | Most active connectors |
| City pairs | Which cities are connecting? |
These metrics inform Phase 4 decisions:
test/models/cp/contact_message_test.rb)test/mailers/contact_mailer_test.rb)After completing Phase 1A:
Cp::ContactMessage to ../../development/MODEL_RELATIONSHIPS.md| Question | Decision |
|---|---|
| Show sender email in form? | No—privacy first. Set via reply-to header. |
| Message length limit? | 2000 characters (enough for intro, not essays) |
| Rate limit? | 10/day to prevent spam |
| Store messages? | Yes, for analytics and future in-app history |