diff --git a/.env.example b/.env.example index 66c1eef..c40fddd 100644 --- a/.env.example +++ b/.env.example @@ -82,5 +82,29 @@ PORT=3000 # which would have published a sitemap full of localhost URLs. NEXT_PUBLIC_SITE_URL=https://www.fedkiit.com +# --- Tunables --------------------------------------------------------------- +# All optional. Every default below reproduces the previous hardcoded value, so +# leaving them unset changes nothing. + +# One-time passwords. NEXT_PUBLIC so OtpInput draws exactly this many boxes — +# one variable for both sides means the code length and the UI cannot desync. +NEXT_PUBLIC_OTP_LENGTH=4 +OTP_VALIDITY_MINUTES=15 + +# Extra hosts allowed to appear in an Origin header when building an emailed +# invite link. Comma-separated. The canonical site host, localhost and 127.0.0.1 +# are always trusted; this is for staging and preview deployments. +# e.g. TRUSTED_ORIGIN_HOSTS=staging.fedkiit.com,fed-frontend.vercel.app +TRUSTED_ORIGIN_HOSTS= + +# Addresses that may read form analytics regardless of role. Comma-separated. +# Previously the literal srex@fedkiit.com in the route. +FORM_ANALYTICS_ALLOWED_EMAILS=srex@fedkiit.com + +# Calendar month (1-12) the academic year rolls over in. Used to derive the year +# of study from a KIIT roll number, so a 2022 intake stays 4th Year until July +# 2026 rather than being promoted every 1 January. +ACADEMIC_YEAR_START_MONTH=7 + LOG_REQ=false DEBUG=false diff --git a/MIGRATION.md b/MIGRATION.md index 697b516..7344ade 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -343,6 +343,757 @@ answer 400 on an empty body, and `logout` is idempotent. `changePassword` is the reset step and is gated on a single-use OTP, rate limited, and returns the same message whether or not the account exists. +## Load time — the barrel files were the problem + +The landing page was shipping **2.3 MB of JavaScript**. The cause is visible in +any dev-server warning trace: + +``` +./src/sections/Profile/Admin/View/VerifyCertificate/VerifyCertificate.jsx +./src/sections/Profile/index.jsx +./src/sections/index.jsx <- re-exports Home *and* Profile +./src/views/Home/Home.jsx +./app/(main)/page.jsx +``` + +`Home.jsx` imported `{ Hero, About, Sponser, Feedback, Contact }` from the +`sections` barrel, which also re-exports `sections/Profile` — the entire admin +panel. Every one of those is a client component, so the bundler pulled the whole +graph into the landing page: certificate tooling, admin tables, the avatar +editor, event analytics. A visitor who only wanted the hero image downloaded the +admin panel. The `features` barrel did the same thing for `LiveEventPopup`. + +Under Vite this cost nothing noticeable, because the dev server serves ES modules +untouched and the SPA loaded one bundle for every route anyway. Under Next each +route gets its own bundle, so a barrel import silently undoes the code splitting. + +Fixed by importing the four components directly instead of through a barrel. The +barrels are untouched — other call sites still use them. + +| Page | Before | After | +|---|---|---| +| `/` | 2317 KB | **1082 KB** | +| `/Events` | 2063 KB | **1082 KB** | +| `/Team` | 2014 KB | **1082 KB** | +| `/Login` | 1248 KB | **920 KB** | + +Uncompressed. Over the wire the landing page is **327 KB** of JS and 55 KB of +HTML, and locally serves in TTFB 38 ms / DOMContentLoaded 135 ms / load 536 ms. + +**Dev-server slowness is separate and expected.** `next dev` compiles each route +on first request, so a cold page can take seconds while production serves the +same page in 5–30 ms. Measure `npm run build && npm start`, never `npm run dev`. + +## Invalid HTML nesting that only mattered under SSR — all of it + +Four components wrapped block-level content in a `
`: + +| Component | The nesting | +|---|---| +| `EventCard` | `
` → `div.price` → `
` | +| `EventModal` | `
` → `div.price` → `
` | +| `Hero` | `
` → `` → ` ` → `div.fed` → `` |
+| `Social` | `