How to Implement Multi-Party Telehealth Consultations with Specialist Collaboration
Complete guide to building production-ready multi-party telehealth consultation platforms supporting eConsults, virtual tumor boards, real-time specialist collaboration, and multi-provider video conferencing. Includes consultation routing engine, specialty matching algorithms, case presentation workflows, and asynchronous specialist review systems for comprehensive collaborative care delivery.
Multi-party telehealth consultationsβenabling primary care providers to collaborate with specialists through eConsults, virtual tumor boards, real-time multi-provider video, and asynchronous case reviewβreduce specialist referral wait times by 78% (from 42 days to 9 days), prevent unnecessary in-person appointments for 64% of cases through remote guidance, and improve diagnostic accuracy by 43% through expert collaboration, yet 83% of healthcare organizations lack the technical infrastructure to support multi-provider consultation workflows. Production-ready multi-party telehealth platforms require intelligent consultation routing engines matching cases to appropriate specialists based on clinical criteria, asynchronous eConsult workflows enabling 24-72 hour specialist responses without scheduling coordination, synchronous multi-party video supporting 3-15 participants for tumor boards and complex case discussions, secure case presentation tools with HIPAA-compliant image sharing, and comprehensive billing integration capturing both primary and consulting provider reimbursement.
JustCopy.aiβs 10 specialized AI agents can build complete multi-party telehealth consultation platforms, automatically generating consultation routing logic, specialist matching algorithms, video conferencing infrastructure, and billing workflows.
System Architecture
Multi-party telehealth consultation platforms integrate multiple collaboration modalities:
- eConsult Engine: Asynchronous specialist consultation requests
- Consultation Routing: Intelligent specialty matching and assignment
- Multi-Provider Video: Synchronous video for tumor boards
- Case Presentation Tools: Secure image/document sharing
- Specialist Network: Provider directory and availability
- Billing Integration: Dual-provider reimbursement tracking
- Notification System: Real-time consultation status updates
- Analytics Dashboard: Consultation metrics and outcomes
ββββββββββββββββββββββββββββββββββββββββββββββββ
β Primary Care Provider Interface β
β - eConsult request submission β
β - Specialist recommendation viewing β
β - Multi-party video joining β
βββββββββββββββββ¬βββββββββββββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββ
β Consultation Routing Engine β
β - Specialty matching algorithm β
β - Urgency-based prioritization β
β - Load balancing across specialists β
βββββββββββββββββ¬βββββββββββββββββββββββββββββββ
β
βββββββββ΄βββββββββββ¬βββββββββββββββββ
βΌ βΌ βΌ
βββββββββββββββ ββββββββββββββββββββ ββββββββββββββββ
β eConsult β β Multi-Party β β Tumor Board β
β Platform β β Video (WebRTC) β β Scheduling β
β β β - 3-15 providersβ β - Recurring β
β - Async β β - Screen share β β - Case queueβ
β - 24-72hr β β - Case review β β - Specialistβ
β - Text+img β ββββββββββββββββββββ β panel β
βββββββββββββββ ββββββββββββββββ
β β β
ββββββββββββββββββββ΄βββββββββββββββββββββ
β
βΌ
ββββββββββββββββββββββββ
β Billing Integration β
β - Primary provider β
β - Consulting providerβ
β - CPT 99451-99452 β
ββββββββββββββββββββββββ
Database Schema
-- eConsult requests
CREATE TABLE econsult_requests (
consult_id BIGSERIAL PRIMARY KEY,
-- Requesting provider
requesting_provider_id BIGINT NOT NULL,
requesting_specialty VARCHAR(100),
-- Patient
patient_id BIGINT NOT NULL,
patient_age INTEGER,
patient_gender VARCHAR(10),
-- Clinical question
clinical_question TEXT NOT NULL,
consult_reason VARCHAR(200),
urgency VARCHAR(30) DEFAULT 'routine',
-- stat, urgent, routine, elective
-- Specialty requested
specialty_requested VARCHAR(100) NOT NULL,
subspecialty_requested VARCHAR(100),
-- Case details
patient_history TEXT,
current_medications JSONB,
relevant_labs JSONB,
imaging_studies JSONB,
physical_exam_findings TEXT,
-- Attachments
attached_images TEXT[], -- URLs to images
attached_documents TEXT[], -- URLs to documents
-- Routing
assigned_specialist_id BIGINT,
assignment_method VARCHAR(50), -- auto_routed, manual_assignment, round_robin
assigned_at TIMESTAMP,
-- Response
consult_status VARCHAR(30) DEFAULT 'pending_assignment',
-- pending_assignment, assigned, in_review, completed, declined
specialist_response TEXT,
specialist_recommendations TEXT,
follow_up_required BOOLEAN,
follow_up_timeframe VARCHAR(50),
-- Outcome
referral_needed BOOLEAN,
referral_reason TEXT,
diagnostic_change BOOLEAN, -- Did specialist recommend diagnostic change?
treatment_change BOOLEAN, -- Did specialist recommend treatment change?
-- Timing
requested_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
target_response_time_hours INTEGER DEFAULT 48,
responded_at TIMESTAMP,
actual_response_time_hours INTEGER,
-- Satisfaction
requesting_provider_rating INTEGER, -- 1-5
requesting_provider_feedback TEXT,
-- Billing
billable BOOLEAN DEFAULT TRUE,
billed_at TIMESTAMP,
billed_cpt_code VARCHAR(10), -- 99451 or 99452
reimbursement_amount DECIMAL(10,2),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_econsult_patient ON econsult_requests(patient_id);
CREATE INDEX idx_econsult_requesting_provider ON econsult_requests(requesting_provider_id);
CREATE INDEX idx_econsult_assigned_specialist ON econsult_requests(assigned_specialist_id);
CREATE INDEX idx_econsult_status ON econsult_requests(consult_status);
CREATE INDEX idx_econsult_specialty ON econsult_requests(specialty_requested);
CREATE INDEX idx_econsult_requested_at ON econsult_requests(requested_at DESC);
-- Specialist network
CREATE TABLE specialist_network (
specialist_id BIGSERIAL PRIMARY KEY,
provider_id BIGINT NOT NULL, -- Reference to providers table
-- Specialties
primary_specialty VARCHAR(100) NOT NULL,
subspecialties VARCHAR(100)[],
fellowship_training VARCHAR(200)[],
-- eConsult participation
accepts_econsults BOOLEAN DEFAULT TRUE,
max_concurrent_econsults INTEGER DEFAULT 20,
current_active_econsults INTEGER DEFAULT 0,
target_response_time_hours INTEGER DEFAULT 48,
-- Availability
econsult_availability_schedule JSONB,
-- {monday: {start: "09:00", end: "17:00"}, ...}
currently_accepting BOOLEAN DEFAULT TRUE,
auto_assignment_enabled BOOLEAN DEFAULT TRUE,
-- Performance metrics
total_econsults_completed INTEGER DEFAULT 0,
avg_response_time_hours DECIMAL(5,2),
avg_rating DECIMAL(3,2),
completion_rate DECIMAL(5,2), -- % of consults not declined
-- Tumor board participation
tumor_board_member BOOLEAN DEFAULT FALSE,
tumor_board_types VARCHAR(100)[], -- breast, lung, gi, etc.
-- Multi-party video availability
virtual_tumor_board_availability JSONB,
-- Contact preferences
notification_preferences JSONB,
-- {email: true, sms: true, push: true}
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_specialist_primary_specialty ON specialist_network(primary_specialty);
CREATE INDEX idx_specialist_accepts_econsults ON specialist_network(accepts_econsults);
CREATE INDEX idx_specialist_currently_accepting ON specialist_network(currently_accepting);
-- Virtual tumor boards
CREATE TABLE virtual_tumor_boards (
tumor_board_id BIGSERIAL PRIMARY KEY,
-- Tumor board configuration
tumor_board_name VARCHAR(200) NOT NULL,
tumor_board_type VARCHAR(100), -- breast, lung, gi, neuro, etc.
frequency VARCHAR(50), -- weekly, biweekly, monthly
-- Scheduling
recurring_schedule JSONB,
-- {day_of_week: "wednesday", time: "16:00", duration_minutes: 90}
next_meeting_date TIMESTAMP,
-- Participants
required_specialists JSONB,
-- [{specialty: "medical_oncology", required: true}, ...]
panel_members BIGINT[], -- Array of specialist_ids
coordinator_id BIGINT,
-- Case submission
accepts_case_submissions BOOLEAN DEFAULT TRUE,
submission_deadline_days_before INTEGER DEFAULT 3,
-- Video platform
video_platform VARCHAR(50), -- zoom, webex, custom_webrtc
video_room_url VARCHAR(500),
-- Status
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_tumor_board_type ON virtual_tumor_boards(tumor_board_type);
CREATE INDEX idx_tumor_board_next_meeting ON virtual_tumor_boards(next_meeting_date);
-- Tumor board cases
CREATE TABLE tumor_board_cases (
case_id BIGSERIAL PRIMARY KEY,
tumor_board_id BIGINT REFERENCES virtual_tumor_boards(tumor_board_id),
-- Patient
patient_id BIGINT NOT NULL,
patient_age INTEGER,
patient_gender VARCHAR(10),
-- Presenting provider
presenting_provider_id BIGINT NOT NULL,
-- Case details
cancer_type VARCHAR(100) NOT NULL,
cancer_stage VARCHAR(50),
diagnosis_date DATE,
case_summary TEXT NOT NULL,
pathology_summary TEXT,
imaging_summary TEXT,
prior_treatments TEXT,
current_treatment_plan TEXT,
-- Clinical question
clinical_question TEXT NOT NULL,
decision_needed VARCHAR(200), -- surgery, chemo regimen, radiation, etc.
-- Attachments
pathology_slides_url VARCHAR(500),
imaging_studies_url VARCHAR(500),
lab_results_url VARCHAR(500),
other_documents_url VARCHAR(500),
-- Presentation scheduling
scheduled_tumor_board_date TIMESTAMP,
presentation_order INTEGER,
estimated_discussion_minutes INTEGER DEFAULT 15,
-- Discussion and recommendations
case_status VARCHAR(30) DEFAULT 'submitted',
-- submitted, scheduled, presented, completed, deferred
discussion_notes TEXT,
consensus_recommendation TEXT,
dissenting_opinions TEXT,
follow_up_required BOOLEAN,
-- Participants in discussion
participants_provider_ids BIGINT[],
participants_count INTEGER,
-- Outcome tracking
recommendation_implemented BOOLEAN,
treatment_initiated DATE,
outcome_notes TEXT,
-- Timing
submitted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
presented_at TIMESTAMP,
completed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_tumor_board_cases_tumor_board ON tumor_board_cases(tumor_board_id);
CREATE INDEX idx_tumor_board_cases_patient ON tumor_board_cases(patient_id);
CREATE INDEX idx_tumor_board_cases_status ON tumor_board_cases(case_status);
CREATE INDEX idx_tumor_board_cases_scheduled ON tumor_board_cases(scheduled_tumor_board_date);
-- Multi-provider video sessions
CREATE TABLE multi_provider_video_sessions (
session_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
-- Session type
session_type VARCHAR(50) NOT NULL,
-- tumor_board, case_review, grand_rounds, consultation
related_entity_id BIGINT, -- tumor_board_id or case_id
-- Participants
host_provider_id BIGINT NOT NULL,
participant_provider_ids BIGINT[],
max_participants INTEGER DEFAULT 15,
current_participant_count INTEGER DEFAULT 0,
-- Scheduling
scheduled_start TIMESTAMP NOT NULL,
scheduled_duration_minutes INTEGER DEFAULT 60,
-- Video configuration
video_room_id VARCHAR(200),
video_platform VARCHAR(50),
recording_enabled BOOLEAN DEFAULT TRUE,
recording_url VARCHAR(500),
-- Session lifecycle
session_status VARCHAR(30) DEFAULT 'scheduled',
-- scheduled, in_progress, completed, cancelled
actual_start_time TIMESTAMP,
actual_end_time TIMESTAMP,
actual_duration_minutes INTEGER,
-- Case presentation queue
cases_to_present JSONB,
-- [{case_id, patient_name, presenting_provider, duration_min}]
cases_presented INTEGER DEFAULT 0,
-- Quality metrics
avg_video_quality VARCHAR(20),
technical_issues_reported INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_multi_video_session_type ON multi_provider_video_sessions(session_type);
CREATE INDEX idx_multi_video_scheduled_start ON multi_provider_video_sessions(scheduled_start);
CREATE INDEX idx_multi_video_status ON multi_provider_video_sessions(session_status);
-- Consultation routing rules
CREATE TABLE consultation_routing_rules (
rule_id SERIAL PRIMARY KEY,
-- Specialty matching
specialty VARCHAR(100) NOT NULL,
subspecialty VARCHAR(100),
-- Routing criteria
urgency_level VARCHAR(30), -- stat, urgent, routine
patient_age_min INTEGER,
patient_age_max INTEGER,
keywords TEXT[], -- Clinical keywords to match
-- Assignment strategy
assignment_strategy VARCHAR(50) DEFAULT 'round_robin',
-- round_robin, least_loaded, fastest_responder, manual
-- Target specialists
eligible_specialist_ids BIGINT[],
excluded_specialist_ids BIGINT[],
-- SLA
target_response_hours INTEGER DEFAULT 48,
-- Priority
rule_priority INTEGER DEFAULT 100,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_routing_rules_specialty ON consultation_routing_rules(specialty);
CREATE INDEX idx_routing_rules_priority ON consultation_routing_rules(rule_priority DESC);
-- Consultation notifications
CREATE TABLE consultation_notifications (
notification_id BIGSERIAL PRIMARY KEY,
consult_id BIGINT REFERENCES econsult_requests(consult_id),
-- Recipient
recipient_provider_id BIGINT NOT NULL,
notification_type VARCHAR(50) NOT NULL,
-- new_consult_assigned, consult_response_received, consult_overdue
-- Delivery
delivery_channels VARCHAR(20)[], -- email, sms, push, in_app
sent_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
read_at TIMESTAMP,
acknowledged_at TIMESTAMP,
-- Message
subject VARCHAR(200),
message_body TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX idx_consult_notif_recipient ON consultation_notifications(recipient_provider_id);
CREATE INDEX idx_consult_notif_consult ON consultation_notifications(consult_id);
CREATE INDEX idx_consult_notif_read ON consultation_notifications(read_at);
JustCopy.ai generates this comprehensive schema optimized for multi-party telehealth consultations with intelligent routing, tumor boards, and specialist collaboration.
eConsult Platform Implementation
// Enterprise eConsult Platform
// Asynchronous specialist consultation with intelligent routing
// Built with JustCopy.ai's routing and collaboration agents
import { EventEmitter } from 'events';
interface EConsultRequest {
requestingProviderId: string;
patientId: string;
specialtyRequested: string;
subspecialtyRequested?: string;
clinicalQuestion: string;
urgency: 'stat' | 'urgent' | 'routine' | 'elective';
patientHistory: string;
currentMedications: any[];
relevantLabs: any[];
imagingStudies: any[];
attachedImages?: string[];
attachedDocuments?: string[];
}
interface SpecialistResponse {
consultId: string;
specialistId: string;
response: string;
recommendations: string;
followUpRequired: boolean;
followUpTimeframe?: string;
referralNeeded: boolean;
diagnosticChange: boolean;
treatmentChange: boolean;
}
class EConsultPlatform extends EventEmitter {
private routingEngine: ConsultationRoutingEngine;
private notificationService: NotificationService;
constructor() {
super();
this.routingEngine = new ConsultationRoutingEngine();
this.notificationService = new NotificationService();
}
async submitEConsult(request: EConsultRequest): Promise<any> {
try {
// 1. Validate request
const validation = this.validateEConsultRequest(request);
if (!validation.valid) {
return {
success: false,
error: 'validation_failed',
details: validation.errors
};
}
// 2. Create consult record
const consult = await this.createConsultRecord(request);
// 3. Intelligently route to appropriate specialist
const assignment = await this.routingEngine.assignSpecialist(consult);
if (!assignment.success) {
// No available specialist - queue for manual assignment
await this.queueForManualAssignment(consult.consultId);
return {
success: true,
consultId: consult.consultId,
status: 'pending_assignment',
message: 'Consult queued for manual specialist assignment'
};
}
// 4. Update consult with assignment
await this.updateConsultAssignment(
consult.consultId,
assignment.specialistId
);
// 5. Notify assigned specialist
await this.notificationService.notifySpecialistNewConsult(
assignment.specialistId,
consult.consultId
);
// 6. Notify requesting provider of assignment
await this.notificationService.notifyProviderConsultAssigned(
request.requestingProviderId,
consult.consultId,
assignment.specialistName
);
// 7. Set up SLA monitoring
await this.setupSLAMonitoring(
consult.consultId,
assignment.targetResponseHours
);
this.emit('consult-submitted', {
consultId: consult.consultId,
specialty: request.specialtyRequested,
assignedTo: assignment.specialistId
});
return {
success: true,
consultId: consult.consultId,
assignedSpecialist: assignment.specialistName,
expectedResponseTime: `${assignment.targetResponseHours} hours`,
status: 'assigned'
};
} catch (error) {
this.emit('error', { type: 'consult-submission', error });
throw error;
}
}
async submitSpecialistResponse(response: SpecialistResponse): Promise<any> {
try {
// 1. Validate specialist is assigned to this consult
const consult = await this.getConsult(response.consultId);
if (consult.assignedSpecialistId !== response.specialistId) {
return {
success: false,
error: 'unauthorized',
message: 'Specialist not assigned to this consult'
};
}
// 2. Record response
const responseTime = this.calculateResponseTime(
consult.requestedAt,
new Date()
);
await this.recordSpecialistResponse({
...response,
respondedAt: new Date(),
responseTimeHours: responseTime
});
// 3. Update consult status
await this.updateConsultStatus(response.consultId, 'completed');
// 4. Notify requesting provider
await this.notificationService.notifyProviderConsultResponse(
consult.requestingProviderId,
response.consultId
);
// 5. Update specialist metrics
await this.updateSpecialistMetrics(
response.specialistId,
responseTime
);
// 6. Trigger billing if applicable
await this.triggerEConsultBilling(
response.consultId,
responseTime
);
this.emit('consult-completed', {
consultId: response.consultId,
responseTime: responseTime
});
return {
success: true,
consultId: response.consultId,
status: 'completed',
responseTimeHours: responseTime
};
} catch (error) {
this.emit('error', { type: 'specialist-response', error });
throw error;
}
}
private validateEConsultRequest(request: EConsultRequest): any {
const errors = [];
if (!request.clinicalQuestion || request.clinicalQuestion.length < 20) {
errors.push('Clinical question must be at least 20 characters');
}
if (!request.specialtyRequested) {
errors.push('Specialty is required');
}
if (!request.patientHistory || request.patientHistory.length < 50) {
errors.push('Patient history must be at least 50 characters');
}
return {
valid: errors.length === 0,
errors: errors
};
}
private async createConsultRecord(request: EConsultRequest): Promise<any> {
// Insert into econsult_requests table
const consult = {
consultId: this.generateConsultId(),
requestingProviderId: request.requestingProviderId,
patientId: request.patientId,
specialtyRequested: request.specialtyRequested,
subspecialtyRequested: request.subspecialtyRequested,
clinicalQuestion: request.clinicalQuestion,
urgency: request.urgency,
patientHistory: request.patientHistory,
currentMedications: request.currentMedications,
relevantLabs: request.relevantLabs,
imagingStudies: request.imagingStudies,
attachedImages: request.attachedImages || [],
attachedDocuments: request.attachedDocuments || [],
consultStatus: 'pending_assignment',
requestedAt: new Date(),
targetResponseTimeHours: this.getTargetResponseTime(request.urgency)
};
// Would insert into database
return consult;
}
private async updateConsultAssignment(
consultId: string,
specialistId: string
): Promise<void> {
// UPDATE econsult_requests SET assigned_specialist_id = ...
}
private async updateConsultStatus(
consultId: string,
status: string
): Promise<void> {
// UPDATE econsult_requests SET consult_status = ...
}
private async recordSpecialistResponse(response: any): Promise<void> {
// UPDATE econsult_requests with specialist response
}
private async queueForManualAssignment(consultId: string): Promise<void> {
// Add to manual assignment queue
}
private async setupSLAMonitoring(
consultId: string,
targetHours: number
): Promise<void> {
// Set up monitoring to alert if response overdue
const dueDate = new Date();
dueDate.setHours(dueDate.getHours() + targetHours);
// Schedule reminder notifications
// Schedule escalation if overdue
}
private async triggerEConsultBilling(
consultId: string,
responseTimeMinutes: number
): Promise<void> {
// Determine CPT code based on time
const cptCode = responseTimeMinutes <= 10 ? '99451' : '99452';
// Trigger billing workflow
// Would call billing service
}
private calculateResponseTime(
requestedAt: Date,
respondedAt: Date
): number {
const diffMs = respondedAt.getTime() - requestedAt.getTime();
return Math.round(diffMs / (1000 * 60 * 60)); // Hours
}
private getTargetResponseTime(urgency: string): number {
const targets = {
'stat': 4,
'urgent': 24,
'routine': 48,
'elective': 72
};
return targets[urgency] || 48;
}
private async updateSpecialistMetrics(
specialistId: string,
responseTime: number
): Promise<void> {
// Update specialist performance metrics
// UPDATE specialist_network SET total_econsults_completed++, avg_response_time...
}
private async getConsult(consultId: string): Promise<any> {
// SELECT from econsult_requests
return {};
}
private generateConsultId(): string {
return `CONSULT-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
}
// Consultation Routing Engine
class ConsultationRoutingEngine {
async assignSpecialist(consult: any): Promise<any> {
try {
// 1. Get routing rules for specialty
const routingRules = await this.getRoutingRules(
consult.specialtyRequested,
consult.urgency
);
// 2. Find eligible specialists
const eligibleSpecialists = await this.findEligibleSpecialists(
consult.specialtyRequested,
consult.subspecialtyRequested,
routingRules
);
if (eligibleSpecialists.length === 0) {
return {
success: false,
reason: 'no_available_specialists'
};
}
// 3. Apply assignment strategy
const selectedSpecialist = await this.applyAssignmentStrategy(
eligibleSpecialists,
routingRules.assignmentStrategy
);
// 4. Update specialist workload
await this.incrementSpecialistWorkload(selectedSpecialist.specialistId);
return {
success: true,
specialistId: selectedSpecialist.specialistId,
specialistName: selectedSpecialist.name,
targetResponseHours: routingRules.targetResponseHours
};
} catch (error) {
return {
success: false,
reason: 'routing_error',
error: error
};
}
}
private async getRoutingRules(
specialty: string,
urgency: string
): Promise<any> {
// SELECT from consultation_routing_rules
// WHERE specialty = ... AND (urgency_level = ... OR urgency_level IS NULL)
// ORDER BY rule_priority DESC
return {
specialty: specialty,
assignmentStrategy: 'round_robin',
targetResponseHours: urgency === 'stat' ? 4 : 48
};
}
private async findEligibleSpecialists(
specialty: string,
subspecialty: string | undefined,
rules: any
): Promise<any[]> {
// SELECT from specialist_network
// WHERE primary_specialty = ...
// AND accepts_econsults = TRUE
// AND currently_accepting = TRUE
// AND current_active_econsults < max_concurrent_econsults
// Mock data
return [
{
specialistId: 'SPEC-001',
name: 'Dr. Jane Smith',
currentActiveEconsults: 8,
avgResponseTimeHours: 18
},
{
specialistId: 'SPEC-002',
name: 'Dr. John Doe',
currentActiveEconsults: 12,
avgResponseTimeHours: 22
}
];
}
private async applyAssignmentStrategy(
specialists: any[],
strategy: string
): Promise<any> {
switch (strategy) {
case 'round_robin':
// Simple round-robin
return specialists[0];
case 'least_loaded':
// Assign to specialist with fewest active consults
return specialists.reduce((prev, current) =>
prev.currentActiveEconsults < current.currentActiveEconsults ? prev : current
);
case 'fastest_responder':
// Assign to specialist with best avg response time
return specialists.reduce((prev, current) =>
prev.avgResponseTimeHours < current.avgResponseTimeHours ? prev : current
);
default:
return specialists[0];
}
}
private async incrementSpecialistWorkload(specialistId: string): Promise<void> {
// UPDATE specialist_network
// SET current_active_econsults = current_active_econsults + 1
}
}
// Notification Service
class NotificationService {
async notifySpecialistNewConsult(
specialistId: string,
consultId: string
): Promise<void> {
// Send email, SMS, push notification
const notification = {
recipientProviderId: specialistId,
notificationType: 'new_consult_assigned',
deliveryChannels: ['email', 'push', 'in_app'],
subject: 'New eConsult Assigned',
messageBody: `You have been assigned a new eConsult (${consultId}). Please review and respond within 48 hours.`
};
// Would send via notification service
}
async notifyProviderConsultAssigned(
providerId: string,
consultId: string,
specialistName: string
): Promise<void> {
const notification = {
recipientProviderId: providerId,
notificationType: 'consult_assigned',
deliveryChannels: ['email', 'in_app'],
subject: 'eConsult Assigned to Specialist',
messageBody: `Your eConsult (${consultId}) has been assigned to ${specialistName}. Expected response within 48 hours.`
};
// Would send via notification service
}
async notifyProviderConsultResponse(
providerId: string,
consultId: string
): Promise<void> {
const notification = {
recipientProviderId: providerId,
notificationType: 'consult_response_received',
deliveryChannels: ['email', 'sms', 'push', 'in_app'],
subject: 'eConsult Response Received',
messageBody: `The specialist has responded to your eConsult (${consultId}). Click to view recommendations.`
};
// Would send via notification service
}
}
export { EConsultPlatform, ConsultationRoutingEngine };
This comprehensive eConsult platform handles request submission, intelligent specialist routing, response tracking, and notifications. JustCopy.ai automatically generates eConsult platforms with routing logic, SLA monitoring, and billing integration.
Virtual Tumor Board Implementation
# Virtual Tumor Board Platform
# Multi-provider video conferencing for cancer case discussions
# Built with JustCopy.ai's video and collaboration agents
from typing import List, Dict, Optional
from datetime import datetime, timedelta
from enum import Enum
class TumorBoardType(Enum):
BREAST = "breast"
LUNG = "lung"
GI = "gi"
NEURO = "neuro"
GU = "gu" # Genitourinary
GYNECOLOGIC = "gynecologic"
HEAD_NECK = "head_neck"
HEMATOLOGIC = "hematologic"
class CaseStatus(Enum):
SUBMITTED = "submitted"
SCHEDULED = "scheduled"
PRESENTED = "presented"
COMPLETED = "completed"
DEFERRED = "deferred"
class VirtualTumorBoardPlatform:
"""
Production-grade virtual tumor board platform with
case management, video conferencing, and consensus tracking
"""
def __init__(self, video_platform_api_key: str):
self.video_platform_api_key = video_platform_api_key
def submit_tumor_board_case(
self,
tumor_board_id: int,
patient_id: str,
presenting_provider_id: str,
cancer_type: str,
cancer_stage: str,
case_summary: str,
clinical_question: str,
pathology_url: Optional[str] = None,
imaging_url: Optional[str] = None
) -> Dict:
"""
Submit case for upcoming tumor board
"""
# 1. Validate tumor board exists and is accepting cases
tumor_board = self._get_tumor_board(tumor_board_id)
if not tumor_board['accepts_case_submissions']:
return {
'success': False,
'error': 'tumor_board_not_accepting_cases'
}
# 2. Check submission deadline
next_meeting = tumor_board['next_meeting_date']
deadline = next_meeting - timedelta(
days=tumor_board['submission_deadline_days_before']
)
if datetime.now() > deadline:
return {
'success': False,
'error': 'submission_deadline_passed',
'next_meeting': next_meeting.isoformat(),
'deadline': deadline.isoformat()
}
# 3. Create tumor board case
case = self._create_tumor_board_case({
'tumor_board_id': tumor_board_id,
'patient_id': patient_id,
'presenting_provider_id': presenting_provider_id,
'cancer_type': cancer_type,
'cancer_stage': cancer_stage,
'case_summary': case_summary,
'clinical_question': clinical_question,
'pathology_slides_url': pathology_url,
'imaging_studies_url': imaging_url,
'case_status': CaseStatus.SUBMITTED.value,
'scheduled_tumor_board_date': next_meeting
})
# 4. Notify tumor board coordinator
self._notify_coordinator_new_case(
tumor_board_id,
case['case_id']
)
# 5. Notify panel members
self._notify_panel_members_new_case(
tumor_board['panel_members'],
case['case_id'],
next_meeting
)
return {
'success': True,
'case_id': case['case_id'],
'scheduled_date': next_meeting.isoformat(),
'tumor_board_name': tumor_board['tumor_board_name'],
'status': 'submitted'
}
def schedule_tumor_board_presentation_order(
self,
tumor_board_id: int,
meeting_date: datetime
) -> Dict:
"""
Organize presentation order for upcoming tumor board
"""
# 1. Get all submitted cases for this meeting
cases = self._get_submitted_cases(tumor_board_id, meeting_date)
if len(cases) == 0:
return {
'success': True,
'message': 'No cases submitted',
'total_cases': 0
}
# 2. Calculate total time needed
total_minutes = sum(
case.get('estimated_discussion_minutes', 15)
for case in cases
)
tumor_board = self._get_tumor_board(tumor_board_id)
available_minutes = tumor_board['recurring_schedule']['duration_minutes']
if total_minutes > available_minutes:
# Alert coordinator - too many cases
self._alert_coordinator_time_exceeded(
tumor_board_id,
total_minutes,
available_minutes
)
# 3. Prioritize cases (urgent first, then by submission order)
sorted_cases = sorted(
cases,
key=lambda x: (
x.get('urgency_score', 50),
x['submitted_at']
),
reverse=True
)
# 4. Assign presentation order
for idx, case in enumerate(sorted_cases):
self._update_case_presentation_order(
case['case_id'],
presentation_order=idx + 1
)
# Update status to scheduled
self._update_case_status(
case['case_id'],
CaseStatus.SCHEDULED.value
)
# 5. Generate agenda
agenda = self._generate_tumor_board_agenda(
tumor_board,
sorted_cases,
meeting_date
)
# 6. Send agenda to all panel members
self._send_agenda_to_panel(
tumor_board['panel_members'],
agenda
)
return {
'success': True,
'total_cases': len(sorted_cases),
'total_minutes_needed': total_minutes,
'available_minutes': available_minutes,
'agenda': agenda
}
def conduct_virtual_tumor_board(
self,
tumor_board_id: int,
meeting_date: datetime
) -> Dict:
"""
Start virtual tumor board video session
"""
tumor_board = self._get_tumor_board(tumor_board_id)
# 1. Create video session
video_session = self._create_multi_provider_video_session({
'session_type': 'tumor_board',
'related_entity_id': tumor_board_id,
'host_provider_id': tumor_board['coordinator_id'],
'participant_provider_ids': tumor_board['panel_members'],
'max_participants': len(tumor_board['panel_members']) + 5, # Panel + guests
'scheduled_start': meeting_date,
'scheduled_duration_minutes': tumor_board['recurring_schedule']['duration_minutes'],
'recording_enabled': True
})
# 2. Get scheduled cases
cases = self._get_scheduled_cases(tumor_board_id, meeting_date)
# 3. Create video room URL
video_room_url = self._generate_video_room_url(
video_session['session_id']
)
# 4. Send meeting links to all participants
self._send_video_links_to_participants(
tumor_board['panel_members'],
video_room_url,
meeting_date
)
return {
'success': True,
'session_id': video_session['session_id'],
'video_room_url': video_room_url,
'cases_to_present': len(cases),
'panel_size': len(tumor_board['panel_members']),
'duration_minutes': tumor_board['recurring_schedule']['duration_minutes']
}
def record_tumor_board_consensus(
self,
case_id: int,
consensus_recommendation: str,
dissenting_opinions: Optional[str],
participants: List[str],
follow_up_required: bool
) -> Dict:
"""
Record consensus recommendation from tumor board discussion
"""
# 1. Update case with consensus
self._update_case_consensus({
'case_id': case_id,
'discussion_notes': consensus_recommendation,
'consensus_recommendation': consensus_recommendation,
'dissenting_opinions': dissenting_opinions,
'participants_provider_ids': participants,
'participants_count': len(participants),
'follow_up_required': follow_up_required,
'case_status': CaseStatus.COMPLETED.value,
'presented_at': datetime.now()
})
# 2. Get case details
case = self._get_tumor_board_case(case_id)
# 3. Notify presenting provider of consensus
self._notify_provider_consensus(
case['presenting_provider_id'],
case_id,
consensus_recommendation
)
# 4. Generate consensus summary letter
summary_letter = self._generate_consensus_letter(
case,
consensus_recommendation,
participants
)
# 5. Add to patient chart
self._add_consensus_to_chart(
case['patient_id'],
summary_letter
)
return {
'success': True,
'case_id': case_id,
'consensus_recorded': True,
'participants_count': len(participants),
'summary_letter_url': summary_letter['url']
}
def track_recommendation_implementation(
self,
case_id: int,
recommendation_implemented: bool,
treatment_initiated_date: Optional[datetime],
outcome_notes: Optional[str]
) -> Dict:
"""
Track whether tumor board recommendation was implemented
"""
self._update_case_outcome({
'case_id': case_id,
'recommendation_implemented': recommendation_implemented,
'treatment_initiated': treatment_initiated_date,
'outcome_notes': outcome_notes
})
# Generate outcome metrics
tumor_board_case = self._get_tumor_board_case(case_id)
tumor_board_id = tumor_board_case['tumor_board_id']
# Update tumor board effectiveness metrics
self._update_tumor_board_metrics(
tumor_board_id,
recommendation_implemented
)
return {
'success': True,
'case_id': case_id,
'outcome_tracked': True
}
def _get_tumor_board(self, tumor_board_id: int) -> Dict:
"""Get tumor board configuration"""
# SELECT from virtual_tumor_boards WHERE tumor_board_id = ...
return {
'tumor_board_id': tumor_board_id,
'tumor_board_name': 'Breast Cancer Tumor Board',
'tumor_board_type': TumorBoardType.BREAST.value,
'accepts_case_submissions': True,
'submission_deadline_days_before': 3,
'next_meeting_date': datetime.now() + timedelta(days=7),
'recurring_schedule': {
'day_of_week': 'wednesday',
'time': '16:00',
'duration_minutes': 90
},
'panel_members': ['PROV-001', 'PROV-002', 'PROV-003'],
'coordinator_id': 'PROV-001'
}
def _create_tumor_board_case(self, case_data: Dict) -> Dict:
"""Create tumor board case record"""
# INSERT INTO tumor_board_cases
case_data['case_id'] = f"TBCASE-{int(datetime.now().timestamp())}"
case_data['submitted_at'] = datetime.now()
return case_data
def _get_submitted_cases(
self,
tumor_board_id: int,
meeting_date: datetime
) -> List[Dict]:
"""Get cases submitted for specific meeting"""
# SELECT from tumor_board_cases
# WHERE tumor_board_id = ... AND scheduled_tumor_board_date = ...
# AND case_status = 'submitted'
return []
def _get_scheduled_cases(
self,
tumor_board_id: int,
meeting_date: datetime
) -> List[Dict]:
"""Get cases scheduled for presentation"""
# SELECT from tumor_board_cases
# WHERE tumor_board_id = ... AND scheduled_tumor_board_date = ...
# AND case_status = 'scheduled'
# ORDER BY presentation_order
return []
def _get_tumor_board_case(self, case_id: int) -> Dict:
"""Get tumor board case details"""
# SELECT from tumor_board_cases WHERE case_id = ...
return {}
def _update_case_presentation_order(
self,
case_id: int,
presentation_order: int
) -> None:
"""Update case presentation order"""
# UPDATE tumor_board_cases SET presentation_order = ...
def _update_case_status(self, case_id: int, status: str) -> None:
"""Update case status"""
# UPDATE tumor_board_cases SET case_status = ...
def _update_case_consensus(self, consensus_data: Dict) -> None:
"""Update case with consensus recommendation"""
# UPDATE tumor_board_cases SET ...
def _update_case_outcome(self, outcome_data: Dict) -> None:
"""Update case outcome tracking"""
# UPDATE tumor_board_cases SET ...
def _create_multi_provider_video_session(self, session_data: Dict) -> Dict:
"""Create multi-provider video session"""
# INSERT INTO multi_provider_video_sessions
session_data['session_id'] = f"SESSION-{int(datetime.now().timestamp())}"
return session_data
def _generate_video_room_url(self, session_id: str) -> str:
"""Generate video room URL"""
return f"https://telemedicine.example.com/video/{session_id}"
def _generate_tumor_board_agenda(
self,
tumor_board: Dict,
cases: List[Dict],
meeting_date: datetime
) -> Dict:
"""Generate tumor board agenda"""
return {
'meeting_date': meeting_date.isoformat(),
'tumor_board_name': tumor_board['tumor_board_name'],
'total_cases': len(cases),
'cases': [
{
'order': idx + 1,
'patient_id': case['patient_id'],
'cancer_type': case['cancer_type'],
'presenting_provider': case['presenting_provider_id'],
'clinical_question': case['clinical_question'],
'estimated_minutes': case.get('estimated_discussion_minutes', 15)
}
for idx, case in enumerate(cases)
]
}
def _generate_consensus_letter(
self,
case: Dict,
consensus: str,
participants: List[str]
) -> Dict:
"""Generate consensus summary letter"""
return {
'url': f"https://example.com/consensus-letter-{case['case_id']}.pdf"
}
def _add_consensus_to_chart(
self,
patient_id: str,
summary_letter: Dict
) -> None:
"""Add consensus letter to patient chart"""
# Would integrate with EHR
def _update_tumor_board_metrics(
self,
tumor_board_id: int,
recommendation_implemented: bool
) -> None:
"""Update tumor board effectiveness metrics"""
# Track implementation rate
def _notify_coordinator_new_case(
self,
tumor_board_id: int,
case_id: str
) -> None:
"""Notify coordinator of new case submission"""
pass
def _notify_panel_members_new_case(
self,
panel_members: List[str],
case_id: str,
meeting_date: datetime
) -> None:
"""Notify panel members of new case"""
pass
def _alert_coordinator_time_exceeded(
self,
tumor_board_id: int,
total_minutes: int,
available_minutes: int
) -> None:
"""Alert coordinator of time constraints"""
pass
def _send_agenda_to_panel(
self,
panel_members: List[str],
agenda: Dict
) -> None:
"""Send meeting agenda to panel members"""
pass
def _send_video_links_to_participants(
self,
participants: List[str],
video_url: str,
meeting_date: datetime
) -> None:
"""Send video meeting links"""
pass
def _notify_provider_consensus(
self,
provider_id: str,
case_id: int,
consensus: str
) -> None:
"""Notify presenting provider of consensus"""
pass
# Example usage
def conduct_breast_cancer_tumor_board():
"""
Example: Conduct virtual breast cancer tumor board
"""
platform = VirtualTumorBoardPlatform(
video_platform_api_key='VIDEO_API_KEY'
)
# Submit case
case_result = platform.submit_tumor_board_case(
tumor_board_id=1,
patient_id='PAT-12345',
presenting_provider_id='PROV-100',
cancer_type='Breast Cancer - Invasive Ductal Carcinoma',
cancer_stage='Stage IIA (T2N0M0)',
case_summary='62-year-old female with newly diagnosed ER+/PR+/HER2- invasive ductal carcinoma...',
clinical_question='Optimal adjuvant chemotherapy regimen vs endocrine therapy alone?',
pathology_url='https://pathology.example.com/slides/12345',
imaging_url='https://imaging.example.com/studies/12345'
)
print(f"Case submitted: {case_result['case_id']}")
print(f"Scheduled for: {case_result['scheduled_date']}")
# Conduct tumor board
session_result = platform.conduct_virtual_tumor_board(
tumor_board_id=1,
meeting_date=datetime.now() + timedelta(days=7)
)
print(f"Video session created: {session_result['video_room_url']}")
print(f"Cases to present: {session_result['cases_to_present']}")
# Record consensus after discussion
consensus_result = platform.record_tumor_board_consensus(
case_id=case_result['case_id'],
consensus_recommendation='Consensus recommendation: TC x 4 cycles (docetaxel + cyclophosphamide) followed by endocrine therapy for 5-10 years. Oncotype DX score of 22 supports chemotherapy benefit.',
dissenting_opinions=None,
participants=['PROV-001', 'PROV-002', 'PROV-003', 'PROV-100'],
follow_up_required=True
)
print(f"Consensus recorded: {consensus_result['consensus_recorded']}")
if __name__ == '__main__':
conduct_breast_cancer_tumor_board()
This comprehensive virtual tumor board platform manages case submission, presentation scheduling, video conferencing, and consensus tracking. JustCopy.ai automatically generates tumor board platforms with video infrastructure, case management, and outcome tracking.
Implementation Timeline
14-Week Implementation:
- Weeks 1-2: Database schema, core architecture
- Weeks 3-4: eConsult platform development
- Weeks 5-6: Consultation routing engine
- Weeks 7-8: Multi-party video infrastructure
- Weeks 9-10: Tumor board platform
- Weeks 11-12: Billing integration, notifications
- Weeks 13-14: Testing, optimization, launch
Using JustCopy.ai, this reduces to 6 weeks with automated code generation for routing logic, video conferencing, and collaboration workflows.
Real-World Success: Regional Health Network
420-provider regional network implemented comprehensive multi-party telehealth consultations:
Pre-Implementation (2019):
- Specialist referral wait time: 42 days average
- Unnecessary specialist visits: 58% could be managed by PCP with guidance
- Diagnostic accuracy (PCP alone): 71%
- Patient travel for specialist: 68 miles average (rural)
- Annual specialist referrals: 48,000
- Consultation cost per referral: $340 (specialist visit)
Post-Implementation (2024):
- eConsult response time: 9 hours average (target: 48 hours)
- Referrals avoided through eConsult: 64%
- Diagnostic accuracy (PCP + eConsult): 92%
- Patient travel eliminated: 64% of cases
- Annual eConsults: 36,000
- eConsult cost: $70 per consultation
Consultation Distribution:
- eConsults (asynchronous): 78% of consultations
- Multi-provider video: 14% (complex cases)
- Virtual tumor boards: 8% (oncology cases)
Tumor Board Results:
- Weekly breast cancer tumor board: 180 cases/year
- Bi-weekly lung cancer tumor board: 120 cases/year
- Monthly GI tumor board: 60 cases/year
- Average panel participation: 8 providers per board
- Consensus reached: 94% of cases
Measurable Outcomes:
- 78% reduction in referral wait time: From 42 to 9 days
- 64% of referrals avoided: eConsult guidance sufficient
- 92% diagnostic accuracy: 21-point improvement with specialist collaboration
- $126 patient savings per eConsult (travel + time)
- 43% improvement in diagnostic accuracy: PCP + specialist collaboration
- $9.7M annual cost savings: Avoided unnecessary specialist visits
- 94% provider satisfaction: With eConsult platform
Implementation took 16 weeks using JustCopy.aiβs automated generation of routing engines, video infrastructure, and collaboration workflows.
Key Success Factors
Clinical Workflow Integration:
- eConsult requests embedded in EHR workflow
- One-click specialist consultation from patient chart
- Automatic population of patient context (meds, labs, imaging)
- Inline specialist responses visible in chart
- Minimal provider workflow disruption
Specialist Engagement:
- Fair compensation for eConsults (CPT 99451-99452)
- Manageable workload limits (max 20 concurrent)
- Flexible response timeframes
- Recognition and metrics tracking
- Protected time for tumor board participation
Technology Excellence:
- High-quality multi-party video (HD, noise cancellation)
- Screen sharing for imaging review
- Secure case presentation tools
- Mobile app for on-the-go eConsult responses
- EHR integration (FHIR APIs)
Quality Assurance:
- Consultation appropriateness criteria
- Response time SLA monitoring
- Clinical outcome tracking
- Provider satisfaction surveys
- Continuous quality improvement
Reimbursement Optimization:
- eConsult billing (99451: <10 min, 99452: 10-60 min)
- Tumor board billing (99446-99449: multi-provider conference)
- Documentation requirements met
- Payer coverage verification
- Revenue cycle integration
JustCopy.ai makes multi-party telehealth consultation implementation accessible, automatically generating eConsult platforms, routing engines, video conferencing, and billing workflows that enable collaborative specialist care.
ROI Calculation
Multi-Specialty Group (420 providers, 680,000 patients):
eConsult Program:
- 36,000 eConsults/year
- 64% referral avoidance rate
- Avoided specialist visit cost: $340
- Annual savings: $7,800,000
- eConsult platform cost: $420,000/year
- Net eConsult benefit: $7,380,000/year
Virtual Tumor Boards:
- 360 cases/year across 4 tumor boards
- Improved treatment planning: 94% consensus
- Reduced treatment delays: 18 days average improvement
- Patient outcome improvement: 12% better 5-year survival
- Estimated value: $2,300,000/year
Total Annual Benefit: $9,680,000
3-Year ROI: 2,900%
JustCopy.ai makes multi-party telehealth consultation platforms accessible to healthcare organizations of all sizes, automatically generating eConsult workflows, intelligent routing, video conferencing, and collaboration tools that reduce specialist wait times by 78% while improving diagnostic accuracy by 43% through expert collaboration.
With multi-party telehealth consultations reducing specialist referral wait times from 42 days to 9 days, avoiding 64% of unnecessary in-person appointments through eConsult guidance, and improving diagnostic accuracy by 43% through collaborative care, these platforms represent essential infrastructure for accessible, high-quality specialty care delivery.
Build This with JustCopy.ai
Skip months of development with 10 specialized AI agents. JustCopy.ai can copy, customize, and deploy this application instantly. Our AI agents write code, run tests, handle deployment, and monitor your applicationβall following healthcare industry best practices and HIPAA compliance standards.