Postings & Matching

The postings workflow is the core of NIVAA's blind matchmaking system. Parents post their tutoring needs, tutors apply, coordinators score and push the best-fit educators, and parents accept or decline -- all without seeing tutor identities until acceptance.

Postings List

The postings queue at /admin/postings shows all postings grouped by status. This is where coordinators spend most of their matching time.

GET /admin/postings
// Returns postings with queue summary counts
{ "postings": [...],
  "counts": { "open": 7, "filled": 34, "closed": 12, "pending_applications": 15 } }
Open Parent has posted; accepting tutor applications. Coordinator action: Monitor for incoming applications; reach out to tutors if none after 72h.
Pending Applications Tutors have applied; coordinator needs to review. Coordinator action: Score applications, select best-fit, push to parent.
Filled Parent accepted a tutor; match is active. No action needed; sessions auto-scheduled.
Closed Posting closed without a match or manually closed. Coordinator action: Review reason; follow up with parent if needed.

Posting Detail

GET /admin/postings/:id
{ "posting_id": 23, "parent_id": 5, "child_id": 12,
  "subject": "Mathematics", "level": "O-Level",
  "schedule_preference": "Weekday evenings",
  "location": "Tampines", "special_requirements": "...",
  "status": "open", "created_at": "2026-03-20T08:00:00Z",
  "applications": [
    { "application_id": 101, "tutor_id": 9, "tutor_name": "Alex Tan (9)",
      "score": { "total": 78, "subject": 22, "language": 15,
               "gender": 10, "timing": 13, "special_needs": 18 },
      "status": "Pending", "applied_at": "2026-03-21T10:30:00Z" }
  ] }

Match Scoring

Every application is scored across 5 dimensions. The total score (0-100) helps coordinators rank candidates, but the final decision is always human.

Match Scoring
/
How well the tutor's subject expertise matches the posting requirements. Exact subject + level match scores highest.
/
Overlap between tutor's teaching languages and parent's preferred language(s).
/
Match against parent's gender preference for the tutor, if specified. No preference = full score.
/
Overlap between tutor's availability slots and the posting's schedule preference.
/
Whether the tutor has relevant special needs experience matching the posting's requirements. No SN need = full score.
Total/100
Score display

Match scores are shown on the admin posting detail view alongside each application. The admin detail view shows both the total score and the per-dimension breakdown so coordinators can see exactly where a candidate is strong or weak.

Application Workflow

Each application moves through a defined lifecycle. Coordinators control the transition from Pending to Pushed; everything after that is between the parent and the system.

Drag to pan · Scroll to zoom
When another tutor acceptedpendingpushedshortlistedAcceptedrejectedSilent Rejection
StatusMeaningWho triggers
PendingTutor has applied; awaiting coordinator reviewTutor (by applying)
PushedCoordinator has selected this application and sent it to the parent for reviewCoordinator
ShortlistedParent has shown interest but not yet committedparent
AcceptedParent has accepted this tutor. Match is active. Sessions auto-scheduled.parent
RejectedApplication explicitly rejected by parent or coordinatorParent or Coordinator
Rejected (silent)Auto-set to Rejected when parent accepts a different tutor -- no notification sentSystem (automatic)

Push to Parent

When a coordinator identifies the best candidate(s), they push the application(s) to the parent. Multiple applications can be pushed simultaneously.

POST /admin/postings/:id/push
// Request body
{ "application_ids": [101, 104] }

// Response
{ "pushed_count": 2 }
  • Pushing moves the application status from Pending to Pushed
  • The parent receives a notification that new tutor options are available
  • Tutor identity remains hidden -- the parent sees an anonymized profile (subject expertise, experience level, area, languages)
  • Coordinators can push multiple applications to give parents a choice

Close Posting

POST /admin/postings/:id/close
// Closes the posting manually -- no further applications accepted
// No request body required

// Response
{ "ok": true }

Silent Rejection

Important behavior

When a parent accepts one educator for a posting, all other pending applications for that same posting are automatically and silently rejected. No notification is sent to the rejected tutors. This prevents awkward situations where tutors learn they were competing against specific individuals.

Blind Matching Rules

  • Before acceptance: Parents see anonymized tutor profiles -- subject expertise, years of experience, languages, area, and a generic introduction. No name, photo, or contact info.
  • After acceptance: Tutor identity is revealed to the parent. Full name and contact details become visible.
  • Admin view: Coordinators always see full tutor identity at every stage.
  • Tutor view: Tutors see the posting requirements but never see the parent or child identity until their application is accepted.

Discounts

Coordinators can create ad-hoc discounts tied to a specific child or match. These are typically applied when a match is accepted (e.g., first-session promotional discount).

POST /admin/discounts
// Create a child/match-specific discount
{ "child_id": 5, "match_id": 12,
  "discount_type": "percent", "percent_off": 25,
  "sessions_remaining": 2, "reason": "First session promo" }

Fields: child_id, match_id, discount_type, percent_off, flat_amount_off, sessions_remaining, reason.

Ad-hoc Sessions

Tutors can batch-log extra sessions outside the regular schedule -- for example, exam preparation sessions. These are flagged with billed_as_addon=1 and tracked separately.

  • Ad-hoc sessions follow the same approval flow (check-in -> check-out -> parent approval)
  • They appear in analytics under the ad-hoc analytics metric
  • Billing treats them as add-ons to the existing package
  • Coordinators can see ad-hoc sessions flagged in the session list with a distinct badge