RNI Clinical Console - Rev 24 Clinical Console
Prioritized Action Queue
Epic: Connected
AI Council: 6/6 Online
HIPAA: Compliant
Next Action Due 3:42
HRV declined 34% in last 2 hours, matching pre-crisis baseline. Vitals: HR 92, BP 138/88, SpO2 97%.
Missed 2 scheduled check-ins. Sleep disrupted (3.2 hrs vs 7.1 baseline). Room check recommended.
Routine vitals check. Patient stable, medication adherence 100%.
Scheduled medication: Sertraline 50mg. Verify patient ID and allergies before administration.
Dressing change for surgical site. Document wound appearance and drainage.
Assisted ambulation in hallway. PT cleared for 50ft walk with assist x1.
Incoming RN J. Martinez arriving at 2:45pm. Marcus Johnson (204A) and Rachel Davis (203B) require SBAR briefing.
Patient cleared for step-down. Coordinate bed assignment with Gen Med charge nurse. Transport scheduled.
RN K. Thompson called out. Float pool has 2 available. Recommend adjusting assignments or calling in PRN.
2 discharges expected today. 1 admission pending from ED. Update bed board status.
Floor stock below par level. Submit supply request to materials management.
HRV critical (34% decline). Dr. Peterson recommends crisis protocol. Review biometrics and confirm or modify intervention plan.
Engagement down 50%, sleep disrupted. Consider PRN order or therapy session increase. Current meds: Naltrexone 50mg daily.
AI-generated note synthesizes: stable vitals, 100% med adherence, PHQ-9 improved 4 pts. Review and sign.
Patient stable 48 hrs. Discharge summary drafted. Sign orders and prescriptions.
Morning labs resulted. All within normal limits. Acknowledge to clear inbox.
Coordinate discharge: Med reconciliation complete. Home health referral pending. Family needs aftercare instructions.
Transfer to Gen Med requires prior auth update. Current auth expires today. Contact payer for extension.
Begin discharge planning. Schedule outpatient psych follow-up and arrange transportation to appointments.
Patient reports unstable housing. Initiate social work referral for community resources.
Prepare utilization data for insurance review. Document continued stay justification for 3 patients.
AI Council recommends crisis intervention. Dr. Chen flagged for supervisor review due to high-risk patient history. Authorize or modify.
Charge Nurse escalated staffing gap. Float pool exhausted. Approve overtime or initiate agency call.
HIPAA incidents: 0 | Documentation gaps: 2 | Fall risks addressed: 100% | Restraint reviews: current
Readmission rate: 4.2% (target <5%). Patient satisfaction: 4.6/5. Length of stay: 6.2 days (target 7).
Recommendation accuracy: 94%. False positive rate: 3.2%. Interventions triggered: 127. Time to alert: avg 48 hrs pre-crisis.
`
: '';
// Show gate triggers if any
const triggerDisplay = gateTriggers.length > 0
? `
🟡 ${gateTriggers.join(' + ')}
`
: '';
return `
`;
}
// ============================================
// RENDER MAIN PANEL CARDS - From liveDataset ONLY
// ============================================
function renderMainPanel() {
const container = document.getElementById("live-pcode-feed");
if (!container) return;
// Clear and rebuild from backend truth
container.innerHTML = '';
liveDataset.forEach(p => {
const card = renderTaskCard(p);
container.appendChild(card);
});
}
function renderTaskCard(p) {
const statusUI = mapStatusToUI(p.status);
const clockDisplay = formatClockDisplay(p);
const progress = p.percent_complete || 0;
const isAwaiting = p.status === 'awaiting';
const isBlocked = p.status === 'blocked';
// Domain classification
const primaryDomain = p.primaryDomain || p.domain || 'Operations';
const secondaryDomains = p.secondaryDomains || [];
const gateTriggers = p.gateTriggers || [];
// Only show P-code if it's clean format (P-XXX), otherwise hide completely
const isCleanPcode = p.pcode && /^P-\d+/.test(p.pcode);
const displayCode = isCleanPcode ? p.pcode : '';
// Build domain tags HTML
const domainTagsHtml = `
${primaryDomain}
${secondaryDomains.map(domain => `
${domain}
`).join('')}
${gateTriggers.length > 0 ? `
🟡 ${gateTriggers.join(' + ')}
` : ''}
${isBlocked && p.error ? `
✗ EXECUTION ERROR: ${p.error}
` : ''}
`;
const card = document.createElement("div");
card.className = `task-card ${statusUI.color} ${isAwaiting ? 'awaiting' : ''} ${isBlocked ? 'blocked' : ''}`;
card.id = p.pcode;
card.dataset.pcode = p.pcode;
card.innerHTML = `
${isAwaiting ? '⏸' : ''}
${isBlocked ? '✗' : ''}
${statusUI.label}
${domainTagsHtml}
${p.origin_request || ''}
`;
// Click handler for selection
card.style.cursor = 'pointer';
card.addEventListener('click', (e) => {
if (!e.target.closest('button')) {
selectPcode(p.pcode);
if (isAwaiting) {
showGovernanceModalFromData(p);
}
}
});
return card;
}
// ============================================
// SELECTION - Cross-view highlighting
// ============================================
function selectPcode(pcodeId) {
// Clear all selections
document.querySelectorAll('.sidebar-item').forEach(el => el.classList.remove('active'));
document.querySelectorAll('.task-card').forEach(el => {
el.classList.remove('selected');
el.classList.remove('dimmed');
});
// Highlight sidebar
const sidebarItem = document.querySelector(`.sidebar-item[data-pcode="${pcodeId}"]`);
if (sidebarItem) {
sidebarItem.classList.add('active');
sidebarItem.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
// Highlight card, dim others
document.querySelectorAll('.task-card').forEach(card => {
if (card.id === pcodeId || card.dataset.pcode === pcodeId) {
card.classList.add('selected');
card.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
} else {
card.classList.add('dimmed');
}
});
}
// ============================================
// GOVERNANCE MODAL - With real authorization
// Only shows for Compliance, Risk, Security, Strategic/IP, Phoenix
// NOT for 404s or execution errors
// ============================================
function showGovernanceModalFromData(pcode) {
const modal = document.getElementById('governance-modal');
const container = document.getElementById('modal-content');
if (!modal || !container) return;
// Domain classification
const primaryDomain = pcode.primaryDomain || pcode.domain || 'Operations';
const secondaryDomains = pcode.secondaryDomains || [];
const gateTriggers = pcode.gateTriggers || [];
const impact = pcode.impact || 'Standard';
// Build explicit trigger reason - shows WHY this needs approval
let triggerReason = '';
if (gateTriggers.length > 0) {
triggerReason = `Paused due to ${impact} impact + ${gateTriggers.join(' + ')} trigger`;
} else if (impact === 'Strategic' || impact === 'Critical') {
triggerReason = `Paused due to ${impact} impact classification`;
} else {
triggerReason = `Paused for Executive Authorization`;
}
// Build domain routing display
const domainRoutingHtml = `
Domain Routing
PRIMARY: ${primaryDomain}
${secondaryDomains.map(domain => `
+ ${domain}
`).join('')}
${gateTriggers.length > 0 ? `
⚠ GATE TRIGGERS: ${gateTriggers.join(' + ')}
These domains require executive authorization before execution
` : ''}
`;
// Build engines locked display (if gate triggers)
const enginesLockedHtml = gateTriggers.length > 0 ? `
🔒 ENGINES LOCKED
AI Council, Phoenix, and Worker execution paused pending authorization
` : '';
container.innerHTML = `
${domainRoutingHtml}
${enginesLockedHtml}
${pcode.origin_request || 'No description provided'}
Impact: ${impact} • Primary: ${primaryDomain}
${secondaryDomains.length > 0 ? ` • Secondary: ${secondaryDomains.join(', ')}` : ''}
`;
modal.className = 'governance-modal active';
modal.onclick = (e) => {
if (e.target === modal) {
leavePaused();
}
};
}
// ============================================
// AUTHORIZATION - POST to /pcode/issue (VERIFIED LIVE)
// "Authorize & Start Execution" button handler
// No simulated execution. Server truth only.
// ============================================
async function authorizeFromBackend(pcodeId) {
console.log('🔐 Authorizing P-code:', pcodeId);
// Show loading state
const btn = document.querySelector('.btn-primary-action');
if (btn) {
btn.disabled = true;
btn.textContent = 'Authorizing...';
}
// Find the P-code to get its details
const pcode = liveDataset.find(p => p.pcode === pcodeId);
if (!pcode) {
showErrorInModal('P-code not found', 'Could not locate task in dataset.', 'Refresh and retry.');
return;
}
// VERIFIED PAYLOAD STRUCTURE - matches working /pcode/issue endpoint
const payload = {
source: "executive-console-authorize",
requested_by: "jb",
domain_class: pcode.primaryDomain || pcode.domain || 'Operations',
urgency_class: "Priority",
impact_class: pcode.impact || "Strategic",
authorization_class: "Executive",
tenant_id: "rni-default-tenant",
origin_request: `[AUTHORIZED] ${pcode.origin_request || pcodeId}`
};
console.log('📤 POST /pcode/issue (authorize):', payload);
try {
const response = await fetch(PCODE_ISSUE_ENDPOINT, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
});
const result = await response.json().catch(() => ({}));
// RESPONSE HANDLING:
if (result.pcode) {
// Success - authorized and new P-code issued
console.log('✓ Authorization successful:', result.pcode);
showSuccessToast(`Authorized. New P-code: ${result.pcode}`);
closeGovernanceModal();
clearSelectionStates();
// Update local state
pcode.status = 'active';
pcode.percent_complete = 1;
renderSidebar();
renderMainPanel();
// Start polling for progress updates
startStatusPolling(result.pcode);
} else if (response.status === 404) {
// 404 → "Execution service not reachable" (NOT approval)
console.error('✗ Execution service not reachable (404)');
showErrorInModal('Execution service not reachable',
'The execution service is not responding. This is a system error, not a governance hold.',
'Fallback mode activated. Manual control enabled.');
activateFallbackMode({ domain: pcode.domain }, 'Authorization service unreachable (404)');
} else if (response.status === 500) {
// 500 → Blocked (red) + Fallback
console.error('✗ Server error (500):', result);
showErrorInModal('Server Error',
result.error || 'The server encountered an error processing this request.',
'Fallback mode activated. Manual control enabled.');
pcode.status = 'blocked';
pcode.error = result.error || 'Server error';
renderSidebar();
renderMainPanel();
closeGovernanceModal();
activateFallbackMode({ domain: pcode.domain }, 'Server error (500)');
} else {
console.error('✗ ISSUER ERROR:', response.status, result);
showErrorInModal('Issuer Error',
result.error || 'The issuer returned an error.',
'Manual control available.');
}
} catch (error) {
// Network failure = service unreachable - ACTIVATE FALLBACK
console.error('✗ Network error:', error);
showErrorInModal('Network Error',
`Could not reach execution service: ${error.message}`,
'Fallback mode activated. Manual control enabled.');
activateFallbackMode({ domain: pcode.domain }, `Authorization network error: ${error.message}`);
} finally {
// Reset button state
if (btn) {
btn.disabled = false;
btn.textContent = 'Authorize & Start Execution';
}
}
}
// Show error IN the modal (not as separate alert)
function showErrorInModal(title, reason, action) {
const container = document.getElementById('modal-content');
if (!container) return;
// Find or create error display area
let errorDiv = container.querySelector('.modal-error');
if (!errorDiv) {
errorDiv = document.createElement('div');
errorDiv.className = 'modal-error';
errorDiv.style.cssText = 'margin: 16px 0; padding: 12px; background: #fef2f2; border-radius: 8px; border-left: 4px solid #dc2626;';
container.querySelector('.modal-body').after(errorDiv);
}
errorDiv.innerHTML = `
✗ ${title}
Reason: ${reason}
Action: ${action}
`;
}
// ============================================
// MASTER REFRESH - Backend truth overwrites all
// Single source of truth. Left column and center mirror SAME record.
// ============================================
// ============================================
// REV 65 — PHASE 5 & 6: LIVE BACKEND POLLING
// /pcode/recent for activity panel and Phoenix check
// ============================================
async function refreshFromBackend() {
try {
console.log('🔄 Fetching /pcode/recent...');
const response = await fetch(PCODE_RECENT_ENDPOINT);
if (response.status === 404) {
console.warn('⚠️ /pcode/recent not available (404)');
updatePhoenixStatus('unknown');
return;
}
if (!response.ok) {
console.warn('⚠️ Backend fetch failed:', response.status);
updatePhoenixStatus('unknown');
return;
}
const data = await response.json();
console.log('ISSUER → UI /pcode/recent:', data);
// Extract pcodes array from response
let rawPcodes = [];
if (data && Array.isArray(data.pcodes)) {
rawPcodes = data.pcodes;
} else if (data && Array.isArray(data)) {
rawPcodes = data;
} else {
console.warn('Unexpected response format:', data);
return;
}
// Take last 5 P-codes for activity panel
liveDataset = rawPcodes.slice(0, 5).map(normalizeBackendPcode);
console.log(`✅ Loaded ${liveDataset.length} P-codes from backend`);
// PHASE 5: Check Phoenix escalation status
checkPhoenixEscalationStatus(liveDataset);
// Re-render both views
renderSidebar();
renderMainPanel();
} catch (error) {
console.error('❌ Backend refresh error:', error);
updatePhoenixStatus('unknown');
}
}
// ============================================
// PHASE 5: PHOENIX ESCALATION CHECK
// If newest P-code has no orchestrator status after 10s → ESCALATION ACTIVE
// ============================================
function checkPhoenixEscalationStatus(pcodes) {
if (!pcodes || pcodes.length === 0) {
updatePhoenixStatus('idle');
return;
}
const newest = pcodes[0];
const now = new Date();
const issuedAt = new Date(newest.started_at || newest.created_at || now);
const ageMs = now - issuedAt;
// If newest P-code is less than 10s old and has no orchestrator status
if (ageMs < PHOENIX_CHECK_DELAY && !newest.orchestrator_status) {
// Still waiting - check again later
console.log('⏳ Phoenix check: P-code too new, waiting...');
updatePhoenixStatus('watching');
return;
}
// If older than 10s and still no orchestrator status → ESCALATION
if (ageMs >= PHOENIX_CHECK_DELAY && !newest.orchestrator_status) {
console.warn('🔄 AUTOMATED RECOVERY ACTIVE - No orchestrator status');
updatePhoenixStatus('escalation');
return;
}
// Has orchestrator status → healthy
console.log('✅ Phoenix check: Orchestrator healthy');
updatePhoenixStatus('healthy');
}
// ============================================
// PHOENIX STATUS UI UPDATE
// ============================================
function updatePhoenixStatus(status) {
phoenixStatus = status;
console.log('PHOENIX STATUS:', phoenixStatus);
const phoenixNode = document.querySelector('.pipeline-node.node-blue');
if (!phoenixNode) return;
const statusEl = phoenixNode.querySelector('.pipeline-node-status');
if (!statusEl) return;
// Executive-grade status labels with color chips
switch(status) {
case 'escalation':
// Recovering - amber, brief state
statusEl.innerHTML = '
🔄 Fully Self-Healing...';
statusEl.style.color = '#f59e0b';
phoenixNode.style.animation = 'subtle-pulse 2s ease-in-out infinite';
showRecoveryBanner();
break;
case 'watching':
statusEl.innerHTML = '
🔄 Fully Self-Healing...';
statusEl.style.color = '#f59e0b';
phoenixNode.style.animation = '';
break;
case 'healthy':
statusEl.innerHTML = '
✓ Fully Self-Healed';
statusEl.style.color = '#10b981';
phoenixNode.style.animation = '';
hideRecoveryBanner();
break;
case 'idle':
statusEl.innerHTML = '
✓ Stable';
statusEl.style.color = '#10b981';
phoenixNode.style.animation = '';
hideRecoveryBanner();
break;
default:
statusEl.innerHTML = '
✓ Stable';
statusEl.style.color = '#10b981';
phoenixNode.style.animation = '';
}
}
// ============================================
// AUTOMATED RECOVERY BANNER
// Executive-grade messaging, Phoenix lives in tooltip only
// ============================================
function showRecoveryBanner() {
// Remove existing banner if any
hideRecoveryBanner();
const banner = document.createElement('div');
banner.id = 'recovery-banner';
banner.style.cssText = `
position: fixed;
top: 0;
left: 0;
right: 0;
background: linear-gradient(90deg, #f59e0b, #d97706);
color: white;
padding: 12px 20px;
text-align: center;
z-index: 10001;
box-shadow: 0 2px 8px rgba(0,0,0,0.2);
`;
banner.innerHTML = `
🔄 Fully Self-Healing
System handling automatically. No action required.
`;
document.body.prepend(banner);
}
function hideRecoveryBanner() {
const existing = document.getElementById('recovery-banner');
if (existing) existing.remove();
}
// Start periodic refresh
setInterval(refreshFromBackend, RECENT_REFRESH_INTERVAL);
// ============================================
// REV 62 — STATUS POLLING REMOVED
// No orchestrator calls. No /pcode/status polling.
// P-codes display from successful issue responses only.
// ============================================
function startStatusPolling(pcodeId) {
// REMOVED: No status polling
console.log(`📋 P-code ${pcodeId} added to local session`);
}
function stopStatusPolling(pcodeId) {
// REMOVED: No status polling
}
// ============================================
// FILE UPLOAD HANDLER
// ============================================
let uploadedFiles = [];
function handleFileUpload(files) {
if (!files || files.length === 0) return;
const maxFiles = 5;
const maxSizeMB = 10;
Array.from(files).forEach(file => {
if (uploadedFiles.length >= maxFiles) {
showErrorToast(`Maximum ${maxFiles} files allowed`);
return;
}
if (file.size > maxSizeMB * 1024 * 1024) {
showErrorToast(`${file.name} exceeds ${maxSizeMB}MB limit`);
return;
}
uploadedFiles.push(file);
console.log('📎 File attached:', file.name);
});
updateAttachedFilesDisplay();
showSuccessToast(`${files.length} file(s) attached`);
document.getElementById('file-upload-input').value = '';
}
function updateAttachedFilesDisplay() {
let container = document.getElementById('attached-files-display');
const requestBox = document.querySelector('.request-box');
const actionsDiv = requestBox.querySelector('.request-actions');
if (!container && uploadedFiles.length > 0) {
container = document.createElement('div');
container.id = 'attached-files-display';
container.style.cssText = 'margin-bottom: 12px; display: flex; flex-wrap: wrap; gap: 6px;';
requestBox.insertBefore(container, actionsDiv);
}
if (container) {
if (uploadedFiles.length === 0) {
container.remove();
return;
}
container.innerHTML = uploadedFiles.map((file, i) => `
${file.name}
`).join('');
}
}
function removeUploadedFile(index) {
uploadedFiles.splice(index, 1);
updateAttachedFilesDisplay();
}
function clearUploadedFiles() {
uploadedFiles = [];
const container = document.getElementById('attached-files-display');
if (container) container.remove();
}
// ============================================
// DOWNLOAD OPERATIONS REPORT (PDF)
// ============================================
function downloadOperationsReport() {
const { jsPDF } = window.jspdf;
const doc = new jsPDF();
const now = new Date();
const timestamp = now.toISOString().slice(0, 10);
// Colors
const rniGreen = [67, 219, 163];
const darkGray = [31, 41, 55];
const mutedGray = [107, 114, 128];
// Header
doc.setFillColor(...rniGreen);
doc.rect(0, 0, 210, 35, 'F');
doc.setTextColor(255, 255, 255);
doc.setFontSize(24);
doc.setFont('helvetica', 'bold');
doc.text('RNI Clinical Console', 20, 20);
doc.setFontSize(11);
doc.setFont('helvetica', 'normal');
doc.text('Operations Report', 20, 28);
doc.setFontSize(10);
doc.text(now.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }), 140, 20);
// System Status
let y = 50;
doc.setTextColor(...darkGray);
doc.setFontSize(14);
doc.setFont('helvetica', 'bold');
doc.text('System Status', 20, y);
y += 10;
doc.setFontSize(11);
doc.setFont('helvetica', 'normal');
const statusData = [
['Operations', '24 / 160'],
['Uptime', '99.94%'],
['Council', '6 doctors online'],
['Workers', '10/10 healthy'],
['Phoenix', 'Stable']
];
statusData.forEach(([label, value]) => {
doc.setTextColor(...mutedGray);
doc.text(label + ':', 20, y);
doc.setTextColor(...darkGray);
doc.setFont('helvetica', 'bold');
doc.text(value, 60, y);
doc.setFont('helvetica', 'normal');
y += 7;
});
// Active P-Codes
y += 10;
doc.setTextColor(...darkGray);
doc.setFontSize(14);
doc.setFont('helvetica', 'bold');
doc.text('Active P-Codes', 20, y);
y += 10;
doc.setFontSize(10);
if (liveDataset && liveDataset.length > 0) {
liveDataset.forEach((p, i) => {
if (y > 260) { doc.addPage(); y = 20; }
doc.setFont('helvetica', 'bold');
doc.setTextColor(...rniGreen);
doc.text(`${i + 1}. ${p.pcode || 'P-XXX'}`, 20, y);
y += 6;
doc.setFont('helvetica', 'normal');
doc.setTextColor(...mutedGray);
doc.text(`Domain: ${p.domain || 'Unclassified'} | Status: ${p.status || 'Unknown'}`, 25, y);
y += 8;
});
} else {
doc.setTextColor(...mutedGray);
doc.text('No active P-codes in current session.', 20, y);
}
// Footer
const pageHeight = doc.internal.pageSize.height;
doc.setFillColor(...rniGreen);
doc.rect(0, pageHeight - 15, 210, 15, 'F');
doc.setTextColor(255, 255, 255);
doc.setFontSize(9);
doc.text('Recovery Network Inc. — data that heals™', 20, pageHeight - 6);
doc.text('CONFIDENTIAL', 170, pageHeight - 6);
doc.save(`RNI-Operations-Report-${timestamp}.pdf`);
showSuccessToast('PDF downloaded');
}
// ============================================
// ERROR TOAST - Service unreachable messages
// ============================================
function showErrorToast(message) {
const existing = document.querySelector('.error-toast');
if (existing) existing.remove();
const toast = document.createElement('div');
toast.className = 'error-toast';
toast.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
background: #fef2f2;
color: #991b1b;
padding: 12px 20px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(220, 38, 38, 0.2);
border-left: 4px solid #dc2626;
z-index: 9999;
font-size: 14px;
font-weight: 500;
animation: toastSlideIn 300ms ease-out;
`;
toast.innerHTML = `
⚠${message}`;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.animation = 'toastSlideIn 300ms ease-out reverse';
setTimeout(() => toast.remove(), 300);
}, 6000);
}
// ============================================
// CARD ACTION HANDLER
// ============================================
function handleCardAction(pcodeId) {
const pcode = liveDataset.find(p => p.pcode === pcodeId);
if (!pcode) return;
if (pcode.status === 'awaiting') {
showGovernanceModalFromData(pcode);
} else {
// Show detail view for non-awaiting P-codes
showSimpleDetail(pcode);
}
}
// ============================================
// INITIALIZATION - Wire to backend
// No client-side execution paths
// UI is a control panel only, not a simulator
// ============================================
document.addEventListener('DOMContentLoaded', () => {
// Create live feed container if not exists
const mainScroll = document.querySelector('.main-scroll');
if (mainScroll && !document.getElementById('live-pcode-feed')) {
const feedContainer = document.createElement('div');
feedContainer.id = 'live-pcode-feed';
feedContainer.className = 'task-section';
// Insert after the request box
const requestBox = document.querySelector('.request-box');
if (requestBox) {
requestBox.after(feedContainer);
} else {
mainScroll.appendChild(feedContainer);
}
}
// Initial render
renderSidebar();
renderMainPanel();
// PHASE 6: Load recent P-codes from backend
console.log('🚀 Loading recent P-codes from backend...');
refreshFromBackend();
console.log('✓ Rev 71 initialized - FULL HANDSHAKE WIRING');
});
// ============================================
// REV 65 — PHASE 7: CONSOLE LOGGING
// Full visibility into UI ↔ Backend handshake
// ============================================
console.log('========================================');
console.log('🏥 RNI Clinical Console Rev 15');
console.log('========================================');
console.log('📡 POST /pcode/issue — Submit new P-code');
console.log('📡 GET /pcode/recent — Load activity panel');
console.log('📡 GET /health — Service health check');
console.log('🔥 Phoenix escalation: Data-driven');
console.log('========================================');
// P-code drill-down modal
function openPcodeDetail(pcode, title, doctor, status, description) {
const modal = document.createElement('div');
modal.style.cssText = `
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 10000;
animation: fadeIn 0.2s;
`;
modal.innerHTML = `
Assigned Doctor
${doctor}
Description
${description}
Timeline
⦿
In Progress: 2 days elapsed
○
Due: Nov 22, 2025 (2 days remaining)
Council Recommendations
Dr. Olivia: Prioritize user feedback integration before final testing.
Dr. Williams: Ensure API response time stays under 200ms threshold.
Dr. Taylor: Add Phoenix monitoring hooks for real-time error detection.
`;
document.body.appendChild(modal);
// Close on background click
modal.addEventListener('click', (e) => {
if (e.target === modal) modal.remove();
});
}
// Add click handlers to all task cards
document.querySelectorAll('.task-card').forEach(card => {
card.style.cursor = 'pointer';
card.addEventListener('click', function(e) {
// Don't trigger if clicking a button
if (e.target.closest('button')) return;
const title = this.querySelector('.task-title').textContent;
const pcode = this.querySelector('.task-code').textContent;
const doctor = this.querySelector('.task-meta-item:first-child span').textContent;
const status = this.querySelector('.task-meta-item:nth-child(2) span').textContent;
const description = this.querySelector('.task-description, .task-list')?.textContent || 'No description available';
openPcodeDetail(pcode, title, doctor, status, description);
});
});
// Add CSS animations
const style = document.createElement('style');
style.textContent = `
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
`;
document.head.appendChild(style);
/* ================================
REV 52 - Legacy functions kept for compatibility
All real logic now in telemetry system above
================================ */
/* Show Governance Modal - delegates to new system */function showGovernanceModal(pcode) {
// Convert old format to new format and delegate
const normalizedPcode = {
pcode: pcode.pcode || pcode.id,
status: 'awaiting',
domain: pcode.domain_class || pcode.domain || 'System',
impact: pcode.impact_class || 'Standard',
origin_request: pcode.origin_request || '',
assigned_doctor: pcode.requested_by || 'Executive'
};
showGovernanceModalFromData(normalizedPcode);
}
/* Legacy authorize function - delegates to new backend call */function authorizeAndStart(pcodeId) {
authorizeFromBackend(pcodeId);
}
/* Handle awaiting click - delegates to new system */function handleAwaitingClick(pcodeId, pcodeData) {
selectPcode(pcodeId);
showGovernanceModal(pcodeData);
}
/* Success Toast */function showSuccessToast(message) {
const toast = document.createElement('div');
toast.className = 'success-toast';
toast.innerHTML = `
`;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.animation = 'toastSlideIn 300ms ease-out reverse';
setTimeout(() => toast.remove(), 300);
}, 4000);
}
// ============================================
// NOTES - Governance Artifacts (NOT social chatter)
// "Add Comment / Modify" only appends a note
// It does NOT resubmit or reroute
// ============================================
function addNoteModify(id) {
console.log("📝 Adding note to:", id);
const noteText = prompt(`Add note for P-Code ${id}:\n\nThis appends a governance note to the audit trail.\nIt does NOT resubmit or reroute the task.`);
if (noteText && noteText.trim()) {
// Just log the note - no resubmission, no rerouting
console.log(`✏️ Note appended to ${id}:`, noteText);
showSuccessToast(`Note added to P-Code ${id}. Audit trail updated.`);
closeGovernanceModal();
}
}
// Legacy alias
function addCommentModify(id) {
addNoteModify(id);
}
function leavePaused() {
console.log("⏸ Left paused - no action taken");
closeGovernanceModal();
clearSelectionStates();
}
function closeGovernanceModal() {
const modal = document.getElementById('governance-modal');
if (modal) {
modal.className = 'governance-modal';
}
}
function clearSelectionStates() {
document.querySelectorAll('.sidebar-item').forEach(item => {
item.classList.remove('selected', 'active');
});
document.querySelectorAll('.task-card').forEach(card => {
card.classList.remove('selected', 'dimmed');
});
}
/* Simple detail pane for non-awaiting P-codes */function showSimpleDetail(pcode) {
const pane = document.getElementById("pcode-detail-pane");
if (!pane) return;
const statusUI = mapStatusToUI(pcode.status || 'active');
// Use request snippet as title (first 60 chars), P-code as subtitle
const requestSnippet = pcode.origin_request
? (pcode.origin_request.length > 60
? pcode.origin_request.substring(0, 60) + '...'
: pcode.origin_request)
: 'Request Details';
const shortPcode = pcode.pcode ? `P-${pcode.pcode.substring(0, 8)}...` : '';
pane.className = "active";
pane.innerHTML = `
${requestSnippet}
${shortPcode} • ${statusUI.label}
Domain: ${pcode.domain || "—"}
Impact: ${pcode.impact || "—"}
Assigned: ${pcode.assigned_doctor || "—"}
Progress: ${pcode.percent_complete || 0}%
Full Request:
${pcode.origin_request || "—"}
`;
pane.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
/* Legacy show detail - delegates to new system */function showPcodeDetail(pcode) {
const normalizedPcode = {
pcode: pcode.pcode || pcode.id,
status: pcode.status || 'active',
domain: pcode.domain_class || pcode.domain || 'System',
impact: pcode.impact_class || pcode.impact || 'Standard',
origin_request: pcode.origin_request || '',
assigned_doctor: pcode.requested_by || pcode.assigned_doctor || 'Unassigned',
percent_complete: pcode.percent_complete || 0
};
if (normalizedPcode.status === 'awaiting' ||
pcode.impact_class === 'Strategic' ||
pcode.impact_class === 'Critical') {
normalizedPcode.status = 'awaiting';
showGovernanceModalFromData(normalizedPcode);
} else {
showSimpleDetail(normalizedPcode);
}
}
function closeDetail() {
const pane = document.getElementById("pcode-detail-pane");
if (pane) pane.className = "";
}
// ============================================
// CLINICAL CONSOLE - ROLE SWITCHING
// ============================================
const roleNames = {
floor_nurse: 'Floor Nurse',
physician: 'Physician',
charge_nurse: 'Charge Nurse',
case_manager: 'Case Manager',
supervisor: 'Supervisor'
};
function switchRole(role) {
console.log('🔄 Switching to role:', roleNames[role] || role);
// Hide all role views (main content)
document.querySelectorAll('.role-view').forEach(view => {
view.classList.remove('active');
view.style.display = 'none';
});
// Show selected role view
const selectedView = document.getElementById(`view-${role}`);
if (selectedView) {
selectedView.style.display = 'block';
selectedView.classList.add('active');
}
// Hide all sidebar role views
document.querySelectorAll('.sidebar-role-view').forEach(view => {
view.classList.remove('active');
view.style.display = 'none';
});
// Show selected sidebar role view
const selectedSidebar = document.getElementById(`sidebar-${role}`);
if (selectedSidebar) {
selectedSidebar.style.display = 'block';
selectedSidebar.classList.add('active');
}
// Update role chip in Ask Council
const roleChip = document.getElementById('pill-role');
if (roleChip) {
roleChip.textContent = roleNames[role] || role;
}
// Count tasks in the active view
const activeView = document.querySelector('.role-view.active');
const urgentTasks = activeView ? activeView.querySelectorAll('.task-card.red, .task-card.yellow').length : 0;
// Update Active count in sidebar
const activeCountEl = document.querySelector('.sidebar-stat-value.red');
if (activeCountEl) {
activeCountEl.textContent = urgentTasks;
}
// Show toast
showToast(`Switched to ${roleNames[role]} view`, 'success');
}
// Shift Clock Countdown
function updateShiftClock() {
const clock = document.getElementById('shiftClock');
if (!clock) return;
let [h, m, s] = clock.textContent.split(':').map(Number);
if (s > 0) s--;
else if (m > 0) { m--; s = 59; }
else if (h > 0) { h--; m = 59; s = 59; }
clock.textContent = `${h}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`;
}
setInterval(updateShiftClock, 1000);
// Toast notification
function showToast(message, type = 'info') {
// Remove existing toasts
document.querySelectorAll('.rni-toast').forEach(t => t.remove());
const toast = document.createElement('div');
toast.className = `rni-toast ${type}`;
// Elegant center notification for role switches
if (message.includes('Switched to')) {
const roleName = message.replace('Switched to ', '').replace(' view', '');
toast.innerHTML = `
Now viewing as
${roleName}
`;
toast.style.cssText = `
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0.9);
padding: 32px 48px;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border-radius: 16px;
box-shadow: 0 24px 80px rgba(0, 0, 0, 0.12), 0 0 1px rgba(0, 0, 0, 0.1);
z-index: 10000;
text-align: center;
opacity: 0;
transition: opacity 0.6s cubic-bezier(0.16, 1, 0.3, 1), transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
`;
// Add inner styles
const style = document.createElement('style');
style.textContent = `
.role-toast-label {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 2px;
color: #9CA3AF;
margin-bottom: 8px;
font-weight: 500;
}
.role-toast-name {
font-size: 24px;
font-weight: 600;
color: #111827;
margin-bottom: 16px;
}
.role-toast-bar {
width: 0%;
height: 3px;
background: linear-gradient(90deg, #4D7CFF, #7C9FFF);
border-radius: 2px;
margin: 0 auto;
animation: roleBarFill 2s cubic-bezier(0.16, 1, 0.3, 1) forwards;
animation-delay: 0.3s;
}
@keyframes roleBarFill {
0% { width: 0%; opacity: 0; }
10% { opacity: 1; }
100% { width: 100%; opacity: 1; }
}
`;
document.head.appendChild(style);
document.body.appendChild(toast);
// Animate in
requestAnimationFrame(() => {
toast.style.opacity = '1';
toast.style.transform = 'translate(-50%, -50%) scale(1)';
});
// Animate out
setTimeout(() => {
toast.style.opacity = '0';
toast.style.transform = 'translate(-50%, -50%) scale(0.95)';
setTimeout(() => {
toast.remove();
style.remove();
}, 600);
}, 2200);
} else {
// Standard toast for other messages
toast.innerHTML = `
${message}`;
toast.style.cssText = `
position: fixed;
bottom: 24px;
right: 24px;
padding: 14px 20px;
background: ${type === 'success' ? '#4D7CFF' : '#3B82F6'};
color: white;
border-radius: 8px;
font-size: 14px;
font-weight: 500;
z-index: 10000;
display: flex;
align-items: center;
gap: 10px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
animation: slideIn 0.3s ease-out;
`;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.animation = 'slideIn 0.3s ease-out reverse';
setTimeout(() => toast.remove(), 300);
}, 3000);
}
}
// Quick Ask presets
function quickAsk(type) {
const input = document.getElementById('request-input');
const box = document.getElementById('askCouncilBox');
const presets = {
'attention': 'Which patients need immediate attention right now?',
'hrv': 'What is the current HRV status across all monitored patients?',
'discharge': 'Which patients are ready for discharge or step-down?',
'handoffs': 'What are the pending handoffs for this shift?'
};
// Expand the Ask Council box if collapsed
if (box && box.classList.contains('collapsed')) {
box.classList.remove('collapsed');
}
if (input && presets[type]) {
input.value = presets[type];
input.focus();
}
}
// Dark Mode Toggle
// Toggle Ask Council Box
function toggleAskCouncil() {
const box = document.getElementById('askCouncilBox');
const icon = document.getElementById('askToggleIcon');
box.classList.toggle('collapsed');
}
function toggleDarkMode() {
document.body.classList.toggle('dark-mode');
const icon = document.getElementById('darkModeIcon');
if (document.body.classList.contains('dark-mode')) {
icon.classList.remove('fa-moon');
icon.classList.add('fa-sun');
showToast('Dark mode enabled', 'success');
} else {
icon.classList.remove('fa-sun');
icon.classList.add('fa-moon');
showToast('Light mode enabled', 'success');
}
}
// S.O.A.P. Auto-Draft Viewer
function viewSOAPDraft(patientId) {
const drafts = {
'james-wilson': {
patient: 'James Wilson',
date: new Date().toLocaleDateString(),
subjective: 'Patient reports improved mood, sleeping 7 hours/night, appetite returned. Denies SI/HI. States "feeling more like myself." Engaged in group therapy.',
objective: 'Alert, oriented x4. Affect euthymic, congruent. Speech normal rate/rhythm. No psychomotor changes. VS: HR 72, BP 118/76, SpO2 99%.',
assessment: 'Generalized Anxiety Disorder, improving. PHQ-9: 8 (↓4 from admission). GAD-7: 6 (↓5). Sleep improved. Medication adherence 100%.',
plan: '1. Continue current medication regimen\n2. Continue group therapy daily\n3. Family session scheduled Thursday\n4. Target discharge Day 7 pending stability'
}
};
const draft = drafts[patientId];
if (!draft) {
showToast('Draft not found', 'error');
return;
}
// Create modal with S.O.A.P. content
const modal = document.createElement('div');
modal.className = 'soap-modal';
modal.innerHTML = `
S Subjective
${draft.subjective}
O Objective
${draft.objective}
A Assessment
${draft.assessment}
`; document.body.appendChild(modal); } console.log('🏥 RNI Clinical Console Rev 24 - Role-Specific Views'); console.log('═══════════════════════════════════════════════════'); console.log('+ 17/17 Clinical Grievances Addressed'); console.log('+ EHR Sync Badge (Epic: Connected)'); console.log('+ S.O.A.P. Auto-Draft Viewer'); console.log('+ Shift Handoff Summary Card'); console.log('+ Med Reconciliation Task'); console.log('+ Dark Mode Toggle'); console.log('+ 5 Role Views with Task Filtering'); console.log('═══════════════════════════════════════════════════');