Skip to main content

Purpose

This document describes what happens in the backend when consultation sessions move to terminal states (done or missed), including payments, wallet availability, review gating, and testing behavior from faker.

Missed-session recovery and repeat purchases

A missed session can be rescheduled when eligible; it is not permanently closed to recovery. The owning consultant may prompt the student, who selects a replacement time and pays any fee. Rescheduling retains the session identity and resets attendance; rebooking instead creates a new purchase and session set. See the rescheduling and rebooking lifecycle and QA checklist.

Core Entities

  • consultation_sessions (ConsultationSessions): runtime session state (scheduled, ongoing, done, missed, etc.)
  • ledger (Ledger): provider credits per consultation session, initially PENDING
  • wallet (Wallet): derived balances from ledger + withdrawals
  • withdrawal (Withdrawal): payout pipeline constrained by wallet.availableBalance

Lifecycle Sequence

Runtime Side Effects Tied to Completion

  1. Session finalization:
  • server/src/consultation/sessions.scheduler.ts
  • Expired + both joined => done
  • Expired + not both joined => missed
  1. Emitted events:
  • consultation.session.updated on both done and missed
  • consultation.completed on done
  • consultation.session.missed on missed
  1. Payment release:
  • done sessions schedule delayed fund release with PAYMENT_HOLD_DAYS
  • missed sessions do not auto-release
  1. Wallet availability:
  • Only RELEASED ledger credits contribute to availableBalance
  • Withdrawals are validated against availableBalance
  1. Review/completion gating:
  • Consultation completion logic requires terminal sessions and at least one done
  • This impacts ability to submit reviews through enrollment completion checks
  1. Metrics:
  • Student/analytics “finished consultation” counts use done sessions
  • Calendar excludes terminal statuses by default (done, missed, cancelled, pending_payment)

Faker Testing Behavior

When calling:
  • POST /faker/session/:sessionId/time
with payload:
behavior is:
  • Session time is shifted.
  • If shifted end time is already expired (<= now - 15 minutes) and triggerCompletionCheck is true, faker immediately runs the same scheduler completion pass (handleSessionCompletion), so downstream effects start without waiting for cron.
  • Default is false, so completion is not auto-triggered unless explicitly requested.

Notes for Deterministic Tests

  1. Use hoursFromNow negative enough so endTime <= now - 15m.
  2. Ensure bothPartiesJoined=true before forcing completion if you expect done and release scheduling.
  3. Use admin POST /sessions/:id/release-funds for missed-session dispute resolution path.