/** * Real-Time Event Definitions for LocalGreenChain * * Defines all real-time event types and utilities for formatting events. */ import type { TransparencyEventType, TransparencyEvent, LiveFeedItem } from './types'; /** * Event categories for grouping and filtering */ export enum EventCategory { PLANT = 'plant', TRANSPORT = 'transport', DEMAND = 'demand', FARM = 'farm', AGENT = 'agent', BLOCKCHAIN = 'blockchain', SYSTEM = 'system', AUDIT = 'audit', } /** * Real-time event types enum for client use */ export enum RealtimeEvent { // Plant events PLANT_REGISTERED = 'plant.registered', PLANT_CLONED = 'plant.cloned', PLANT_TRANSFERRED = 'plant.transferred', PLANT_UPDATED = 'plant.updated', // Transport events TRANSPORT_STARTED = 'transport.started', TRANSPORT_COMPLETED = 'transport.completed', TRANSPORT_VERIFIED = 'transport.verified', // Demand events DEMAND_CREATED = 'demand.created', DEMAND_MATCHED = 'demand.matched', SUPPLY_COMMITTED = 'supply.committed', // Farm events FARM_REGISTERED = 'farm.registered', FARM_UPDATED = 'farm.updated', BATCH_STARTED = 'batch.started', BATCH_HARVESTED = 'batch.harvested', // Agent events AGENT_ALERT = 'agent.alert', AGENT_TASK_COMPLETED = 'agent.task_completed', AGENT_ERROR = 'agent.error', // Blockchain events BLOCKCHAIN_BLOCK_ADDED = 'blockchain.block_added', BLOCKCHAIN_VERIFIED = 'blockchain.verified', BLOCKCHAIN_ERROR = 'blockchain.error', // System events SYSTEM_HEALTH = 'system.health', SYSTEM_ALERT = 'system.alert', SYSTEM_METRIC = 'system.metric', // Audit events AUDIT_LOGGED = 'audit.logged', AUDIT_ANOMALY = 'audit.anomaly', } /** * Map event types to their categories */ export const EVENT_CATEGORIES: Record = { 'plant.registered': EventCategory.PLANT, 'plant.cloned': EventCategory.PLANT, 'plant.transferred': EventCategory.PLANT, 'plant.updated': EventCategory.PLANT, 'transport.started': EventCategory.TRANSPORT, 'transport.completed': EventCategory.TRANSPORT, 'transport.verified': EventCategory.TRANSPORT, 'demand.created': EventCategory.DEMAND, 'demand.matched': EventCategory.DEMAND, 'supply.committed': EventCategory.DEMAND, 'farm.registered': EventCategory.FARM, 'farm.updated': EventCategory.FARM, 'batch.started': EventCategory.FARM, 'batch.harvested': EventCategory.FARM, 'agent.alert': EventCategory.AGENT, 'agent.task_completed': EventCategory.AGENT, 'agent.error': EventCategory.AGENT, 'blockchain.block_added': EventCategory.BLOCKCHAIN, 'blockchain.verified': EventCategory.BLOCKCHAIN, 'blockchain.error': EventCategory.BLOCKCHAIN, 'system.health': EventCategory.SYSTEM, 'system.alert': EventCategory.SYSTEM, 'system.metric': EventCategory.SYSTEM, 'audit.logged': EventCategory.AUDIT, 'audit.anomaly': EventCategory.AUDIT, }; /** * Event display configuration */ interface EventDisplay { title: string; icon: string; color: string; } /** * Map event types to display properties */ export const EVENT_DISPLAY: Record = { 'plant.registered': { title: 'Plant Registered', icon: '🌱', color: 'green' }, 'plant.cloned': { title: 'Plant Cloned', icon: '🧬', color: 'green' }, 'plant.transferred': { title: 'Plant Transferred', icon: '🔄', color: 'blue' }, 'plant.updated': { title: 'Plant Updated', icon: '📝', color: 'gray' }, 'transport.started': { title: 'Transport Started', icon: '🚚', color: 'yellow' }, 'transport.completed': { title: 'Transport Completed', icon: '✅', color: 'green' }, 'transport.verified': { title: 'Transport Verified', icon: '🔍', color: 'blue' }, 'demand.created': { title: 'Demand Created', icon: '📊', color: 'purple' }, 'demand.matched': { title: 'Demand Matched', icon: '🎯', color: 'green' }, 'supply.committed': { title: 'Supply Committed', icon: '📦', color: 'blue' }, 'farm.registered': { title: 'Farm Registered', icon: '🏭', color: 'green' }, 'farm.updated': { title: 'Farm Updated', icon: '🔧', color: 'gray' }, 'batch.started': { title: 'Batch Started', icon: '🌿', color: 'green' }, 'batch.harvested': { title: 'Batch Harvested', icon: '🥬', color: 'green' }, 'agent.alert': { title: 'Agent Alert', icon: '⚠️', color: 'yellow' }, 'agent.task_completed': { title: 'Task Completed', icon: '✔️', color: 'green' }, 'agent.error': { title: 'Agent Error', icon: '❌', color: 'red' }, 'blockchain.block_added': { title: 'Block Added', icon: '🔗', color: 'blue' }, 'blockchain.verified': { title: 'Blockchain Verified', icon: '✓', color: 'green' }, 'blockchain.error': { title: 'Blockchain Error', icon: '⛓️‍💥', color: 'red' }, 'system.health': { title: 'Health Check', icon: '💓', color: 'green' }, 'system.alert': { title: 'System Alert', icon: '🔔', color: 'yellow' }, 'system.metric': { title: 'Metric Update', icon: '📈', color: 'blue' }, 'audit.logged': { title: 'Audit Logged', icon: '📋', color: 'gray' }, 'audit.anomaly': { title: 'Anomaly Detected', icon: '🚨', color: 'red' }, }; /** * Get the category for an event type */ export function getEventCategory(type: TransparencyEventType): EventCategory { return EVENT_CATEGORIES[type]; } /** * Get display properties for an event type */ export function getEventDisplay(type: TransparencyEventType): EventDisplay { return EVENT_DISPLAY[type] || { title: type, icon: '📌', color: 'gray' }; } /** * Format a description for an event */ export function formatEventDescription(event: TransparencyEvent): string { const { type, data, source } = event; switch (type) { case 'plant.registered': return `${data.name || 'A plant'} was registered by ${source}`; case 'plant.cloned': return `${data.name || 'A plant'} was cloned from ${data.parentName || 'parent'}`; case 'plant.transferred': return `${data.name || 'A plant'} was transferred to ${data.newOwner || 'new owner'}`; case 'plant.updated': return `${data.name || 'A plant'} information was updated`; case 'transport.started': return `Transport started from ${data.from || 'origin'} to ${data.to || 'destination'}`; case 'transport.completed': return `Transport completed: ${data.distance || '?'} km traveled`; case 'transport.verified': return `Transport verified on blockchain`; case 'demand.created': return `Demand signal created for ${data.product || 'product'}`; case 'demand.matched': return `Demand matched with ${data.supplier || 'a supplier'}`; case 'supply.committed': return `Supply committed: ${data.quantity || '?'} units`; case 'farm.registered': return `Vertical farm "${data.name || 'Farm'}" registered`; case 'farm.updated': return `Farm settings updated`; case 'batch.started': return `Growing batch started: ${data.cropType || 'crops'}`; case 'batch.harvested': return `Batch harvested: ${data.yield || '?'} kg`; case 'agent.alert': return data.message || 'Agent alert triggered'; case 'agent.task_completed': return `Task completed: ${data.taskName || 'task'}`; case 'agent.error': return `Agent error: ${data.error || 'unknown error'}`; case 'blockchain.block_added': return `New block added to chain`; case 'blockchain.verified': return `Blockchain integrity verified`; case 'blockchain.error': return `Blockchain error: ${data.error || 'unknown error'}`; case 'system.health': return `System health: ${data.status || 'OK'}`; case 'system.alert': return data.message || 'System alert'; case 'system.metric': return `Metric: ${data.metricName || 'metric'} = ${data.value || '?'}`; case 'audit.logged': return `Audit: ${data.action || 'action'} by ${data.actor || 'unknown'}`; case 'audit.anomaly': return `Anomaly: ${data.description || 'unusual activity detected'}`; default: return `Event from ${source}`; } } /** * Convert a TransparencyEvent to a LiveFeedItem */ export function toFeedItem(event: TransparencyEvent): LiveFeedItem { const display = getEventDisplay(event.type); return { id: event.id, event, timestamp: new Date(event.timestamp).getTime(), formatted: { title: display.title, description: formatEventDescription(event), icon: display.icon, color: display.color, }, }; } /** * Get events by category */ export function getEventsByCategory(category: EventCategory): TransparencyEventType[] { return Object.entries(EVENT_CATEGORIES) .filter(([, cat]) => cat === category) .map(([type]) => type as TransparencyEventType); } /** * Check if an event type belongs to a category */ export function isEventInCategory(type: TransparencyEventType, category: EventCategory): boolean { return EVENT_CATEGORIES[type] === category; } /** * Priority to numeric value for sorting */ export function priorityToNumber(priority: string): number { switch (priority) { case 'CRITICAL': return 4; case 'HIGH': return 3; case 'NORMAL': return 2; case 'LOW': return 1; default: return 0; } } /** * Sort events by priority and time */ export function sortEvents(events: TransparencyEvent[]): TransparencyEvent[] { return [...events].sort((a, b) => { const priorityDiff = priorityToNumber(b.priority) - priorityToNumber(a.priority); if (priorityDiff !== 0) return priorityDiff; return new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime(); }); }