Roadmap & Todos
Structured backlog from stakeholder meetings (Mar 19-27, 2026) plus ongoing agent work through Apr 2, 2026. Each item includes implementation status verified against the codebase, with an agent verdict explaining what was found.
Summary
| Status | Count |
|---|---|
| DONE | 99 |
| PARTIAL | 9 |
| TODO | 38 |
| CANCELLED | 6 |
| SUPERSEDED | 2 |
| Total | 154 |
0. Other Changes Made
Work completed outside the original meeting notes. These items emerged from agent development sessions between Mar 27 – Apr 2, 2026.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| DONE | Telegram bot built (@NIVAAMainBot) — 21 commands, check-in/out, session changes, reminders | Telegram docs | Agent work Mar 27-29 | Full bot at workers_nivaa/src/telegram/bot.ts. Tutor commands: /sessions, /upcoming, /checkin, /checkout, /todos, /mystudents, /postings, /notes, /mypay. Coordinator: /dashboard, /alerts, /pending, /postingsqueue, /newapps, /lowpackages, /student, /tutor, /impersonate. See Telegram docs. |
| DONE | Admin impersonation via Telegram | Telegram docs | Agent work Mar 27 | Coordinators can /impersonate any tutor to view their session data. Stored in telegram_links.impersonating_tutor_id (migration 0022). See Telegram docs. |
| DONE | Monthly billing cron removed | Billing | Agent work Mar 27 | Removed 10 0 1 * * from wrangler.toml. Billing is now manual via POST /billing/run-monthly. See Billing. |
| DONE | Nicole Telegram linked (chat_id 6916064747) | Telegram docs | Agent work Mar 27 | Linked to user 19 ([email protected]) as Admin. All 3 coordinators now linked: Nicole, Sid, Bel. See Telegram docs. |
| DONE | Documentation site built (25 pages, JSON engine) | /docs | Agent work Mar 28-29 | JSON-driven docs at /docs. DocRenderer.svelte, 17 block types, 6 diagram types. DocLang spec at /docs/doclang. |
| DONE | Gantt chart removed from WIP page | /docs/roadmap | Agent work Mar 29 | Replaced with simple checklist + link to /docs/roadmap. |
| DONE | InvoiceView component | /admin/billing/invoices | Agent work Mar 30 | Professional invoice layout at /admin/billing/invoices. Pure CSS, INV-0687 design. Preview button per record. |
| DONE | Clickable route links in coordinator docs | text | Agent work Mar 30 | All 10 coordinator doc pages updated with text links to admin frontend routes. See Coordinator docs. |
| DONE | Multi-step educator onboarding wizard | /apply/onboard | Agent work Mar 30 | 5-step guided flow: account creation, subjects, location, profile, review. Public page. Subject picker matches parent posting form. |
| DONE | Parent invoice preview (InvoiceView) | /parent/billing | Agent work Mar 30 | Same InvoiceView component as admin. Preview button per invoice on parent billing page. |
| DONE | Parent impersonation picker (family tree) | /parent | Agent work Mar 30 | Admin visiting /parent sees family tree dropdown with children metadata. View as Parent/Tutor links in admin sidebar. |
| DONE | Tutor View My Public Profile link | /tutor/profile | Agent work Mar 30 | Button on tutor profile page links to /educator/{id} in new tab. |
| DONE | Daily reminder pending notes bug fix | Telegram docs | Agent work Mar 28 | Fixed inverted ternary in reminders.ts — pending notes count was always 0. See Telegram docs. |
| DONE | /lowpackages table fix | Telegram docs | Agent work Mar 28 | Fixed query: was using nonexistent packages table. Now uses package_ledgers with correct columns. See Telegram docs. |
| DONE | Docs link in workspace sidebar | /docs | Agent work Mar 28 | All workspace sidebars (admin, tutor, parent) show "Docs" link at bottom via WorkspaceShell component. See /docs. |
| DONE | SSR auth — HttpOnly cookies + server hooks | hooks.server.ts | Agent work Mar 30 | Backend sets HttpOnly cookies on login/register/refresh. Frontend hooks.server.ts validates on every request. Follows Ontologer pattern. Backward compatible with existing client-side auth. |
| DONE | Educator public profile (SSR-gated) | /educator/ID | Agent work Mar 30 | Access-controlled profile at /educator/ID. SSR via +page.server.ts. Not indexable. NIVAA-branded layout with stats, experience, testimonials. |
| DONE | Invoice preview component | /admin/billing/invoices | Agent work Mar 30 | InvoiceView.svelte matching INV-0687 design. Inline preview at /admin/billing/invoices. |
| DONE | Clickable route links in all coordinator docs | text | Agent work Mar 30 | All 10 coordinator doc pages + roadmap updated with text links to admin pages. |
| DONE | Demo account login with named role picker | /login | Agent work Mar 30 | Login page has Demo Accounts section with 3 named buttons (Parent: Rachel Ng, Educator: Alex Tan, Coordinator: Bundle Coordinator). Uses POST /auth/demo-login. Sets HttpOnly cookies. |
| DONE | Parent insights scoped to own children only | /parent/insights | Agent work Mar 30 | Backend already filtered by parent_user_id. Fix was in the login flow — admin impersonation was showing all data. Demo parent login now uses actual Parent role, sees only own children. |
| DONE | Admin sidebar restructure (Students→Sessions→Educators→Postings→Billing→Analytics) | /admin | Bundle 10 Mar 30 | Flat nav. Removed People, Family Tree, standalone Insights. Postings top-level. Tickets under Billing. |
| DONE | Breadcrumbs replaced with uppercase text path | /admin | Bundle 10 Mar 30 | ADMIN \ STUDENTS \ NAME format. No clickable links. Platform logic pill removed. |
| DONE | Educator Public Profile tab on tutor detail | /admin/tutors | Bundle 10 Mar 30 | EducatorProfile embedded as tab in admin tutor detail view. |
| DONE | Platform logic migrated to docs (6 pages) | /docs/logic-sessions | Bundle 10 Mar 30 | Sessions, billing, postings, students, educators, insights logic pages now in JSON docs engine. |
| DONE | Student detail direct child_id lookup fix | /admin/students | Bundle 10 Mar 30 | Was scanning full list causing not-found for some children. Now uses ?child_id=N. |
| DONE | Tutor detail cleanup (removed Flow column, fixed match display) | /admin/tutors | Bundle 10 Mar 30 | Match shows student name prominently. Match ID as small muted label. |
| DONE | Posting detail status icons + profile links | /admin/postings | Bundle 10 Mar 30 | Colored icons per application status. Student/Parent/Educator linked to profiles. |
| DONE | Parent educator display pizzazz (first name, intro, pills) | /parent/postings | Bundle 10 Mar 30 | First name only, initials avatar, intro snippet, experience+special needs pills. Removed introductory call. |
| DONE | Add Parent/Educator buttons on respective admin pages | /admin/students | Bundle 10 Mar 30 | Moved from deleted People page. Modal with form + Telegram link generation. |
| DONE | Sessions calendar view toggle on admin | /admin/appointments | Bundle 10 Mar 30 | Month grid with status-colored dots. Click day to see sessions. |
| DONE | Custom error pages — 404, 403, 401, 500 | /404 | Agent work Apr 2 | Root-level +error.svelte. Grey background, white card, large status code, icon (FileQuestion/ShieldAlert/LockKeyhole/AlertCircle), friendly message, Go Back + Home buttons. No more SvelteKit default error screen. |
| DONE | Tutor visiting /parent now redirects to /tutor | /parent | Agent work Apr 2 | Parent layout onMount checks session role. Non-parent, non-admin users are redirected to their workspace before any API calls are made. Eliminates the 'you do not have permission' flash on wrong workspace. |
| DONE | Sign out button fixed — clears session and redirects | /login | Agent work Apr 2 | signOutFirebaseSession() was incorrectly setting useDevAuth: true after logout. Fixed to clear all session fields. TopNav now calls goto('/login') after sign out. |
| DONE | Tutor profile personal fields made read-only | /tutor/profile | Agent work Apr 2 | Name, Gender, DOB, Contact Number, Address, Race are now static display labels (not form inputs). 'Contact your coordinator to update personal details' note added. Employment Type remains editable. |
| DONE | Coordinator approval gate on tutor postings | /tutor/postings | Agent work Apr 2 | Backend: tutor postings access is now driven by the shared tutor-onboarding projection and only opens for approved tutors. Frontend shows normalized onboarding states instead of branching on legacy raw values. |
| DONE | Pending coordinator review page for unapproved tutors | /tutor | Agent work Apr 2 | All /tutor/* routes now consume the normalized tutor-onboarding projection. Non-approved tutors see invite/intake/review/rejected states instead of a single generic pending shell. Admins impersonating still bypass the gate. |
| DONE | Font changed to Poppins sitewide | / | Agent work Apr 2 | Replaced Montserrat with Poppins (@fontsource/poppins) across all weights (300/400/500/600/700). Updated body font-family in app.css. |
| DONE | Brand color palette updated — #552c7d purple + #f09092 peach | / | Agent work Apr 2 | CSS variables updated: --primary: #552c7d, --primary-hover: #3d1f5e, --primary-soft: #f3eef8, --accent: #f09092, --accent-hover: #e07a7c, --accent-soft: #fff5f5. Hardcoded hex values updated across component files. Purple is primary (80% usage), peach is accent (20%). |
| DONE | Operator tooling split — deploy, verify, release-check, commit helper | deploy.sh / nivaa-*.sh | Agent work Apr 2 | Root deploy.sh now remains as a compatibility wrapper while the operator split lives in ilx-nivaa-deploy.sh, ilx-nivaa-verify.sh, ilx-nivaa-release-check.sh, ilx-nivaa-commit.sh, and ilx-nivaa-git-auth.sh. Deploy paths stay lean: frontend builds then deploys, worker runs tests then deploys, commit/push logic stays outside the deploy scripts, and GitHub PAT auth is stored repo-locally in .git/config. |
| PARTIAL | Trial session invoice — backend built, no frontend UI | /admin/billing | Agent work Apr 2 | Backend complete: trial_invoices table, POST /matches/:id/trial/propose creates appointments + invoices, POST /matches/:id/trial/invoice/:invoiceId/confirm-payment marks paid, auto-converts match when all paid. No admin or parent frontend screen exists yet for viewing/confirming trial invoices. |
1. Respond.io & WhatsApp Integration
Integration with Respond.io for contact management, WhatsApp messaging, and lead lifecycle tracking. Contact cache and message cache are implemented in D1 with a proxy layer for admin-only API access.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| DONE | Respond.io contact cache (D1 + auto-refresh if >24h stale) | Respond.io contacts | Mar 24 Nicole | Implemented in respondio.ts. Full paginated sync with respondio_contacts_cache table, 24h TTL, force-refresh endpoint. See Respond.io contacts. |
| DONE | Respond.io message cache per contact | Respond.io contacts | Mar 24 Nicole | Implemented in respondio.ts. Messages fetched from v2/contact/id:{id}/message/list, cached in respondio_messages_cache, with WhatsApp template body extraction. See Respond.io contacts. |
| DONE | Admin proxy to respond.io API (/admin/respondio/*) | Respond.io API explorer | Mar 24 Nicole | Implemented in index.ts. Server-side auth forwarding with RESPOND_IO_KEY, admin-only. See Respond.io API explorer. |
| DONE | WhatsApp message view (parsed, not raw JSON) | Respond.io contacts | Mar 24 Nicole | Frontend page at /admin/marketing-and-comms/respondio/contacts/id]/+page.svelte renders parsed messages. Messages are extracted from respond.io format with sender labels (NIVAA/Workflow/Bot/Contact) and text extraction from templates. See [Respond.io contacts. |
| DONE | Tutor comms through Telegram bot | Telegram docs | Mar 24 Nicole | Full Telegram bot built in bot.ts with /sessions, /upcoming, /checkin, /checkout, /mystudents, /postings, /notes, /mypay commands plus session change/cancel/reschedule flows. See Telegram docs. |
| CANCELLED | Keep vs move intake process to Respond.io | — | Mar 24 Nicole | Cancelled. Intake stays in-app. No outbound Respond.io messaging from within the platform. |
| CANCELLED | WhatsApp template messages (utility + marketing) | — | Mar 24 Nicole | Cancelled. No outbound messaging from within the app. Respond.io is read-only (contact cache + message history). |
| CANCELLED | Enable live messaging for Sid (+65 91153059) | — | Mar 24 Nicole | Cancelled. Outbound messaging will be done directly in Respond.io, not through the NIVAA platform. |
| CANCELLED | Template selector for WhatsApp conversations | — | Mar 24 Nicole | Cancelled. Templates managed directly in Respond.io workspace. |
| CANCELLED | Snippets (quick reply) from Respond.io | — | Mar 24 Nicole | Cancelled. Quick replies stay in Respond.io native interface. |
| CANCELLED | Sales number vs marketing number coordination | — | Mar 24 Nicole | Cancelled. Multi-number setup is a Respond.io workspace concern, not in-app. |
2. Heatmap / Distribution
Location intelligence for understanding where leads, students, and tutors are distributed across Singapore. Uses postal codes, areas, and address data.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| DONE | 3-layer location distribution (area, postal prefix, full postal) | Distribution map | Mar 24 Nicole | Implemented as GET /admin/respondio-cache/distribution in respondio.ts. Returns DistributionPoint] with type (lead/educator/student), subtype (active/inactive/converted), area, postal_code, postal_prefix. Includes area-to-prefix mapping for ~50 Singapore areas. See [Distribution map. |
| DONE | Collect address on parent signup | People | Mar 24 Nicole | Parent signup in people.ts accepts address_data field. Child addresses stored in child_profiles.address_data. Profile endpoints support get/update for both parent and child addresses. See People. |
| DONE | Area from Respond.io custom fields | Distribution map | Mar 24 Nicole | Distribution endpoint extracts area, address, and subject from respond.io custom_fields_json. FB Lead form fields are captured as custom fields. See Distribution map. |
| PARTIAL | Address from AI bot vs Nicole manual update | People | Mar 24 Nicole | Address data can be updated via admin ETL (etl.ts bulk postal code update) or parent self-service (profile.ts). No AI bot address extraction yet. Would appear at People. |
| DONE | Heatmap visualization (interactive map) | Distribution map | Mar 24 Nicole | Implemented. Two Leaflet map pages: Distribution map (D3 SVG overlay, toggleable lead/educator/student layers, area + prefix tables) and Geography analytics (postal sector heatmap with histogram). Both use sg-geo.ts for coordinate resolution. |
3. Lead Lifecycle & Analytics
Tracking leads through their journey from initial Facebook ad click to paying customer. Lifecycle data comes from Respond.io custom fields.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| DONE | Lifecycle field on contact cache | Respond.io contacts | Mar 24 Nicole | The respondio_contacts_cache table has a lifecycle column. Values observed: Customer, Pending Payment, Pending Client, and others from respond.io. See Respond.io contacts. |
| DONE | Lifecycle stages stored and queryable | Respond.io contacts | Mar 24 Nicole | Distribution endpoint uses CONVERTED_LIFECYCLES set (Customer, Pending Payment, Pending Client) to classify leads. Full lifecycle value available per contact. See Respond.io contacts. |
| PARTIAL | Show lifecycle on contact list front page | Respond.io contacts | Mar 24 Nicole | Contact list at Respond.io contacts fetches cached contacts with lifecycle field. Rendering depends on frontend implementation. |
| DONE | FB Lead Form fields (Ad Name, FB Form ID, Area) captured | Respond.io contacts | Mar 24 Nicole | Respond.io custom_fields_json captures all fields from FB Lead Forms. Distribution endpoint reads area, address, subject, listing_number from custom fields. See Respond.io contacts. |
| DONE | List by lead type on left sidebar of contact list | Respond.io contacts | Mar 24 Nicole | Implemented. Lifecycle sidebar on contact list page with color-coded stage buttons, counts per stage, and click-to-filter. Stages derived dynamically from cached contacts. See Respond.io contacts. |
| DONE | Tags distribution analysis | Respond.io contacts | Mar 24 Nicole | Implemented. GET /admin/respondio-cache/analytics returns tags_distribution with count per tag, sorted by frequency. See Respond.io contacts. |
| DONE | Lifecycle change history by date | Respond.io contacts | Mar 24 Nicole | Implemented. respondio_lifecycle_history table (migration 0024) tracks old/new lifecycle per contact on each sync. Analytics endpoint returns last 100 changes with names and timestamps. See Respond.io contacts. |
| DONE | Conversion analytics by Facebook campaign | Respond.io contacts | Mar 24 Nicole | Implemented. GET /admin/respondio-cache/analytics returns fb_campaigns with per-campaign totals and lifecycle stage breakdown (ad_name + fb_lead_form_name extracted from custom_fields). See Respond.io contacts. |
4. Tutor Onboarding & Profile
Tutor registration, profile completion, and identity verification. Profile data feeds into the matching algorithm.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| PARTIAL | Subject > Curriculum > Age/Level multi-select picker | /tutor/profile | Mar 24 Nicole / Mar 23 Bel | Subject picker exists in subject-picker.ts with subject/curriculum config. Tutor hard_constraints stores subjects array. Full multi-stage picker (subject then curriculum then level) not yet a guided wizard. Would appear at /tutor/profile. |
| DONE | Race field (Chinese/Malay/Indian/Other) | Tutors | Mar 24 Nicole | Implemented. tutor_profiles has race column. Captured during intake (intake.ts line 33, 82) and people registration (people.ts line 46, 71). See Tutors. |
| DONE | Postal code and area on tutor profile | Tutors | Mar 24 Nicole | Tutor profiles store postal_code, area, and address. ETL endpoint (etl.ts) supports bulk postal code updates. See Tutors. |
| DONE | Languages on tutor profile | Tutors | Mar 24 Nicole | Tutor profiles store languages as JSON array. Used in match scoring (language dimension, 0-20 points). See Tutors. |
| TODO | Certificate upload (not mandatory to proceed) | /tutor/profile | Mar 23 Bel | Not implemented. File upload exists for session notes (R2 nivaa-pdfs) but no certificate upload flow. Would appear at /tutor/profile. |
| TODO | Regions served: MRT stations as proxy | /tutor/profile | Mar 24 Nicole | Not implemented. Current location uses area/postal code, not MRT-based regions. Would appear at /tutor/profile. |
| TODO | Autofill tutor profile address | /tutor/profile | Mar 24 Nicole | Not implemented. No address autocomplete/geocoding integration. Would appear at /tutor/profile. |
| TODO | Multiple location selector for tutors | /tutor/profile | Mar 24 Nicole | Not implemented. Tutor profile stores single area/postal_code, not multiple regions. Would appear at /tutor/profile. |
| DONE | Lock name/gender/race/DOB after signup | /tutor/profile | Mar 24 Nicole | Implemented. NRIC name, DOB, gender, and race are all locked after first save. Backend uses COALESCE(null, existing) pattern to prevent overwrites. Frontend shows disabled inputs with 'Locked after first save' note. See /tutor/profile. |
| DONE | Notify coordinator on profile changes | Telegram docs | Mar 24 Nicole | Implemented. Profile changes are logged to profile_change_log table and now trigger Telegram notifications to all coordinators showing tutor name, field changed, old > new values. See Telegram docs. |
| TODO | MOH certification verification (DISE etc.) | Tutors | Mar 24 Nicole | Not implemented. Singpass scaffold exists (migration 0012) for identity verification but no MOH/DISE integration. Would appear at Tutors. |
5. Session Management (Telegram + Web)
Core session lifecycle: scheduling, check-in/out, change/cancel/reschedule, reminders, and approval. Heavily integrated with the Telegram bot for tutor-facing operations.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| DONE | Session change/cancel on web sessions + Telegram | Session Lifecycle | Apr 20 Codex / Mar 24 Nicole / Mar 23 Bel | Parents and tutors now get direct per-session Reschedule and Cancel controls on their web session surfaces. Tutor Telegram change flows remain available, and backend policy is now shared: reasons required, responder-side counter-proposals, one open proposal version at a time, 4-hour freeze for new self-service changes, check-in blocked while unresolved, and unresolved requests expire to Not_Completed at the original session start. |
| DONE | Shared self-service bounds for cancel/reschedule | Session Lifecycle | Mar 24 Nicole | Implemented worker-side and surfaced in parent/tutor session UIs. Reschedule and cancel now share the same new-change lockouts for both roles: Scheduled only, future only, outside the 4-hour freeze, required reasons, and overlap checks against both tutor and child calendars. Reschedule also keeps the original duration fixed, allows counter-proposals, and expires unresolved threads at the original start time. |
| DONE | Call parent button in Telegram | Telegram docs | Mar 24 Nicole | Implemented. tel: URL button shown when parent hasn't acknowledged. Falls back to 'No phone on file -- contact coordinator' if no phone number. See Telegram docs. |
| DONE | Clock in/out with time windows | Telegram docs | Mar 24 Nicole / Mar 23 Bel | Implemented in bot.ts. Check-in: opens 30 min before session start. Check-out: 30 min before end to 24 hours after end. Records checked_in_at and checked_out_at on appointments. Check-out auto-transitions status to Awaiting_Approval_Parent. See Telegram docs. |
| DONE | Daily 7am reminders with session details | Telegram docs | Mar 24 Nicole | Implemented in reminders.ts. sendDailyReminders() runs for all linked tutors. Shows today's sessions with child name, time, Google Maps link for address, and pending upload count. Dedup via telegram_reminder_log. See Telegram docs. |
| DONE | Pre-session 1hr reminders | Telegram docs | Mar 24 Nicole | Implemented in reminders.ts. sendPreSessionReminders() finds sessions starting in 45-75 min window (15-min cron interval). Shows check-in button if not yet checked in. See Telegram docs. |
| DONE | Coordinator notifications on changes | Telegram docs | Mar 24 Nicole | Implemented via notifyCoordinators() in bot.ts. All admin-linked Telegram accounts receive notifications for cancellations and reschedule requests. See Telegram docs. |
| DONE | Session notes submission via Telegram | Telegram docs | Mar 24 Nicole | Implemented. Tutors can send files/voice notes with #ID in caption to attach to sessions. Files stored in R2 (nivaa-pdfs). /notes command available. See Telegram docs. |
| DONE | Verify session after it happened (post-session confirmation) | Appointments | Mar 23 Bel | Implemented. Confirmation endpoint (POST /appointments/:id/confirm) now has explicit guard: cannot confirm before session date (appt.date > today check). 2-day post-session window also enforced. See Appointments. |
| PARTIAL | Ad-hoc session approval vs regular distinction | Appointments | Mar 23 Bel | Sessions can be logged with billed_as_addon=1 flag. Tracked separately in analytics. But no distinct approval workflow for ad-hoc vs regular -- both follow the same confirmation path. Would appear at Appointments. |
6. Posting & Matching
The postings workflow replaced the old algorithmic matching. Parents post needs, tutors browse and apply, coordinators review and push, parents accept. Match scoring is precomputed across 5 dimensions.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| DONE | Full postings workflow (post > apply > push > accept) | Postings | Mar 19 Nicole/Bel/Bipin | Fully implemented in postings.ts. Parent creates posting, tutors browse/apply, coordinators push selected tutors, parent accepts. Silent rejection of other applicants on acceptance. Routes registered in index.ts. See Postings. |
| DONE | Match scoring across 5 dimensions | Postings | Mar 19 Nicole/Bel/Bipin | Implemented in postings.ts. Subject (0-25), Language (0-20), Gender (0-15), Timing (0-20), Special Needs (0-20) = max 100. Location is a separate filter toggle. Shown on admin detail view. See Postings. |
| DONE | 25% discount off first 2 sessions per child | Billing | Mar 19 Nicole/Bel/Bipin | Implemented in postings.ts line 403-415. On match acceptance, creates FirstSession discount with 25% off, 2 sessions remaining. Checks for existing active discount first. See Billing. |
| DONE | Coordinator ad-hoc discounts | Billing | Mar 19 Nicole/Bel/Bipin | Implemented as POST /admin/discounts in postings.ts line 709+. Supports custom percent_off, flat_amount_off, sessions_remaining, and reason. See Billing. |
| DONE | Location area and postal code on postings | Postings | Mar 19 Nicole/Bel/Bipin | Postings store location_area and postal_code. Location match scoring uses area string matching and postal district comparison (first 2 digits). See Postings. |
| DONE | Gender and language preference on postings | Postings | Mar 19 Nicole/Bel/Bipin | Postings store gender_preference and language_preference. Used in match scoring (gender 0-15, language 0-20). See Postings. |
| TODO | Multi-stage posting wizard (1. child, 2. time, 3. subject, 4. prefs, 5. special needs, 6. coordinator notes) | Postings | Mar 19 Nicole/Bel/Bipin | Not implemented as a guided wizard. Current posting creation is a single-form submission. API supports all fields but frontend doesn't have step-by-step flow. Would appear at Postings. |
| TODO | Prefill subject with child proficiency | Postings | Mar 19 Nicole/Bel/Bipin | Not implemented. Posting form doesn't auto-populate from child's student_profile hard_requirements. Would appear at Postings. |
| PARTIAL | Prefill location from parent/child address | Postings | Mar 19 Nicole/Bel/Bipin | Address data exists on both parent users and child profiles. Posting accepts location_area and postal_code but no auto-prefill from child address in the frontend. Would appear at Postings. |
| TODO | Decision aging for matches (how long a parent has been waiting) | Students | Mar 24 Nicole | Not implemented. No aging/SLA tracking on match decisions. Would appear at Students. |
| TODO | Show 'X other kids need this tutor' indicator | Postings | Mar 24 Nicole | Not implemented. No cross-posting demand indicator on tutor application views. Would appear at Postings. |
7. Parent Experience
Parent-facing features: child management, tutor visibility, session approval, disputes, and dashboard guidance.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| DONE | Child soft delete (deactivated_at) | Students | Mar 20 Nicole | Implemented in migration 0013. DELETE /children/:id sets deactivated_at timestamp. Parent list/get filters out deactivated. Admin sees all. See Students. |
| DONE | Parent issues linked to sessions | Tickets | Mar 20 Nicole | Implemented. POST /issues requires appointment_ids array. parent_issues table (migration 0013). Routes: /issues, /issues/mine, /admin/issues. See Tickets. |
| DONE | Parent alerts system | /parent | Mar 20 Nicole | Implemented. GET /alerts/parent computes: package low (<20%), pending session approvals, tutor recommendations, children without intake, readiness reports due. See /parent. |
| PARTIAL | Parent view: child > tutors (color coded current vs past) | /parent/children | Mar 20 Nicole / Mar 24 | Parent child detail page exists at /parent/children/childId]/+page.svelte with sub-routes for appointments, sessions, feedback, insights, proposals, readiness. Tutor visibility is controlled by match status (hidden until Parent_Accepted). Color coding of current vs past tutors not verified in frontend. See [/parent/children. |
| TODO | Fix guide boxes on parent dashboard | /parent | Mar 24 Nicole | Not verified as fixed. Parent dashboard at /parent/+page.svelte exists but guide box state unclear. Would appear at /parent. |
| DONE | Can't approve session before it happened | Appointments | Mar 24 Nicole | Implemented. POST /appointments/:id/confirm now rejects if appt.date > today (future session guard). Combined with existing 2-day post-session window. See Appointments. |
8. Admin Operations
Coordinator-facing pages for managing students, tutors, appointments, and operational oversight.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| DONE | Students page with enrichment (active status, days since last lesson, total sessions, funnel split, search) | Students | Mar 24 Nicole / Mar 19 | Fully implemented in admin.ts handleAdminListStudents. Returns total_sessions, last_session_date, sessions_last_30d, future_sessions, days_since_last_lesson, is_active, match_status, posting status. Funnel filter with active/awaiting/has_options/needs_attention. Separate handleAdminStudentCounts for KPI badges. See Students. |
| DONE | Students page: respond.io lead linkage | Students | Mar 24 Nicole | Implemented. Admin student list cross-references legacy_listing_id with respond.io listing_number custom field. Returns has_lead and respondio_contact_id per student. See Students. |
| DONE | Family tree view | /admin/family-tree | Mar 19 Nicole/Bel/Bipin | Implemented. GET /admin/family-tree returns hierarchical JSON (parents > children > tutors with session counts). Frontend at /admin/family-tree. |
| DONE | Tutor performance list with stats | Tutors | Mar 24 Nicole / Mar 19 | Implemented as handleAdminTutorPerformance in admin.ts. Returns total_sessions, total_hours, last_session_date, active_match_count, completion_rate, avg_nps, subjects, languages, area, onboarding_status per tutor. See Tutors. |
| DONE | Tutor detail endpoint | Tutors | Mar 24 Nicole | Implemented as handleAdminTutorDetail in admin.ts (line 1106+). See Tutors. |
| DONE | Appointments page: full session metadata | Appointments | Mar 24 Nicole | Implemented. Backend now returns confirmed_by_parent, confirmed_by_tutor (integer flags), legacy_listing_id, posting_subject, parent_user_id, child_id, tutor_id. Frontend has approval checklist, quick links, subject chip, tutor notes display. See Appointments. |
| DONE | Insights: macro trends and pills | Students | Mar 24 Nicole | Implemented. Backend returns aggregates: trend_distribution (improving/steady/declining), attention_profile_distribution, avg_confidence_score, total_observations. Frontend shows KPI pills. Also added source_origin for demo data badges. See Students. |
| DONE | Admin appointments page: quick links to parent info and listing IDs | Appointments | Mar 24 Nicole | Implemented. Backend returns parent_user_id, child_id, tutor_id, legacy_listing_id. Frontend groups by child and shows parent name. Quick links available via ID fields. See Appointments. |
9. Billing & Packages
Session packages, invoicing, payouts, and financial operations. Currently basic with significant planned enhancements.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| DONE | Package summary endpoint | Billing | Mar 19 Nicole/Bel/Bipin | Implemented as GET /billing/package-summary in billing.ts. See Billing. |
| DONE | Pricing plan resolution with ad-hoc vs package billing | Billing | Mar 19 Nicole/Bel/Bipin | Implemented in pricing.ts. resolvePricingPlanForSession with billedAsAddon option. Discount resolution via resolveDiscountForSession and consumeDiscountSession. See Billing. |
| TODO | Package renewal workflow (threshold at 80% used, trigger at 8th session) | Billing | Mar 19 Nicole/Bel/Bipin | Not implemented. No renewal trigger or threshold detection. Would appear at Billing. |
| TODO | FIFO deduction from packages | Billing | Mar 19 Nicole/Bel/Bipin | Not implemented. No FIFO package consumption logic. Would appear at Billing. |
| TODO | Payout through OCBC (CSV format for bulk payments) | Billing payouts | Mar 19 Nicole/Bel/Bipin | Not implemented. Payout route exists (payout.ts) but no OCBC CSV export. Would appear at Billing payouts. |
| TODO | Aging A/R: block parents with 30+ day overdue | Risk | Mar 19 Nicole/Bel/Bipin | Not implemented. No accounts receivable tracking or blocking mechanism. Would appear at Risk. |
| TODO | Invoice generation + send link through WhatsApp | Billing | Mar 19 Nicole/Bel/Bipin | Not implemented. PDF generation exists (pdf-lib in Worker) but no invoice template or WhatsApp delivery. Would appear at Billing. |
| TODO | CardUp integration for payments | Billing | Mar 19 Nicole/Bel/Bipin | Not implemented. No payment gateway integration. Would appear at Billing. |
10. Analytics & Reviews
Parent feedback, NPS scoring, and conversion analytics.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| PARTIAL | NPS reviews with scoring | Tutors | Mar 19 Nicole/Bel/Bipin | Feedback system exists in feedback.ts. Captures nps_score and session_rating per appointment/match. Average NPS calculated per tutor. However, no automated timing trigger (after trial + every 8 sessions) -- reviews are submitted manually. See Tutors. |
| PARTIAL | Review questions (educator quality, operations, NPS, curated content) | Tutors | Mar 19 Nicole/Bel/Bipin | Current feedback captures nps_score, session_rating, and comment. Does not have the full 4-question structure (educator quality, operations, NPS, curated content) -- only NPS and session rating. Would appear at Tutors. |
| TODO | If good NPS, prompt Google review | Tutors | Mar 19 Nicole/Bel/Bipin | Not implemented. flagged_for_review triggers on low NPS (<6) but no positive NPS flow to Google review. Would appear at Tutors. |
| TODO | Conversion by Facebook campaign analytics | Respond.io contacts | Mar 19 Nicole/Bel/Bipin | Not implemented. Campaign data exists in respond.io custom fields but no aggregation by campaign. Would appear at Respond.io contacts. |
| TODO | Parent NPS review timing automation (after trial + every 8 sessions) | Appointments | Mar 19 Nicole/Bel/Bipin | Not implemented. No session-count trigger for review prompts. Would appear at Appointments. |
11. Educator Insights & Gamification
Tools for educators to build knowledge about their students' conditions, earn recognition, and access research.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| DONE | Educator submit insights per child | Students | Mar 19 Nicole/Bel/Bipin | Implemented in insights.ts. Tutors submit per-child insights with learning_style, pacing_recommendation, motivators, friction_points, confidence_score, and source_origin. Admin and parent views available. See Students. |
| DONE | Telegram reminders to clock in (challenge: remembering) | Telegram docs | Mar 19 Nicole/Bel/Bipin | Solved via pre-session 1hr reminders in reminders.ts and daily 7am summary. Check-in button included in reminder messages. See Telegram docs. |
| TODO | Points and ranking system for educators | Tutors | Mar 19 Nicole/Bel/Bipin | Not implemented. No gamification, points, or leaderboard system. Would appear at Tutors. |
| TODO | Research page per student (PubMed journals) | Students | Mar 19 Nicole/Bel/Bipin | Not implemented. No PubMed or academic research integration. Would appear at Students. |
| TODO | Conditions knowledge base (Autism, ADHD, Dyslexia, GDD, Dyscalculia) | /docs | Mar 19 Nicole/Bel/Bipin | Not implemented. Special needs are tracked as a flag (has_sped_needs) but no condition-specific content library. Would appear at /docs. |
| TODO | Color contrast / sensory strategies from AI | Students | Mar 19 Nicole/Bel/Bipin | Not implemented. No AI-driven strategy recommendations. Would appear at Students. |
13. Phase 1 Launch (April 2026)
Priority features for the limited educator + coordinator launch. Parents mimicked by coordinators.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| DONE | Rename Matches → Assignments throughout tutor workspace | /tutor/matches | Mar 30 Nicole | DONE. Sidebar, page titles, labels across 6 tutor-facing files renamed. API endpoint /matches/mine unchanged. |
| DONE | Fit Score: grade + subject + special needs only (not location) | /admin/postings | Mar 30 Nicole | DONE. Location removed from score. Special needs (0-20) added. 'Show in my area' toggle filter on tutor browse page. |
| DONE | Coordinator flag on tutors (hidden from educators) | /admin/postings | Mar 30 Nicole | DONE. coordinator_flag text column on tutor_profiles. Inline editor on posting review. Hidden from tutors. |
| DONE | Demo profiles: Bel + Nicole as Parent and Tutor | /login | Mar 30 Nicole | DONE. Migration 0028: 4 accounts created with PBKDF2 password hashes. Password: Demo1234. |
| DONE | Dispute invoice line items (select sessions → dispute → ticket) | /parent/billing | Mar 30 Nicole | DONE. Migration 0030. POST /invoices/:id/dispute. Parent selects sessions, enters reason, creates Dispute ticket. |
| DONE | D3 swimlane flowcharts for 5 key workflows (in docs) | /docs | Mar 30 Nicole | DONE. Swimlane block type added to DocRenderer. 5 workflow pages at /docs/workflows/*. |
| DONE | Withdrawn status update immediately on tutor browse page | /tutor/postings | Mar 30 Nicole | DONE. Backend subquery excludes withdrawn apps. Frontend does optimistic UI update. |
| DONE | Payout notification via Telegram | /docs/telegram | Mar 30 Nicole | DONE. notifyTutorsPayoutProcessed() fires on cycle Finalized. Shows amount, period, hours, breakdown. |
| DONE | Save as Draft on key forms (posting, readiness, intake) | /docs/forms-validation | Mar 30 Nicole | DONE. Posting: Draft status + ?draft=id editing. Readiness: Draft + resume. Onboarding: Save & Continue Later. |
| DONE | Bigger tutor proposal cards with full profile for parents | /parent/postings | Mar 30 Nicole | DONE. Enlarged cards with stats bar, experience bars, subject pills, SN support. Trial session slot picker. |
| DONE | Proficiency test at time of posting (or reuse from last 30 days) | /parent/postings/new | Mar 30 Nicole | DONE. Migration 0029. GET/POST /children/:id/proficiency. Inline assessment in posting form. 30-day reuse. |
| TODO | Proficiency visible over time in student page for coordinators | /admin/students | Mar 30 Nicole | Historical proficiency snapshots on student detail page. |
| DONE | Three sections in tutor postings: Good Match / Other / My Area | /tutor/postings | Mar 30 Nicole | DONE. 3 collapsible sections: Good Match (≥60), Other, My Area. Fit pills and breakdown rows. |
| TODO | Gamification: points, leaderboard, session-based rewards | /tutor/insights | Mar 30 Nicole | Points for sessions, new students, uploads. Leaderboard concept. |
| TODO | Tutor timing dispute mockup + workflow | /tutor/sessions | Mar 30 Nicole | Tutor proposes alternative timing, parent responds. |
12. Readiness Report Enhancements
The readiness report is currently a 7-domain questionnaire (A-G) scored 0-3. Bel's feedback calls for significant restructuring to focus on tutoring-specific assessment rather than classroom readiness.
| Status | Item | Route | Source | Agent Verdict |
|---|---|---|---|---|
| SUPERSEDED | Current 7-domain structure (A: Classroom Compliance through G: Literacy & Numeracy) | /parent/children/ID/readiness | Mar 23 Bel | Current implementation in readiness.ts uses domains A-G with 4 items each (G has 9). Bel's feedback proposes restructuring -- current implementation works but structure needs revision. See /parent/children/ID/readiness. |
| DONE | Rename: 'Classroom Readiness' to 'Tutoring Readiness: Sensory, Developmental, and Learning Profile' | /parent/children/ID/readiness | Mar 23 Bel | Implemented. Backend readiness.ts restructured. Alerts reference 'Tutoring Readiness Profile'. Route stays /readiness/. See /parent/children/ID/readiness. |
| DONE | Remove: Classroom Compliance (A), Group Readiness (F) domains | /parent/children/ID/readiness | Mar 23 Bel | Implemented. Domains A and F removed from DOMAIN_KEYS. Legacy keys kept for backward-compat scoring of old reports. New overall = B+C+D+E+H. See /parent/children/ID/readiness. |
| DONE | Add: Sensory Processing domain | /parent/children/ID/readiness | Mar 23 Bel | Implemented. Domain H with 4 items (H1-H4): sensory sensitivity, sensory seeking, sensory avoidance, self-regulation strategies. Stored in total_h column (migration 0025). See /parent/children/ID/readiness. |
| DONE | Emotional regulation: what does child need? (teddy, hug, cartoon) | /parent/children/ID/readiness | Mar 23 Bel | Implemented. coping_mechanisms text field on readiness_reports (migration 0025). Captures specific regulation needs alongside 0-3 scoring. See /parent/children/ID/readiness. |
| DONE | Add textboxes for all domains (qualitative notes) | /parent/children/ID/readiness | Mar 23 Bel | Implemented. notes_b through notes_h columns (migration 0025). Each domain gets a free-text field for qualitative observations. See /parent/children/ID/readiness. |
| DONE | Custom questions per subject/level | /parent/children/ID/readiness | Mar 23 Bel | Implemented. 459 proficiency topics across 3 subjects (English, Maths, Science), 61 level/stream combos parsed from .docx files into proficiency-topics.json. Stored in proficiency_scores_json column. See /parent/children/ID/readiness. |
| SUPERSEDED | Only show readiness after tutor allocated | /parent/children/ID/readiness | Mar 23 Bel | Current implementation allows parents to fill out readiness reports for any child at any time. Per CLAUDE.md: 'Recommended after first 2 sessions.' Gating by tutor allocation would conflict with the current flow where reports help inform matching. See /parent/children/ID/readiness. |
| DONE | Pre-first-session: soft requirement for readiness report | /parent | Mar 23 Bel | Implemented. Alerts now trigger when child has a match (even 0 sessions). Message: 'Complete their Tutoring Readiness Profile before the first session.' Check endpoint also returns has_match flag. See /parent. |