projects / easemysemester / features
Privacy notice and terms, tested against the schema
v2's privacy notice and terms replaced one-paragraph stubs and are tested against the real schema, so a claim about what data is held cannot drift from what the database actually stores.
feature · current · updated 2026-09-16 · EaseMySemester case study
See overview and Google OAuth decision. Shipped 2026-09-10, public and ungated, ahead of OAuth review.
The problem it fixes
The old privacy stub told students the app keeps their name. It never has: the Google
callback reads sub, email and email_verified, and the users table has no name column.
A public page carried a false statement about what the app holds, and nothing in a review had
caught it because nothing linked the page's claims to the schema.
The fix is a test, not just a rewrite
A disclosure list renders on the privacy page, and a test reads the real migrations and fails
the unit lane when a table that references users(id) or carries an email column is missing
from that list. The same test proves every table the page claims is deleted with the account
actually cascades from users, so the deletion promise is only as true as the schema. Adding
a per-user table later breaks the suite until the new page copy accounts for it.
What the pages disclose
The three OAuth scopes requested, Google's Limited Use disclosure, all seven personal-data tables, the cookies in use and what each is for, the four processors (Google, OpenRouter, Vercel, Neon) including that model providers may train on text sent to them, a 30-day deletion window, and a contact address. No governing-law clause, by decision.
A second test asserts properties invisible from inside the app that would otherwise break
silently: both pages render with no session, neither imports the auth guard, the connection
pool, or next/headers, the landing page links to both, and the notice carries a contact
address and the Limited Use text. A production build confirms /privacy and /terms are the
only static routes in the app.
Status
Shipped 2026-09-10 (issue unspecified in the commit). No migration was required.