Repository navigation
[Epic · V1] Revenue Calendar × Trophy Wall #467
Description
[Epic · V1→V1.5] Revenue Calendar × Trophy Wall Closed Loop (Tutor/Centre Lock-In)
RESOLVED 2026-10-25: #444 / #469 merged — live ToS §15 = tutor-pays (
owed by the Tutor; Customers and centres do not pay MatchMax a matching fee). Build/copy against tutor-pays; admin-fee automation gate on #444 is cleared for payer identity (other #475 phase gates still apply).
Payer lock: Issues lock tutor pays 1.5-lesson admin (#464). Live ToS §15 now matches (see RESOLVED above). Build against tutor-pays. #475 Phase1 Collect Tuition (parent→tutor) remains available after
#459/#461A; automated admin collection still waits on #475 phase gates (not on #444 identity).
URGENT parent epic — CEO 2026-10-25.
Turns bookkeeping into a habit and public proof into lock-in: logging a lesson calculates income and builds reputation in one closed loop.
Does not replace human matching waves (#438·#449·#451·#454·#466). Ships after / with foundation#459(hours ledger must exist before public trophy hours mean anything).
Prototype & mockups (SoT for UI)
| Asset | URL / path |
|---|---|
| Interactive Gemini simulator | https://share.gemini.google/OWAm773iPg6S |
| Revenue simulator mockup | Attached on this issue / comment (4 KPI cards + stacked bars A–E + sliders) |
| Trophy roster mockup | Attached on this issue / comment (Active cards · Verified vs New Match · Fee lines) |
Brand tokens (from live DESIGN.md): Azure #1D9BF0, Sky #8ECDF8, Wash #E3ECF6, Ink #0F1419, success green #157F47, destructive #D61F2E. Do not invent a second palette.
Closed-loop thesis (must stay true in both children)
- Off-platform after Lesson 2 → Trophy hours freeze at last verified total; Active card drops after 45 days inactivity → looks like the student quit early.
- Stay on MatchMax calendar from Lesson 3 onward → 0% commission forever on that case + Active count, avg retention hours, and search ranking keep climbing.
- Parents/students confirm lessons → credit their own Verified Learning Hours on personal Academic CV (
#459dual-sided ledger) + unlock milestones later (#460). - BYO / external students → tutor can track private $ immediately; hours + Trophy Wall credit only after parent/student links a MatchMax account (viral invite loop). Phase B of
#461.
Phase table
| Phase | When | Scope | Issue |
|---|---|---|---|
| Foundation | Urgent V1 now | Unified account + progressive roles + child sub-profiles + VerifiedHoursLedger |
#459 |
| A — Revenue private dashboard | V1 (build after/with #459) | 4 financial buckets + session complete → ledger write + fee math + multi-student stacked bars + unpaid bucket | #461 Phase A |
| A — Trophy KPI banner | V1-soon (not blocking desk densification) | Public/profile KPI strip only: Active · Past · Avg retention (≥8) · Rating — no PII rows required | Documented in #459 counters + #462 Phase A |
| B — Full calendar ERP | Later | Drag-drop calendar, recurrence, .ics/Google, prepaid burn-down, group seats, BYO invite, term picker, WA hooks | #461 Phase B (parked inside same issue) |
| B — Full Trophy Wall | Later | Active/Past tabs, cards, 3-tier privacy, anti-poach, interim ratings, alumni outcome tags | #462 Phase B (On Hold for full roster until lessons flow) |
| Retention / Rewards | On Hold (after #459+#461A) | Full gamification epic: Phase 0 badges on #459/#462 · Phase A fee rebate + streaks · Phase B+ vault/plaques/sponsors | #468 |
Children (do not duplicate bodies here)
-
#461 — Scheduling + Revenue & Earnings Engine (4 Buckets) — Phase A urgent · Phase B parked in-body
-
#462 — Trophy Wall Roster — Phase A KPI · Phase B full wall On Hold
-
#468 — Gamified Retention Engine (FULL epic, On Hold) — Phase 0 badges fold to [Urgent · V1] Unified account + roles + child sub-profiles + hours ledger #459/[V1 Phased · under #467] Trophy Wall Roster — KPI Banner → Full 3-Tier Privacy Wall #462; Phase A = next-match fee rebate + weekly streak after sessions; Phase B+ vault/plaques/lifestyle/ESG
Website integration map (live routes on keyframesfound/matchmaxhk)
| Surface | Route / file | What this epic adds |
|---|---|---|
| Tutor workspace home | /dashboard · #lessons / #my-tutor · src/routes/_authenticated.dashboard.tsx · src/features/cases/tutor/tutor-home.tsx · week-view.tsx · calendar-windows-editor.tsx |
Phase A primary host: Schedule & Earnings header (4 buckets) + stacked bar + session actions |
| Tutor public profile | /tutors/$tutorCode · src/routes/tutors.$tutorCode.tsx · public-tutor-card.tsx |
Trophy KPI banner (Phase A) → full roster section (Phase B) |
| Business / centre portal | /business/ · /business/courses · /business/team · /business/settings · src/components/business/business-layout.tsx |
Same earnings header for org-scoped calendars (Cap.57: centres = Organization) |
| Public centre page | /business/$slug |
Optional org Trophy KPI (Phase B) |
| Parent cases | /account/cases · /account/cases/$caseId |
Confirm/dispute session → dual-sided ledger credit |
| Tutor requests | /tutor-requests/ · /tutor-requests/$caseCode |
Link matched case → TuitionCase for fee sequence |
| Fee helpers (reuse) | src/features/cases/fee-breakdown.ts · help admin-fee-structure.md |
Do not re-implement 1.5×; call existing helpers / extend them |
CEO fee locks (never “correct” away)
- Tutor (or self-employed tutor under a centre) pays MatchMax 1.5-lesson admin on platform-matched cases: L1 = 100% of gross lesson · L2 = 50% · L3+ = 0%.
- Parents / centres do not pay the matching admin fee.
- Short case ≤5 lessons: 20% of package (
#443/ track#464). - Pro-bono / $0 rate: 0% admin.
TUTOR_SELF_IMPORTED/ BYO linked later: 0% admin forever.- Cap.57: Independent Tutor path only for personal tutor billing; centres = Organization + self-employed tutors; vacancy SaaS stays
#413. - Do not invent parent-pays.
Dependencies
| Dep | Why |
|---|---|
#459 |
Ledger is single source of truth for hours; progressive roles; child sub-profiles |
#464 / #443 / #444 |
Fee track + short-case + ToS |
#465 |
B2B / Cap.57 org overflow |
#428 |
Matching outcome ledger — ≠ hours ledger; do not merge |
#460 |
Profile chrome / Students tab hosts Trophy UI later |
Desk #438 #449 #451 #454 #466 |
Untouched ownership — parallel track |
Success for this epic
- Tutor opens
/dashboard(Schedule & Earnings) and sees live 4 buckets + per-student bars matching Gemini mockup math. - Completing a session moves Pipeline → Realized, writes
#459ledger rows both sides, updates unpaid if needed. - Public
/tutors/$tutorCodeshows Trophy KPI numbers derived from ledger (Phase A); full privacy roster later (Phase B#462). - Off-platform behaviour visibly hurts Trophy Active/hours — on-platform L3+ is the rational default.
Out of scope
- Replacing human-assisted matching / Tutor Code desk flow.
- Parent-pays fee model.
- Full Instagram profile grid (
#460). - Escrow / Shop (
#429/#251).
Filed children
Gamification cut (CEO 2026-10-25 — ADOPT ALL ideas; phase only)
| Slice | When | Where |
|---|---|---|
| 25h/100h digital badges | V1-now with ledger/Trophy KPI | #459 + #462 Phase A |
| 100h → 0.25-lesson next-match fee rebate + weekly lesson streak + MaxPoints-from-verified-lesson | V1-soon after #459+#461A | #468 Phase A |
| Daily check-in, freezes, Day-7 chest | After A | #468 Phase A.5 |
| Full Rewards Vault, physical plaques, Shari Shari/Starbucks/HKTVmall, parent supermarket, ESG packs | Volume + sponsors/fee-slice | #468 Phase B+ |
Reject HKTA self-serving coupons. Dual-gate anti-farming from day 1 on #468. #468 is not Urgent.
Quality deepen & product add-ons (CEO 2026-10-25)
Quality scorecard (before → after this pass)
| Issue | Before | After | Main gaps closed |
|---|---|---|---|
| #459 | ~3/5 | ~5/5 | Journeys, placement, APIs, wireframes, reconcile UI, QA fixtures |
| #461 | ~4/5 | ~5/5 | Named actions, idempotency, dual-confirm clocks, void/undo, notif matrix, short-case×rebate, mobile, i18n, sor.ts→fee-breakdown |
| #462 | ~3.5/5 | ~5/5 | Actions/jobs, empty states, i18n/mobile, short-case/BYO, analytics light |
| #466 | ~2/5 | ~5/5 | Full rewrite: flows, stages, wireframes, filters, ACs, copy locks |
| #467 | ~3.5/5 | ~4.5/5 | Orchestration matrix, notif overview, add-on decisions (this section) |
| #468 | ~4.5/5 | ~5/5 | Thin spots only: short-case×rebate, rate limits, analytics, notif on redeem — Phase B+ kept |
Cross-epic notification matrix (owner per event)
| Event | Owner issue | Tutor | Parent | Staff |
|---|---|---|---|---|
| Case submitted / stage change | #466 | — | Status card + WA expectation | Desk |
| Lesson logged complete | #461 | — | Confirm CTA | — |
| Lesson verified / 24h auto | #461+#459 | Hours+earnings refresh | Learning hours | — |
| Dispute / void | #461 | Yes | Yes | Flag |
| Unpaid tuition (to tutor) | #461 | Reminder | Soft | — |
| MatchMax admin fee invoice | existing desk/bus.ts |
Yes (tutor-pays) | Not as matching debtor | Desk |
| Trophy Active/badge unlock | #462 | In-app | — | — |
| Streak / rebate unlock / redeem | #468 (when unparked) | In-app | — | Audit |
Extend src/features/cases/bus.ts — do not fork.
Product add-ons — decisions (adopt into children; do not inflate #468 to Urgent)
| Idea | Decision | Where |
|---|---|---|
| Lesson reminder / WA sync after log | Adopt coordinate | #461 notif + #466 copy (no calendar promise) |
| Dual confirm + 24h auto | Adopt clarify | #461 §11.2 · #459 ledger statuses |
| Dispute / undo before lock | Adopt | #461 undo 2h / void soft |
| Admin staff reconcile view | Adopt expand | #459 §8.5 + ACs |
| Short-case 20% × N × rebate | Adopt table | #461 §11.4 · #468 thin spot |
| BYO privacy clarity | Adopt | #461 §11.5 |
| Parent learning-hours CV teaser | Park | #460; one-liner OK on case page |
| Notification matrix | Adopt | #461/#462/#466/#467/#468 |
| Idempotent log-completed-lesson | Adopt | #461 AC |
| Soft void vs hard delete | Adopt | #461 voidSession |
Mobile vs desktop /dashboard CTAs |
Adopt | #461 §11.6 |
| i18n EN/繁中 | Adopt | All V1 issues ACs |
| Analytics events light | Adopt park-detail | Named events; dashboards later |
| Rate limits badge/rebate | Badges = recompute; rebate claim rate-limit on #468 | #468 |
| HKTA-style coupons / parent-pays | Reject | Breaks model |
| Making #468 Urgent | Reject | Stays On Hold until #459+#461A |
Build order (unchanged)
- [Urgent · V1] Unified account + roles + child sub-profiles + hours ledger #459 foundation
- [Urgent · V1] Case/Tutor Form Progressive Disclosure + Parent Match-Status Card + Admin Filters #466 parallel ops
- [V1 · #467] Scheduling + revenue/earnings engine (4 buckets) #461 Phase A thin log + 4 buckets
- [V1 Phased · under #467] Trophy Wall Roster — KPI Banner → Full 3-Tier Privacy Wall #462 Phase A KPI + badges
- [Parked · Full Epic] Gamified Retention Engine — Streaks · MaxPoints · Trophy Ladder · Rewards Vault · Fee Rebate #468 Phase A (unpark) rebate + weekly streak
- Phase B+ everywhere parked
Urgent set (locked — unchanged)
#438 · #449 · #451 · #454 · #459 · #461 · #466 · #467
#468 remains On Hold / not Urgent.
Live code pointers (epic-level)
| Concern | Live path |
|---|---|
| Fee multiplier | src/features/cases/sor.ts → extract/extend fee-breakdown.ts |
| Tutor home / confirms | src/features/cases/tutor/tutor-home.tsx · tutor.functions.ts |
| Week view | src/features/cases/tutor/week-view.tsx |
| Public tutor | src/features/tutors/public-tutor-card.tsx |
| Case form | src/features/cases/CaseRequestForm.tsx · plan .opencode/plans/tutor-request-3-page-form.md |
| Admin cases | src/routes/_authenticated.admin.cases.tsx |
| Notifications bus | src/features/cases/bus.ts |
| Prototype | https://share.gemini.google/OWAm773iPg6S |
Dev readiness — zero-guesswork pass (CEO 2026-10-25)
Children upgraded from “good product specs” → implementation tickets. This epic body stays the thesis + map; detail lives on children.
| Child | Added in quality pass |
|---|---|
| #459 | Exact SQL schema vs complete_onboarding/switch_role; numbered idempotent migration; full 7-day claim token spec; primary ledger bridge creditVerifiedHoursFromCaseLesson from case_lessons.status=done; RLS matrix; i18n keys; impl checklist |
| #461 | Log-lesson modal lock + fields + no-rate block; concurrent verify race; sequence races; pipeline pseudocode + HKD rounding; unpaid copy + tutor-only Mark paid; empty zero-case; fee-breakdown.ts rebate signature; RLS; i18n; checklist |
| #462 | Active/Past algorithm w/ sparse history; 45-day lock (live was 30 — change sor.ts); Phase A public query no PII; hide KPI at 0; checklist |
| #468 | Rebate one-time-use steps; ISO week Mon–Sun HKT + Sunday/multi-lesson rules; empty streak; Phase A checklist only — still On Hold |
| #466 | (Prior deepen) status card must not promise calendar early — unchanged this pass |
Live-code discoveries that locked decisions
fee-breakdown.tsalready exists — extend for 0.25 L2 rebate; don’t fork.markLessonDoneTutor/lessonAdminMarkare the first ledger writers via shared credit fn (before full calendar).ACTIVE_STUDENT_WINDOW_DAYS=30insor.tsvs product 45 — children now require aligning to 45.- Dual schedule confirm already on
case_lessons; complete-verify is a separate idempotent transition.
Build order (unchanged)
459 → 466∥ → 461A → 462A → 468A → rest parked.
Urgent set (locked — unchanged)
#438 · #449 · #451 · #454 · #459 · #461 · #466 · #467
#468 remains On Hold / not Urgent.
Consolidated sub-issues (eng map)
| # | Title | Notes |
|---|---|---|
| #461 | Scheduling + Revenue & Earnings Engine | V1 phased |
| #462 | Trophy Wall Roster | On Hold / V1.5 — nested for track clarity only |
Consolidated for eng — sub-issues listed.
Activity
owlstonbusiness-svg commentedon Oct 25, 2026
Children rewritten for developer zero-guesswork (phased A/B, schemas, fee examples, routes, AC):
enhancement+urgent(Phase A build-now; Phase B parked in-body). RemovedOn Hold.enhancement+On Hold(Phase A KPI V1-soon in body; Phase B full roster held until ledger has volume).Prototype: https://share.gemini.google/OWAm773iPg6S
Mockups: see following comments (revenue simulator + trophy roster PNGs).
owlstonbusiness-svg commentedon Oct 25, 2026
CEO mockups
PNG upload via API returned multipart/auth quirks — visual SoT remains the interactive prototype:
https://share.gemini.google/OWAm773iPg6S
Revenue simulator (describe for implementers): 4 KPI cards — REALIZED NET HK$8,725 · SCHEDULED PIPELINE HK$15,975 · FORECAST NET TOTAL HK$24,700 (Admin Fee HK$2,100) · TROPHY WALL HOURS 562 hrs / 5 Active; stacked bars Students A–E with green Realized / blue Pipeline / pink Admin Fee; QA sliders (rate 450, completed 3, scheduled 4, new-match toggle).
Trophy roster: Active cards — Verified (100% Net) vs New Match (Fee: -HK$…); school · curriculum · hrs · done/plan; private mirror shows fee chips; public wall uses privacy tiers (#462).
CEO also has local PNG paths used during filing:
revenue-simulator.png/trophy-roster.png(attached in CEO share session).owlstonbusiness-svg commentedon Oct 25, 2026
Grok re-check ADOPT map (2026-10-25) — live repo keyframesfound/matchmaxhk
Build order locked on this epic.
owlstonbusiness-svg commentedon Oct 25, 2026
Child added: Gamified Retention Engine (#468) — parked, not V1
New child: #468
[Parked] Gamified Retention Engine MVP: Streaks + Hour Badges + Next-Match Fee RebateLabels:
enhancement+On Hold— not urgent / not V1 densification.Why under this epic: Retention rewards close the same loop as Revenue × Trophy — users stay on-platform to keep hours/streaks flowing. Building the full vault before the ledger + session writer would leave empty rewards.
MVP (after #459 + #461 Phase A):
Full vault parked (Phase B+ on #468): physical plaques, Shari Shari/Starbucks/HKTVmall sponsorships, parent supermarket cash, institutional ESG plaques, Day-7 chest, streak freezes, etc.
Fee lock unchanged: tutor-pays 1.5 (#464); Cap.57-safe independent-tutor language on rebate.
owlstonbusiness-svg commentedon Oct 25, 2026
Grok gap close-out (CEO adopt · 2026-10-25)
Structure kept. Small gaps written into child bodies (no new sprawling issues; #468 stays On Hold):
fee-breakdown.tsBuild order (unchanged): 459 → 466∥ → 461A → 462A → 468A → rest parked.
Urgent set unchanged. Tutor-pays 1.5 base unchanged. #468 Phase B+ content not simplified.
owlstonbusiness-svg commentedon Oct 25, 2026
Quality scorecard + deepen pass (CEO 2026-10-25)
Assessed against zero-guesswork bar (placement, flows, state machines, data model, named APIs, wireframes, empty/edge, fee/Cap.57 locks, ACs, parked specs, deps, QA fixtures). Live paths verified in
keyframesfound/matchmaxhk(sor.tsfee helper,tutor-home.tsx,case_lessonsdual-confirm,CaseRequestForm.tsx,public-tutor-card.tsx,bus.ts, 3-page plan).Before → after
logCompletedLesson…), idempotency, dual-confirm vs 12h SoR clock, undo/void, notif matrix, short-case×rebate, BYO privacy, mobile/desktop, i18n,sor.ts→fee-breakdown.tsAdd-ons adopted vs rejected
Adopted into bodies (phased): lesson reminder/#466 sync · dual confirm + 24h auto · dispute/undo · admin reconcile expand · short-case×N×rebate table · BYO privacy clarity · notif matrix · idempotent log · soft void · mobile/desktop CTAs · EN/繁中 · light analytics · rebate claim rate-limit.
Parked: parent learning-hours CV teaser → #460 · search ranking (already on #462) · vault/plaques/lifestyle (already #468 B+).
Rejected: HKTA coupons · parent-pays · making #468 Urgent.
Locks confirmed
Bodies edited (not skinny comments): #459 #461 #462 #466 #467 #468.
owlstonbusiness-svg commentedon Oct 25, 2026
Zero-guesswork quality pass (CEO 2026-10-25) — ADOPT Grok gaps
Turned children from good product specs → implementation tickets via body edits (appendices). Thesis/map on this epic unchanged.
complete_onboarding/switch_rolecreditVerifiedHoursFromCaseLessononcase_lessons.status=done(markLessonDoneTutor+lessonAdminMark); secondary backfill — #459 §15.4/dashboardcase card; fields + no-rate block — #461 §12.1sor.tswas 30)fee-breakdown.tsextend)Live-code locks:
fee-breakdown.tsalready exists (extend for 0.25 L2); bridge ledger from existing done path; align Active window 30→45.Rejected: #468 Urgent · parent-pays · HKTA coupons · full calendar in Phase A.
Build order unchanged: 459 → 466∥ → 461A → 462A → 468A → rest parked.
Urgent set unchanged; #468 stays On Hold.
owlstonbusiness-svg commentedon Oct 25, 2026
V1 urgent inventory lock — 2026-10-25
Eng / product V1 (ship now)
Legal V1 (parallel — not eng density)
Explicitly NOT urgent (V1-soon / On Hold)
#428 · #441 · #443 · #445 · #448 · #462 (Phase A V1-soon; Phase B On Hold) · #255 V2 · #450 · #460 · #468 · #472 · #473 · #474 · #475 · tracks #463–#465
owlstonbusiness-svg commentedon Oct 25, 2026
Payer-conflict loop closed (2026-10-25 Asia/Hong_Kong)
#444 closed · #469 merged — live ToS §15 = tutor-pays (
owed by the Tutor; Customers and centres do not pay MatchMax a matching fee).Body top updated: RESOLVED note + payer lock refreshed. Build/copy against tutor-pays. Admin-fee automation identity gate on #444 cleared; other #475 phase gates / On Hold status unchanged. Urgent labels untouched.
owlstonbusiness-svg commentedon Oct 25, 2026
V1 must-have re-audit — 2026-10-25 (functions → issues)
Must ship (urgent)
Done (not open)
Must-not inflate (stay off urgent)
Urgent eng set size: 11 open (#438 #449 #451 #454 #459 #461 #466 #467 + #443 #441 #259).
owlstonbusiness-svg commentedon Oct 28, 2026
CEO nav pointer (2026-10-28)
Top-bar Calendar tab (icon + placement next to Cases) + tutor/parent ops hub entry is locked on child #461 — do not duplicate the full amendment here.
Quick locks:
Tutors → Guide → Saved → Cases → **Calendar**owlstonbusiness-svg commentedon Oct 28, 2026
Consolidated for eng — sub-issues listed: #461 #462 (#462 remains On Hold). Parent epic map: see #518.
owlstonbusiness-svg commentedon Oct 28, 2026
On Hold child — do not build in V1
Nested for navigation only: #462 is On Hold. Ship active children first; ignore On Hold kids in V1 sprints.
[-][Epic · V1→V1.5] Revenue Calendar × Trophy Wall Closed Loop (Tutor/Centre Lock-In)[/-][+][Epic · V1] Revenue Calendar × Trophy Wall[/+]owlstonbusiness-svg commentedon Oct 29, 2026
Child epic: Classcard → Hybrid Academy Ops #530