Real-Time Meeting Cost Tracking
Overview
The Real-Time Meeting Cost Tracking module is designed to dynamically calculate and display the ongoing cost of a meeting by considering the number of attendees, their average hourly wage, and the elapsed duration of the meeting. This module enables users to start, pause, update parameters during, and stop meetings, ensuring continuous and accurate cost updates throughout the meeting lifecycle.
This capability addresses a common challenge in organizational settings: quantifying the monetary impact of time spent in meetings, thereby promoting cost awareness and better resource management.
Core Concepts and Purpose
At its core, this module models a meeting as a series of time increments, each capturing a snapshot of attendee count, wage rate, and duration. When any relevant parameter changes or the meeting is stopped, the current increment is finalized, and a new increment begins if applicable. This incremental approach allows the system to handle dynamic parameter changes mid-meeting without losing precision.
The module:
Tracks elapsed time accurately using system timestamps.
Calculates incremental and total meeting costs based on attendee count and wage.
Supports real-time updates to attendee count, wage, and meeting purpose.
Manages meeting lifecycle events: start, pause/stop, reset.
Interfaces with persistent storage to save completed meeting records.
Key challenges it solves include:
Accurately accumulating cost over time with variable inputs.
Providing immediate feedback to users on cost burn rate and totals.
Maintaining modular, clear abstractions for meeting state and increments.
Meeting Lifecycle Management
This subtopic governs the creation, updating, and termination of meetings.
Lifecycle States and Transitions
Start: Initializes the meeting, clearing prior increments and capturing the start time.
Pause/Stop: Finalizes the current increment by recording elapsed time and cost, then saves the meeting data persistently.
Reset: Clears all meeting data and returns to default parameters.
Parameter Updates: Changing attendee count or wage mid-meeting triggers the closure of the current increment and starts a new one with updated values.
Key Mechanisms
The Meeting class encapsulates the meeting state, managing:
Whether the meeting clock is running (
clockRunning).The list of completed
incrementsrepresenting time slices.Current increment parameters:
currentIncrementAttendeeCount,currentIncrementAverageWage, andcurrentIncrementStartTime.Meeting purpose description.
Example lifecycle method snippets:
// Start meeting: resets increments and marks clock running
startMeeting () {
this.increments = [];
this.clockRunning = true;
this.currentIncrementStartTime = new Date;
}
// Stop meeting: stops clock, pushes final increment, saves data
stopMeeting () {
this.clockRunning = false;
this.pushIncrement();
this.warehouse.save(this.increments);
}
// Change attendee count mid-meeting: close current increment, start new
changeAttendeeCount (newAttendeeCount) {
this.pushIncrement();
this.currentIncrementAttendeeCount = newAttendeeCount;
}
The lifecycle management ensures that the meeting state remains consistent and that cost calculations reflect the true meeting flow, including changes in participants or rates.
Incremental Cost Calculation
Cost calculation is handled through discrete Increment objects representing time intervals with fixed attendee counts and wage rates.
Increment Structure and Calculation
Each Increment captures:
Start and stop timestamps.
Elapsed time in seconds.
Attendee count during the interval.
Average wage during the interval.
The cost accrued during the interval.
The cumulative total cost up to this increment.
Meeting purpose (carried through increments).
The cost for an increment is computed as:
cost = attendeeCount × (averageWage / secondsPerHour) × elapsedTime
This formula prorates the hourly wage to a per-second rate and multiplies by the number of attendees and the elapsed seconds.
Increment Aggregation
The meeting aggregates increments to determine:
Total cost: Sum of all increments plus ongoing cost if the meeting is running.
Total elapsed time: Sum of elapsed time of all increments plus any running increment.
Burn rate: Real-time cost per second and per minute based on current attendee count and wage.
Example calculation snippet from the Meeting class:
getTotalCost() {
const lastIncrement = this.increments.slice().reverse()[0];
const totalCost = lastIncrement ? lastIncrement.totalCost : 0.00;
if (this.clockRunning) {
return totalCost + new Increment(
this.currentIncrementStartTime,
new Date,
this.currentIncrementAttendeeCount,
this.currentIncrementAverageWage
).cost;
}
return totalCost;
}
This approach supports continuous, accurate cost tracking as the meeting progresses and parameters change.
Dynamic Cost Visualization
The module integrates with the view layer to present live cost data to the user.
Real-Time UI Updates
A timer (e.g., setInterval) triggers cost recalculations and UI refreshes at a frequent interval (100ms in the main app). The view renders:
The current total meeting cost formatted as currency.
The current cost burn rate per minute and per second.
The elapsed meeting time formatted into human-readable units (seconds, minutes, hours, days, months, years).
Time Formatting
Elapsed time is formatted by progressively dividing seconds into larger units, appended to an output string, e.g.:
5m 12s
1h 3m 20s
The rendering function uses window.requestAnimationFrame to optimize DOM updates and avoid jank.
Example snippet from the meeting view renderer:
let html = `
<h2 class="count">$${meeting.getTotalCost().toFixed(2)}</h2>
<small>$${meeting.burnPerMinute().toFixed(4)} / minute</small><br>
<small>$${meeting.burnPerSecond().toFixed(4)} / second</small><br>
<small>${format_time(meeting.getTotalTime())}</small>
`;
This presentation enables users to instantly perceive the financial impact of the meeting as it unfolds.
Interaction with Other System Components
Integration with Persistent Storage
When a meeting stops, its increments are saved using the Warehouse model, which abstracts localStorage operations. This persists meeting data for later review in the [Persistent Meeting History](None) module.
UI Event Handling
The index.js file orchestrates user interactions, binding UI controls to Meeting methods for starting, stopping, resetting, and updating meeting parameters. It triggers view updates through the MeetingTemplate renderer, enabling seamless synchronization between model state and user interface.
Process Flow of Real-Time Meeting Cost Tracking
flowchart TD
Start[User starts meeting]
Init[Initialize Meeting Instance]
Timer[Start periodic timer]
UpdateInputs[User updates attendees/wage]
PushIncrement[Push current increment]
CalculateCost[Calculate current cost]
UpdateUI[Update cost display]
StopMeeting[User stops meeting]
SaveData[Save meeting increments]
Reset[User resets meeting]
Start --> Init --> Timer
Timer --> CalculateCost --> UpdateUI
UpdateInputs --> PushIncrement --> Init
StopMeeting --> PushIncrement --> SaveData
SaveData --> UpdateUI
Reset --> Init
This flowchart shows the core lifecycle and how cost calculation and UI updates interleave with user actions.
Summary of Key Files
lib/models/meeting.js: Contains the
Meetingclass managing meeting lifecycle, increments, and cost calculations.lib/models/increment.js: Defines the
Incrementclass modeling discrete timed cost segments.lib/views/meeting.js: Responsible for rendering the dynamic cost and time display in the UI.
index.js: Coordinates UI events, interacts with theMeetinginstance, and triggers view updates.
These components collaborate to provide a robust, user-friendly real-time meeting cost tracking experience within the larger application. The module's incremental cost calculation strategy combined with lifecycle management ensures precise, flexible cost tracking even as meeting parameters evolve.