Operations & Workflow Automation
DOPA Mentor Management Portal
Real-time mentor operations with live notifications, payments, and automated reporting.
Overview
Problem
Mentor assignments, session tracking, and payouts were coordinated manually across chats and spreadsheets, with no live visibility into session status or payment state for program coordinators.
Solution
A real-time operations portal where mentor activity, payments, and reporting update live — coordinators see session and payment status the moment it changes, without refreshing or asking around.
Architecture
Client
Next.js UI subscribed to a live event stream for instant status updates.
Realtime
Server-Sent Events (SSE) endpoint pushing state changes to connected clients.
Workflow
Step-based automation engine advancing mentor sessions through defined states.
Payments
Payment engine reconciling mentor payouts against completed sessions.
Data
MongoDB storing sessions, payment records, and reporting aggregates.
- SSE was chosen over WebSockets for the notification layer — the traffic is one-directional (server → client), so SSE gives real-time updates with a much simpler connection model.
- Workflow steps are modeled explicitly as a state machine, so a mentor session's status is always one of a known, finite set of states — never ambiguous.
- Reporting is computed from the same event stream that drives live notifications, so dashboards and payouts never disagree with what coordinators are seeing in real time.
Feature Breakdown
- Live notifications on session and payment status via SSE — no polling
- Automated workflow steps moving mentor sessions from scheduled to completed to paid
- Integrated payment engine reconciling payouts against completed sessions
- Reporting dashboard for program-level oversight
Implementation Detail
export async function GET() {
const stream = new ReadableStream({
start(controller) {
const unsubscribe = sessionEvents.subscribe((event) => {
controller.enqueue(`data: ${JSON.stringify(event)}\n\n`);
});
return () => unsubscribe();
},
});
return new Response(stream, {
headers: { "Content-Type": "text/event-stream" },
});
}Challenges & Solutions
Coordinators needed to see status changes the instant they happened, without expensive polling or a full WebSocket infrastructure.
Implemented an SSE endpoint that streams state changes as they're written, giving near-instant updates with a fraction of the complexity of a WebSocket server.
Manual payout tracking was error-prone — sessions could be marked complete without payment being reconciled, or vice versa.
Modeled the mentor lifecycle as an explicit state machine, so a payout can only be triggered once a session has reached a verified 'completed' state.
Results
- Session and payout status is visible the moment it changes, replacing a routine of coordinators pinging mentors in chat to ask 'where are we at?'
- A payout can no longer be triggered for a session that wasn't actually verified complete — a gap that existed in the old chat-and-spreadsheet process.
- One SSE connection per client replaced what would have been a WebSocket server, connection registry, and keepalive protocol to build and operate.
Lessons Learned
- Picking SSE over WebSockets by asking "does the client ever send on this channel?" — rather than reaching for WebSockets because the feature was labeled real-time — kept the operational surface much smaller.
- A state machine only pays off if illegal transitions are actually rejected, not just undocumented; enforcing that at the data layer, not the UI, was what prevented the payout-before-completion bug class.
Gallery
Screenshots to be added.