Changelog

What's new.

Everything that's shipped on tutor., in reverse chronological order. Expect this page to grow as we get closer to launch.

  1. shipped

    Automatic refunds on paid cancellations

    • Cancel a paid session 12+ hours before it starts and you get a full refund back to the original card — we fire a Stripe refund at the same moment the booking is cancelled.
    • Shows up on the dashboard as a 'Refunded' badge. Usually lands on your statement in 5–10 business days.
    • Cancel dialog now promises the refund explicitly. Terms updated to match.
    • If the refund call fails for any reason, the cancel is rolled back so we never end up in the 'cancelled but not refunded' state silently.
  2. design

    Confirmation dialogs + duration-grid slots + friendlier copy

    • Booking now asks 'are you sure?' before submitting. Free sessions get a softer 'Lock in your free session?'; paid sessions get 'Ready to pay and book?' with the amount in the confirm button.
    • Cancelling asks 'Cancel this session?' with the exact date/time and reminds you that the slot opens up and your free session resets.
    • Calendar now snaps to the duration: pick 60 min → slots show at every hour, not every 15 min. Pick 30 → :00 and :30 only. A 60-min booking still blocks overlapping 30-min attempts via the DB exclusion constraint.
    • Student-facing copy softened: dashboard greeting, empty-state headline, and supporting lines now read more like a friend than a form.
  3. fix

    Cancellation window: 24h → 12h

    • You can now cancel a booking up to 12 hours before the start time (down from 24). Dashboard, signup copy, terms, booking review, and confirmation email all updated.
    • The Resend-hosted email template still needs a matching edit in the Resend UI (we can only change template copy there, not in code).
  4. shipped

    Stripe payments + first session free

    • Every account gets one free session to start. After that, sessions are paid: 30 min / 45 min / 60 min priced in CAD, configurable via env.
    • Paid bookings now redirect through Stripe Checkout. The slot is locked when you click confirm (via the Postgres exclusion constraint), held for 30 min while you finish checkout, and released if you abandon.
    • After payment, Stripe sends you back to /book/success which verifies the session with Stripe, marks the booking paid, and fires the confirmation email.
    • Cancelling a booking — even a paid one — resets you to the free tier. Next booking is on the house again. Deliberate: we want you to actually show up, not get stuck.
    • Dashboard now shows a payment status pill on every booking: Free, Paid, Payment pending.
  5. design

    Brand mark lands on every page

    • Replaced the plain ink squares in the nav, footer, and every page header with the actual tutor. brand mark — a lime T with a period, on an ink rounded-square background.
    • Same mark is now the browser favicon and the iOS home-screen icon.
  6. shipped

    Post-Google-signup profile step

    • Google sign-in doesn't give us age (Google won't share it) — so after Google signup you land on /get-started to fill in age (5–18) and confirm your name.
    • Returning users skip the page automatically; the route bounces straight to the dashboard if the profile is already complete.
    • Trying to hit /book without a complete profile now redirects back to finish it. Age is required for picking the right material.
  7. shipped

    Privacy policy + terms of service

    • Added /privacy and /terms pages written in plain language — what we collect, how long we keep it, cancellation rules, contact.
    • Covers K-12 specifics: parental guidance for under-13 accounts, account deletion on request.
    • Linked from the footer. Firebase OAuth consent can now point at these URLs for the 'App privacy policy' and 'App terms' links.
  8. fix

    Human-readable auth errors

    • Raw Firebase errors like 'auth/popup-closed-by-user' are now translated into plain English on the signup and login pages.
    • Cancelling the Google popup is silent (no red error splashed across the form). Wrong password, network errors, blocked popups, and similar all have friendly messages.
  9. infra

    Auth swapped from better-auth to Firebase

    • Email + password and Google sign-in both go through Firebase now.
    • Firebase owns identity (password hashing, OAuth, email verification); our database keeps the app-specific bits — role, age, and booking relationships keyed by Firebase UID.
    • Session is a signed httpOnly cookie created from a verified Firebase ID token. No more custom session table.
    • Anyone who made a test account earlier will need to sign up again — the user table was reset during the migration.
  10. infra

    Email design now lives in Resend

    • Booking confirmation emails are now sent via a Resend-hosted template (alias: session-confirmation).
    • Design edits happen in Resend's UI — no redeploy needed for copy or layout tweaks.
    • Server sends only the eight variables the template expects: student_name, teacher_name, date_label, time_label, duration_minutes, address, cancel_url, site_url.
  11. shipped

    Booking confirmation emails via Resend

    • Every confirmed booking now fires a branded HTML email: session time, duration, where, and a link back to the dashboard.
    • Lime-and-ink system carried over into the email so the brand stays consistent. Table-based layout with inline styles, renders everywhere from Gmail to Outlook.
    • Fire-and-forget: if the email fails to send, the booking still succeeds. The DB is the source of truth, not the email.
    • While the custom sending domain (mail.tutoring.aradrsk.com) verifies with DNS, we're sending from Resend's shared onboarding@resend.dev. Flip the EMAIL_FROM env once verification completes.
    • Preview the template live at /dev/email/booking.
  12. shipped

    Dashboard shows your real bookings

    • The /account/bookings page now reads from the database instead of showing a placeholder.
    • Upcoming sessions appear in a chunky card list with date, time, and duration. Past sessions collapse into a muted list below.
    • Students can cancel upcoming sessions more than 24 hours out. Closer than that, the cancel button is hidden and a note explains why. Teachers can cancel any session (emergencies happen).
    • Teachers see every confirmed booking with the student's name and email, not just their own.
  13. design

    Booking step 2 is now a calendar

    • The long vertical list of days in the booking wizard is gone.
    • New month-calendar grid: green = open (shows how many start times), grey = no availability, red = blocked.
    • Tap a date → open times appear in a panel below. Much faster than scrolling a list.
    • Works across month boundaries with prev/next arrows when the 30-day horizon crosses a month.
  14. design

    Teacher has a name: Theepa Jeyapalan

    • The landing page 'Your teacher' card now reads Theepa Jeyapalan. Bio copy updated too.
  15. shipped

    Booking flow is live

    • The /book route is a three-step wizard: pick length (30/45/60), pick a start time, review & confirm.
    • The server double-checks every booking against live availability before inserting, and catches the Postgres exclusion-violation cleanly when two people try to grab the same slot.
    • Dashboard empty-state now points straight to /book.
  16. shipped

    Teacher availability editor + public preview

    • Teachers now have /dashboard/availability: add weekly windows, block specific dates, and a 14-day preview that overlays 30/45/60-minute valid start times.
    • Landing page shows real availability for the next 15 days, with a green/grey/red legend. No more fake placeholder school logos.
    • The whole slot-generation engine is shared across teacher preview, landing page, and booking — so all three stay in sync automatically.
  17. design

    Full UX rehaul + /updates page

    • Introduced a shared Nav + Footer across every page — logged-in users now see a Dashboard link, logged-out users see Log in + Book a session.
    • Redesigned /signup and /login in the lime + ink system: chunky card, inline hints, proper error states, a value-prop list on signup.
    • Dashboard at /account/bookings got stat cards, an empty-state with clear next steps, and an account-details card that reads live from the session.
    • This /updates page is new. You're reading it.
  18. shipped

    Live at tutoring.aradrsk.com

    • Deployed to Vercel production with a custom domain.
    • Cloudflare DNS A record → Vercel edge. SSL auto-provisioned.
    • Environment variables moved out of local dev; production now reads DATABASE_URL, BETTER_AUTH_SECRET, and the site URLs from Vercel.
  19. infra

    Migrated to Neon Postgres

    • Swapped local SQLite for Neon serverless Postgres so the app works on Vercel's ephemeral filesystem.
    • Schema ported to pg-core with real enums (user_role, booking_status), timestamptz, checks, and proper indexes.
    • Bookings overlap exclusion constraint restored via btree_gist + a trigger-maintained end_at column — prevents a 30-min booking at 4:30 pm from colliding with a 60-min booking at 4 pm at the DB layer.
  20. design

    Landing page redesign

    • New visual system: lime #B9FF66 + ink #191A23 on white.
    • Chunky rounded cards with offset drop-shadows, section headers in lime pills, inline SVG illustrations for sessions and the hero.
    • Added a 4-card sessions grid (30 / 45 / 60 / free trial), 3-step how-it-works, a teacher profile card, and a dark pricing panel.
  21. shipped

    Auth + schema for signup / login / verify flow

    • Users can create accounts with name, age, email, and password.
    • Session cookies via better-auth. Dashboard redirects unauthenticated visitors to /login.
    • Email verification is currently off in dev; it comes back on when Resend is wired in TU-9.
  22. infra

    Project scaffold

    • Next.js 16 (App Router, Turbopack) on React 19, TypeScript 5, Tailwind 4, ESLint 9.
    • drizzle-orm + drizzle-kit for schema and migrations.
    • better-auth with a drizzle adapter. Pushed to github.com/aradrsk/tutoring.
  23. shipped

    PRD v1 locked

    • Resolved the five open product questions: public landing as home, teacher's home as fixed session location, configurable 30 / 45 / 60 min sessions, 24-hour cancellation window, and Vercel subdomain for v1 (later upgraded to tutoring.aradrsk.com).
    • Everything else in the PRD is downstream of those five decisions.

What's next

The remaining MVP backlog. Each row is a tracked issue; order is the critical path to launch.

  • TU-6

    Teacher sets weekly availability + date blocks

    Next up
  • TU-7

    Public landing page with visible availability

    Planned
  • TU-8

    Users can book a session with slot locking

    Planned
  • TU-9

    Email confirmations via Resend

    Planned
  • TU-10

    Teacher dashboard

    Planned
  • TU-11

    User dashboard with cancel

    Planned
  • TU-12

    Deploy to prod + onboard teacher

    Partial (prod live)