Skip to content

Testing Dashboard Redesign & Edge Endpoint Migration

Date: November 18, 2025 Status: ✅ Complete Impact: Production-quality testing interface + correct backend integration


Summary

Completely redesigned the iMessage test app with a professional SaaS-quality dashboard (Stripe/Ramp/Brex inspired) and migrated from /orchestrator/message to /edge/message endpoint. This provides a production-grade testing interface for backend development and clarifies that all messages are conversations WITH Sage (not user-to-user).

What Was Built

1. Professional Dashboard UI (Streamlit)

Design System: - Color Palette: #0066FF primary, #fafafa backgrounds, #e6e6e6 borders - Typography: System fonts, 600 weight headers, clean hierarchy - Components: Cards, message bubbles, metrics, status badges - Inspiration: Stripe dashboard, Ramp interface, Brex design language

Key Features: - ✅ Real-time chat interface with Sage - ✅ Message bubbles (You → Sage conversation) - ✅ Session metrics (message count, avg response time) - ✅ Backend status monitoring - ✅ Quick test scenarios (greetings, calendar, email, emotional support) - ✅ API request/response inspector - ✅ Environment selector (Dev/Staging/Production) - ✅ Conversation history management

Files Modified: - test_app/web/app.py - Complete rewrite (600+ lines)

2. Backend Integration Update

Migration: /orchestrator/message/edge/message

Changes: - Schema: OrchestratorRequestFilteredMessage - Authentication: RELAY_WEBHOOK_SECRETEDGE_SECRET - Timestamp format: Unix int → ISO 8601 string - Payload structure updated to match edge client spec

Files Modified: - test_app/core/api_client.py - Updated send_message() method - test_app/config.py - Added EDGE_SECRET configuration - test.sh - Export EDGE_SECRET instead of RELAY_WEBHOOK_SECRET

3. UX Improvements

Clarified Messaging Flow: - CLI help text: "Send a message to Sage" (not user-to-user) - Web UI: "Chat with Sage" interface - Quick tests explicitly show conversation with AI - Documentation updated throughout

Files Modified: - test.sh - Updated help text and send command description - docs/testing/IMESSAGE_TEST_APP.md - Major documentation update - docs/apis/MESSAGE_ENDPOINTS.md - Updated to show /edge/message as primary

Technical Details

Schema Migration

Before (OrchestratorRequest):

{
  "chat_guid": "iMessage;-;+15559876543",
  "mode": "direct",
  "sender": "+15551234567",
  "text": "Hello Sage!",
  "timestamp": 1700000000,
  "participants": ["+15551234567", "+15559876543"],
  "metadata": {"message_type": "text"}
}

After (FilteredMessage):

{
  "thread_id": "iMessage;-;+15551234567",
  "sender": "+15551234567",
  "filtered_text": "Hey Sage, how are you?",
  "original_timestamp": "2025-11-18T12:00:00Z",
  "is_group": false,
  "participants": ["+15551234567"],
  "was_redacted": false,
  "redacted_fields": [],
  "filter_reason": "test_app_message"
}

Authentication Update

Before:

# Config
RELAY_WEBHOOK_SECRET = "<REDACTED_HEX_SECRET>"

# Header
Authorization: Bearer {RELAY_WEBHOOK_SECRET}

# Endpoint
POST /orchestrator/message

After:

# Config
EDGE_SECRET = "<REDACTED_HEX_SECRET>"

# Header
Authorization: Bearer {EDGE_SECRET}

# Endpoint
POST /edge/message

Testing

Manual Testing Performed

Web UI Launch:

./test.sh web
# → Opens http://localhost:8501
# → Dashboard loads with professional design
# → Chat interface ready

Message Sending (CLI):

./test.sh send "Testing the redesigned interface!"
# → 📤 Sending message to Sage...
# → ✅ Message sent successfully!
# → Bubble 1: oo nifty!!
# → Bubble 2: how's it feeling rn?

Backend Connection:

./test.sh heartbeat
# → 💓 Testing heartbeat...
# → ✅ Backend Connected

