Gradeful
CoursesPricingAbout

How Gradeful connects

Raw markdown

Auth & onboarding

Registration, sign-in, password recovery, and name/university setup. Product rules: ../onboarding.md. How this hooks to checkout and dashboard: 00-how-everything-connects.md.


PAGE: /login Purpose: Sign in with Google or email/password. Access: public (logged-in visitors are redirected by proxy to /auth/home with safe next) Entry points: Header Sign in; protected-route bounce with next; signup Sign in →; forgot/reset return; checkout buildLoginHref; /login?next=; /login?message=password_updated; /login?error= from /auth/callback.

SECTION: Brand panel (desktop) Copy: Your exam is coming. Your course is ready. Course-specific study packs. Data shown: static

ELEMENT: Gradeful (logo, aria-label Gradeful homepage) Action: navigate Destination: / Writes to: none Reads from: none

SECTION: Status banner Copy: Password updated. Please sign in. Data shown: query message=password_updated only

SECTION: Callback error Copy: allowlisted human messages from lib/auth/callback-errors.ts (auth_failed, access_denied, otp_expired, …). Raw IdP errors are never shown. Data shown: query error

SECTION: Form header Copy: Welcome back Sign in with Google or the email you used to create your account. Data shown: static

ELEMENT: Continue with Google Action: submit Destination: Google OAuth then /auth/callback?next= (safe) Writes to: auth.users / session; new Google users also get profiles via trigger Reads from: none Errors: Social sign-in is unavailable. Please try again. Unable to connect. Please check your connection.

SECTION: Divider Copy: or email Data shown: static

SECTION: Email panel Copy: Label Account email placeholder you@email.com. Label Password. Data shown: form state

ELEMENT: Forgot password? Action: navigate Destination: /forgot-password Writes to: none Reads from: none

ELEMENT: Sign in Action: submit Destination: /auth/home?next= (safe) Writes to: Auth session only Reads from: none Errors: Email or password is incorrect. Unable to connect. Please check your connection.

SECTION: Footer Copy: Don't have an account?

ELEMENT: Sign up → Action: navigate Destination: /signup or /signup?next=… Writes to: none Reads from: next query if present

Phone OTP is not offered. Hosted Gradeful had zero phone identities.


PAGE: /signup Purpose: Create a student account (Google or email). Access: public (logged-in redirected by proxy) Entry points: Login Sign up →; marketing; course page Start this course (buildSignupHref to checkout); /signup?next=.

SECTION: Form header Copy: Create your account Google or email. Then your name and university — enough to open the right course. Data shown: static

ELEMENT: Continue with Google Action: submit Destination: Google then /auth/callback?next=… Writes to: auth.users; profiles via private.handle_new_user (role stays student) Reads from: none Errors: Social sign-up is unavailable. Please try again. Unable to connect. Please check your connection.

SECTION: Email signup Copy: Label Email placeholder you@email.com. Label Password. Help Use at least 8 characters. Avoid passwords that have shown up in a data breach. Label Confirm password. Data shown: form state

ELEMENT: Create account Action: submit Destination: in-place “Check your email” Writes to: auth.users; profiles via trigger Reads from: none Errors: Enter a valid email address. Passwords do not match. We could not create your account. Try signing in instead. Unable to connect. Please check your connection.

SECTION: Footer ELEMENT: Sign in → Destination: /login or /login?next=…

SECTION: Check your email Copy: Check your email We sent a verification link to {submittedEmail} Didn't receive it? ELEMENT: Resend → Success: Verification email sent. ELEMENT: Back to sign in → /login (+ optional next)


PAGE: /forgot-password Purpose: Request a password-reset email. Access: public Entry points: Login Forgot password?

SECTION: Card Copy: Reset your password Enter your email and we'll send you a reset link. Label Email placeholder you@email.com. ELEMENT: ← Back to login → /login ELEMENT: Send reset link / Sending... Destination: none (redirectTo /reset-password) Success: Check your email for a reset link. Errors: We could not send the reset link. Please try again. Unable to connect. Please check your connection.


PAGE: /reset-password Purpose: Set a new password from the email recovery link. Access: public (needs recovery session or ?code=) Entry points: Reset email link.

SECTION: Invalid Copy: This reset link is invalid or has expired. ELEMENT: Request a new reset link → /forgot-password

SECTION: Ready form Copy: Label New password. Help Use at least 8 characters. Label Confirm password. ELEMENT: Update password / Updating... Destination: /login?message=password_updated after signOut Writes to: auth.users password hash Errors: Passwords do not match. We could not update your password. Try again. Unable to connect. Please check your connection.


PAGE: /auth/callback Purpose: Exchange OAuth/email code for a session; optional welcome email; send the student through /auth/home with safe next. Access: public (session is created here) Entry points: Google OAuth; email verification link; Auth redirects with ?code=&next=.

SECTION: No UI Copy: none. On failure: /login?error={allowlisted} plus preserved safe next. ELEMENT: none (route handler) Action: navigate Destination: /auth/home?next= on success; login error URL on failure Writes to: Auth session cookies. Welcome email via Resend if profiles.created_at within 5 seconds. Reads from: profiles.created_at, profiles.full_name


PAGE: /auth/home Purpose: After login, send incomplete name/university profiles to /welcome?next= and everyone else to the preserved destination (course, checkout, or /dashboard). Access: logged-in (anonymous → /login) Entry points: Default after login/signup/OAuth; proxy redirect from /login//signup when already logged in.

SECTION: No UI ELEMENT: none (route handler) Action: navigate Destination: resolveLoggedInDestination Reads from: profiles.full_name, university, onboarding_completed_at


PAGE: /welcome Purpose: Required onboarding only: who are you (name) and which university offering (AUB/LAU). Preserve next. Access: logged-in; incomplete onboarding. Anonymous → /login?next=/welcome. Already complete → preserved next, /dashboard if active access, otherwise /. Entry points: /auth/home; workspace layout; checkout; direct URL.

SECTION: Brand panel (desktop) Copy: Your university. Your courses. Twenty seconds. Then you're in — not a marketing page.

SECTION: Intro Copy: Almost in Tell us where you study. Name, university, major. We use this to show the right packs — nothing to verify here.

SECTION: Who are you? Copy: Label Your name placeholder Maya Haddad. How Gradeful greets you — not a public username.

SECTION: What course do you need? Copy: Which university? AUB and LAU use different course codes. This picks the matching offering. ELEMENT: AUB / LAU cards If next is checkout/course: We'll send you back to checkout for the course you already picked. / We'll send you back to that course. If homepage: After this you can pick a course. Major and campus can wait. plus continue to /courses.

SECTION: Submit Copy: Continue to checkout / Continue to your course / Find a course Writes to: profiles.full_name, university, onboarding_completed_at (optional campus/major if present) Toasts: Add the name you use at uni. Pick AUB or LAU so we show the right packs. Could not save that. Try again.

Major, minors, and LAU campus are not on this form.

Gradeful

Course-specific study packs for AUB and LAU students. Built for focused self-study.

Gradeful is an independent study-support service. Universities named on this site are listed only so you can match a Gradeful pack to the course you are taking. Those universities do not provide, sponsor, or endorse Gradeful, and Gradeful does not claim access to their official materials or assessments.

© 2026 Gradeful.

Platform

HomeCoursesPricing

Policies

Privacy PolicyTerms of ServiceRefund PolicyAcademic Integrity