Features Verified

  • Web UI renders with production styling
  • Chat messages display as "You" → "Sage" conversation
  • Multi-bubble responses render correctly
  • Session metrics track message count and response time
  • Backend status monitoring works
  • Quick test buttons trigger conversations
  • API inspector shows correct FilteredMessage payload
  • Environment selector changes API base URL
  • Clear conversation resets state
  • CLI sends messages successfully
  • Help text clarifies "message to Sage"

Impact

User Experience

  • Clarity: No more confusion about user-to-user vs user-to-AI messaging
  • Professionalism: Dashboard matches production SaaS quality
  • Usability: Quick tests, metrics, status monitoring all in one interface
  • Debugging: API inspector shows exact payloads sent/received

Engineering

  • Correct Endpoint: Now using /edge/message (matches Mac mini edge client)
  • Correct Schema: FilteredMessage schema properly implemented
  • Correct Auth: EDGE_SECRET instead of relay webhook secret
  • Better Testing: Real-time chat interface for faster iteration

Documentation

  • docs/testing/IMESSAGE_TEST_APP.md - Complete redesign documentation
  • docs/apis/MESSAGE_ENDPOINTS.md - Updated to show /edge/message as primary
  • test.sh - Help text clarified
  • ✅ Implementation notes (this document)

Configuration Changes

Environment Variables

New:

EDGE_SECRET=<generated_hex>

Deprecated:

RELAY_WEBHOOK_SECRET=<generated_secret>
# Still exported in test.sh for backwards compatibility, but not used

Files Updated

Core: 1. test_app/web/app.py - 600+ line complete rewrite 2. test_app/core/api_client.py - Updated send_message(), __init__() 3. test_app/config.py - Added EDGE_SECRET

Scripts: 4. test.sh - Updated help text, added EDGE_SECRET export

Documentation: 5. docs/testing/IMESSAGE_TEST_APP.md - Major update with redesign notes 6. docs/apis/MESSAGE_ENDPOINTS.md - Updated to show /edge/message as primary 7. docs/implementation/2025-11-18-TEST-APP-REDESIGN.md - This document

Design Decisions

Why Streamlit Instead of React/Next.js?

Chosen: Streamlit (existing) Rationale: - Already integrated and working - Fast iteration for internal tools - Python-native (matches backend stack) - Custom CSS achieves production quality - Focus time on features, not framework setup

Trade-offs: - Less flexibility than React (acceptable for internal tool) - Some CSS hacks needed for professional styling (worth it) - Not suitable for user-facing product (this is dev testing tool only)

Why /edge/message Instead of /orchestrator/message?

Chosen: /edge/message Rationale: - Mac mini edge client uses /edge/message - Test app should match production behavior - FilteredMessage schema is the production contract - Consolidation on single endpoint simplifies backend

Migration: - Easy schema update (one function change) - Authentication already using Bearer tokens - No data loss (testing tool only)

Why "Chat with Sage" Instead of User-to-User?

Chosen: User-to-AI conversation model Rationale: - Reflects actual product behavior - Eliminates confusion about message routing - Makes testing intent clear ("test talking to Sage") - Matches user mental model

UX Changes: - Message bubbles: "You" vs "Sage" - Quick tests: "Hey Sage!" not "Hey Bob!" - Documentation: All examples show user→Sage

Next Steps

Immediate

  • Merge to dev branch
  • Update documentation
  • Test end-to-end flow
  • Deploy to staging environment

Future Enhancements

  • Add scenario recording/playback
  • Export conversation transcripts
  • Add performance benchmarking
  • Integration test suite using CLI
  • Multi-user simulation (group chats)

Lessons Learned

What Went Well

✅ Custom CSS in Streamlit can achieve production quality ✅ Schema migration was straightforward (single endpoint change) ✅ Documentation-driven development caught issues early ✅ User feedback ("this should be to Sage") was critical

What Could Be Improved

⚠️ Should have clarified messaging flow earlier ⚠️ Could have designed production UI from start

Best Practices Applied

✅ Professional design system (Stripe/Ramp/Brex reference) ✅ Comprehensive documentation updates ✅ Schema validation before testing ✅ User-centric UX improvements ✅ Iterative testing with real backend


Completed: November 18, 2025 Next Review: When adding new testing features