Changelog

What's new in ResumeBuildz. Every feature, fix, and improvement in one place.

v1.33.0June 1, 2026

Admin Role System, Impersonation & Email Notifications

Added

  • Admin role system with two internal tiers (admin / superadmin). Admins are scoped to their assigned users; superadmins act on all users. Access at /admin — full server-side role gate, no public exposure.
  • Admin dashboard at /admin/users — paginated, debounce-searched user table. User detail page supports plan override (admin+) and role change (superadmin only) with instant toast feedback.
  • User impersonation via signed HMAC-SHA256 cookies. Amber sticky banner on every page while impersonating; Exit button clears cookies and returns to /admin/users. Export My Data hidden during impersonation to prevent data extraction.
  • Admin email notifications: role promotion email sent when a user is upgraded to admin; plan change email sent on any admin-triggered plan override. Both are best-effort and never block the API response.
  • Superadmin bootstrap via SUPERADMIN_EMAIL env var — set it to auto-promote on first signup; existing accounts use a one-line SQL UPDATE. Documented in .env.example and README.
  • Unlimited AI rewrites and PDF exports for admin/superadmin — daily counters bypassed server-side in /api/usage.
  • Indigo ADMIN badge in the profile dropdown for admin/superadmin accounts; avatar ring changes to indigo; Admin dashboard link added below Account settings.
  • Pricing FAQ entry clarifying managed admin access for organizations.

Improved

  • useAuth.ts — role added to Profile type; isPro() returns true for admin/superadmin regardless of billing plan.
  • profile API — role field exposed in GET response.
  • proxy.ts replaces deprecated middleware.ts (Next.js 16 naming convention).
  • DB migration 0003 adds role and managed_by columns with managed_by index.
v1.32.0May 29, 2026

Real Rate Limiting via Upstash Redis

Added

  • Real rate limiting via Upstash Redis. When UPSTASH_REDIS_REST_URL + UPSTASH_REDIS_REST_TOKEN are set, every public write endpoint (share invite, waitlist, contact, checkout) gets a real per-IP/per-route limit shared across every Lambda instance and region. Atomic via Redis INCR + first-write EXPIRE; falls through to the in-memory burst guard on Upstash failure so a Redis blip never locks everyone out.
  • New optional env vars UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN. Without them the limiter degrades to the existing per-process in-memory burst guard — fine for dev and self-hosted single-node deploys; bypassable on Vercel because each Lambda instance has its own counter.

Improved

  • rateLimit() is now async; all four callers updated to await it.
  • @upstash/redis added as a dependency.
v1.31.0May 29, 2026

Server-Side Cleanup: R2 GC, Webhook Idempotency, DB Indexes

Added

  • R2 cleanup on account delete and avatar re-upload. Avatars are now removed from Cloudflare R2 when a user deletes their account, and the previous avatar is removed before a new one is uploaded. Closes the GDPR "right to be forgotten" gap and stops storage drift.
  • Stripe webhook idempotency. New webhook_events table records every processed event.id with ON CONFLICT DO NOTHING so a replayed webhook short-circuits before mutating state — defends against the next non-idempotent handler we add.
  • Database indexes on the columns the daily crons and Stripe webhook query — profiles.last_seen_at / inactive_warned_at / notify_product / stripe_customer_id and user.created_at. Eliminates full-table scans on every cron tick.
  • New lib/storage.ts helpers deleteFromR2 and deletePrefixFromR2. Both no-op when R2 isn't configured and swallow errors so storage failures cannot break the calling request.

Improved

  • Removed dead proxy.ts at the repo root — it was named/exported incorrectly so Next.js never picked it up; nothing in the file was running.
  • Removed five stale planning HTML files from the repo root (~225 KB) — none were referenced from code.
  • Landing page no longer mutates document.title and meta tags from useEffect. Those overrides were a no-op for crawlers and a redundant overwrite of the root-layout metadata.
  • Account page drops its document.title useEffect — app/account/layout.tsx already exports the correct metadata.
  • lib/rateLimit.ts docstring now honestly calls itself a best-effort burst guard rather than a rate limiter (the in-memory Map is per Lambda instance on Vercel — warm-instance scale-out and concurrent invocations bypass the cap). Calls out Upstash/Redis/Vercel KV as the migration target.
  • Silenced the pre-existing react-hooks/incompatible-library warning in VersionHistoryDialog with an inline eslint-disable. Build now ships with zero warnings.
v1.30.0May 29, 2026

Builder Polish: ATS Badges, Cover Letter PDF, JSON Resume, Share Expiry

Added

  • ATS-risk badges in the template picker — every template card now carries a small ✓ / △ / ✗ pill so users picking by aesthetics see upfront whether the layout is ATS-safe (single column), caution (decorative elements some parsers mis-read), or risky (multi-column / sidebar that ATS may reorder or drop).
  • Empty-state CTA cards on Education / Projects / Skills forms with a clear "Add Your First X" button.
  • Persistent offline banner when localStorage writes fail (private window or quota) — replaces the silent failure where the autosave chip still claimed "Saved".
  • Confirm-before-import dialog summarizing what is about to land ("Import 4 experience, 2 education, 18 skills?") with a reminder that Ctrl+Z reverts.
  • Share-link expiry (Never / 24h / 7d / 30d). Expiry timestamp encoded in the URL fragment; viewer renders an "expired" page past that date. Zero-trust model preserved.
  • Cover letter as PDF cover page — new checkbox in the Export → PDF menu prepends a styled cover-letter page to the PDF. Hidden on screen to avoid cluttering the preview.
  • JSON Resume schema import/export (jsonresume.org-compatible). Export menu gets "JSON Resume .json"; file import auto-detects the schema.
  • Schema-version migration scaffold on the persisted store so future schema changes can land without breaking existing localStorage data.
  • Toast warning when version history JSON is unreadable (instead of silent loss).

Improved

  • ATS scoring is now per-entry, not all-or-nothing. Adding one experience without a date no longer drops the Work Experience section from 25 to 15 points; partials get half credit.
  • Quantified-results detection broadened to catch $50K, $1.2M, 25x, 3.5×, 2nd / 3rd / 4th, 3M users — the metric formats real resumes use.
  • KeywordAutoInsert uses a small allowlist of real tech acronyms (API, SQL, AWS, CI/CD, …) so non-tech all-caps words like NBA / CEO / USA stop being classified as skills.
  • ATS score rings now include a non-color glyph (✓ / △ / ✗) plus role="meter" + aria-label, so colorblind and screen-reader users get the same signal as the colored rings.
  • Hardened print CSS — bullets no longer split across pages; paragraph orphans/widows policy added; the in-preview page-break indicator is now hidden in the printed PDF.
  • Import robustness — AI-fallback parser normalizes any non-array section (including explicit null) to [], so a malformed AI response cannot crash the import flow.
  • 44 × 44 touch targets on the preview zoom buttons, with proper aria labels.
  • aria-live on async AI regions so screen-reader users get notified when generation completes or errors.
  • AbortController on streaming AI calls (JDTailor, CoverLetterForm) — navigating away mid-stream cancels the request instead of burning Groq quota.
  • Fixed: Groq API key was being sent quoted because useSessionStorage JSON-stringifies its value, while getGroqApiKey() read the raw string. Every Groq call sent Authorization: Bearer "gsk_..." and got back 401 — AI features looked broken even with a valid key. Now unwrapped on read.
  • /api/share/invite refactored to use sendEmail() from lib/email.ts instead of a duplicate fetch — picks up the shared error logging; no behavior change for users.
v1.29.0May 24, 2026

Inactive-Account Cleanup + Token Hygiene

Added

  • Inactivity lifecycle: a daily cron (/api/cron/inactive-cleanup) warns accounts inactive for 6 months by email that they will be deleted in 14 days, then deletes them (and their data) if still inactive after the grace period. Returning users are spared automatically — /api/profile bumps last_seen_at and clears the warning on any authenticated load. New profiles.last_seen_at + inactive_warned_at columns (migration 0001, with backfill so existing users start fresh).
  • Token hygiene: the same cron purges expired session and verification rows (spent auth artifacts, no email) to keep the database lean.

Improved

  • New email templates inactiveWarningEmail + inactiveDeletedEmail; deletion is always preceded by a warning email (the warning timestamp is only stamped once the email actually sends).
v1.28.0May 24, 2026

Resumes Stay in Your Browser — Cloud Sync Disabled

Improved

  • Disabled all server-side resume storage to match our privacy promise: deleted the cloud-sync API, the useCloudSync hook, and the builder sync indicator. The resumes table is kept in the schema but is now dormant — nothing reads or writes it. Your resume lives only in your browser; Neon stores only login details (Better Auth tables) and profile data.
  • Reset-password + change-password flows fixed (correct Better Auth endpoints, new /reset-password page, current-password field) and email failures now log their reason server-side.
  • Resume-reminder cron reframed to a gentle new-user nudge (signup age + opt-out consent) since resume state is no longer visible server-side.
v1.27.0May 24, 2026

Email System Hardening (code-review fixes)

Added

  • Password-changed security alert now also fires when a logged-in user changes their password (Better Auth request-lifecycle hooks.after on /change-password), not just on the forgot-password reset flow.
  • lib/apiAuth.ts requireCronAuth(): constant-time (timingSafeEqual) bearer check shared by /api/admin/broadcast and both cron routes, replacing per-route string comparisons.

Improved

  • Unsubscribe is now two-step to defeat email link-prefetchers/security scanners that auto-follow GET links: GET renders a confirmation page (no mutation), POST performs the opt-out. Marketing email carries List-Unsubscribe + List-Unsubscribe-Post (RFC 8058 one-click) headers.
  • Resume-reminder consent switched to opt-OUT (sends unless notifyProduct is explicitly false) so lifecycle nudges actually reach new users; bulk product-update broadcasts stay strict opt-in. Every such email still carries an unsubscribe link.
  • Welcome email no longer doubles up with the verification email: credential signups are welcomed after they verify (afterEmailVerification); social signups (pre-verified) are welcomed at creation.
  • Lead APIs (/api/leads/contact + waitlist) no longer leak raw DB/driver error strings to clients — generic message returned, details logged server-side.
  • Bulk send routes set maxDuration=60 and escape all interpolated text in the unsubscribe page.
v1.26.0May 23, 2026

Full Transactional + Lifecycle Email System

Added

  • Shared email module: lib/emails/layout.ts (one branded, responsive HTML wrapper) + lib/emails/templates.ts (pure {subject, html} builders) for welcome, email verification, password reset, password-changed alert, email-change confirmation, account-deleted, contact-notify, product-update, and resume-reminder. All sent through lib/email.ts sendEmail() which no-ops without RESEND_API_KEY and never throws.
  • Email verification on signup via Better Auth emailVerification.sendVerificationEmail (sendOnSignUp, autoSignInAfterVerification). Non-blocking — verification is not required to sign in. Social signups arrive pre-verified and are skipped.
  • Account lifecycle emails: password-changed security alert (onPasswordReset), change-email confirmation to the current address (user.changeEmail), and an account-deleted confirmation (user.deleteUser.afterDelete). Enabling deleteUser also repairs auth.api.deleteUser used by /api/account/delete.
  • Product-update broadcasts: POST /api/admin/broadcast (CRON_SECRET-gated) emails everyone with profiles.notifyProduct = true, batched, each with a one-click unsubscribe link. Supports dryRun.
  • Engagement nudge: GET /api/cron/resume-reminders (daily Vercel Cron) emails users who signed up 2-3 days ago but have no saved resume, respecting product-update consent. The signup-age window means each user is reminded at most once with no extra schema.
  • Stateless unsubscribe: lib/emailTokens.ts HMAC tokens + GET /api/email/unsubscribe flips notifyProduct off with no DB-stored token. New env vars CRON_SECRET, WELCOME_FROM documented in .env.example.

Improved

  • AGENTS.md expanded into a real project guide: stack, the mandatory lint+tsc+build gate, env/deploy gotchas (pooled Neon URL, build-time NEXT_PUBLIC vars), and conventions for email graceful-degradation, lazy db/auth proxies, API hardening, and cron/admin auth.
v1.25.0May 23, 2026

Production Auth Fix + Transactional Email Re-wire + Lead API Hardening

Added

  • Welcome email re-implemented for the Better Auth stack. The old Supabase send-welcome Edge Function was removed in the migration, leaving new signups with no welcome mail; it now sends via a Better Auth databaseHooks.user.create.after Resend call. Best-effort and non-blocking — a slow or failed send can never break signup.
  • Contact-form submissions now notify the operator. /api/leads/contact emails CONTACT_NOTIFY_TO with the message (Reply-To set to the sender) instead of silently piling up in the contact_messages table. Skips cleanly when unset.
  • lib/email.ts shared Resend wrapper: a single sendEmail() helper that no-ops without RESEND_API_KEY and never throws, plus escapeHtml. Welcome, password-reset, and contact-notify paths all route through it.

Improved

  • Production Google OAuth fixed: switched DATABASE_URL to the Neon pooled (-pooler) connection string, resolving "fetch failed" on the verification insert during the OAuth callback under serverless concurrency. README + .env.example now document the pooled-string requirement and the build-time nature of NEXT_PUBLIC_SITE_URL.
  • Lead API hardening: /api/leads/contact and /api/leads/waitlist now enforce server-side length caps, email-format validation, safe JSON parsing, and per-IP rate limiting (contact 5/hr, waitlist 10/hr) — the API no longer trusts client-side trimming alone.
v1.22.1May 5, 2026

Crawlability Hardening + Schema Cleanup + Docs Sync

Improved

  • Crawl/indexing hardening: /blog filter chips and pagination now render as real links instead of JS-only buttons; sitemap.ts no longer emits duplicate blog filter query URLs; static entries use stable lastModified dates instead of request-time churn; /login, /forgot-password, and /account now ship server-rendered noindex metadata; robots.ts explicitly disallows /auth callback paths; app/not-found.tsx now searches only published posts so scheduled slugs never leak through the 404 helper.
  • Structured-data cleanup: faqPageSchema() now trims whitespace and drops empty question/answer pairs before emitting JSON-LD, preventing Search Console "Unnamed item" rich-result errors. HowTo step names/text and breadcrumb labels now receive the same normalization.
  • Docs synced with the current codebase: README now documents the real NEXT_PUBLIC_SITE_URL fallback (https://resumebuildz.tech) and the actual Husky hook flow (pre-commit no-op, pre-push runs lint + tsc + build). CHANGELOG.md and lib/changelogData.ts now match the shipped crawl/indexing work.
v1.22.0April 19, 2026

Full SEO migration, mobile fixes, security hardening, Edge Functions live

Added

  • lib/blogSeo.ts central SEO registry holding per-post title, description, category, FAQs. One source of truth for 19 blog posts.
  • /author/surya-l bio page with Person JSON-LD schema (sameAs GitHub + LinkedIn). DEFAULT_AUTHOR in articleSchema.ts now points at this page, lifting E-E-A-T across every Article schema in one edit.
  • lib/lazyStripe.ts DRY helper replacing 16 lines of duplicated lazy Stripe SDK loading in /api/checkout and /api/stripe/webhook.
  • BLOG_PLAN_V2.html reference doc: 50 queued blog topics in 6 clusters with per-post SEO fields, priority-ordered. Total search volume ~740k/month.
  • .claude/SKILLS_CATALOG.md routing reference (gitignored) mapping 38 top-level skills + 100+ sub-skills to keyword triggers.

Improved

  • SEO migration across all 29 public pages (19 blog + 10 non-blog). Pre-migration every use-client page served the root layout title to Google because document.title was set in useEffect. Each page split into server page.tsx (metadata + JSON-LD) + Content.tsx (use-client body). Per-page-type schemas: Article + FAQPage + BreadcrumbList for blog posts, SoftwareApplication for /builder, Product + Offer for /pricing, CollectionPage for /templates and hubs, Organization for /about, ContactPage for /contact.
  • BlogPostLayout mobile fix: collapsible mobile TOC (was display:none below lg), responsive H1 text-2xl sm:text-3xl md:text-4xl, centred article column on mobile, min-w-0 overflow guard, Prev/Next stacks on narrow phones.
  • Husky reconfig: pre-commit is now a no-op; lint + tsc + build consolidated in pre-push. Fast commits, single gate at push.
  • Contact form hardening: maxLength caps on every input, hidden honeypot, client-side sessionStorage rate limit (3 per 5 min), server-side slice caps, email regex, 10-char minimum message.
  • XSS defence in depth: homepage FAQ JSON-LD swapped from raw JSON.stringify to jsonLd() helper (escapes < to \u003c). sanitizeCSS extended to strip @import, @charset, data:text/html, quoted javascript:/vbscript:, -moz-binding, behavior:
  • All 3 Supabase Edge Functions deployed and ACTIVE: delete-user, increment-usage, send-welcome. Mis-named resend-email removed and redeployed under canonical send-welcome slug so the welcome trigger SQL resolves correctly.
  • Supabase RLS verified on contact_messages (INSERT only, no SELECT/UPDATE/DELETE) and profiles (SELECT/INSERT/UPDATE gated on auth.uid() = id, no DELETE).
v1.21.0April 19, 2026

BLOG_PLAN v1: 10 SEO Posts + 10 Role Pages + Sentry + Analytics + Husky

Added

  • 10 SEO-optimised blog posts covering combined ~323k/mo search volume: pass-ats-resume-scanning, resume-action-verbs (210 verbs by role), resume-length, resume-summary-examples (25 before/after), resume-format-guide, quantify-resume-achievements (XYZ formula + 50+ bullets), cover-letter-vs-resume, tailor-resume, best-free-resume-builder, ai-resume-builders-tested. Each follows BLOG_PLAN uniform structure: 40-60 word featured-snippet answer, H2-heavy outline, PAA-harvested FAQ accordion, 5 related cross-links, mid + final CTAs.
  • 10 programmatic role-based resume guides at /resume/[role] via generateStaticParams over lib/resumeRoleData.ts: software-engineer, data-scientist, product-manager, ui-ux-designer, digital-marketer, full-stack-developer, devops-engineer, business-analyst, cybersecurity-analyst, machine-learning-engineer. Hand-written, India + global aware. Hub at /resume groups by category.
  • Sentry error monitoring (dormant, DSN-gated). @sentry/nextjs wired via instrumentation.ts (server + edge), instrumentation-client.ts (browser), and app/global-error.tsx. Zero traffic until NEXT_PUBLIC_SENTRY_DSN is set.
  • Typed analytics events in lib/analytics.ts wrapping @vercel/analytics with a compile-checked event-name union. Wired at 5 sites: signup, login, ai_rewrite_used, upgrade_modal_opened, resume_exported.
  • Husky pre-commit + pre-push hooks enforce the mandatory checklist. Pre-commit runs lint + tsc --noEmit; pre-push runs the full next build.

Improved

  • /about gains "Our principles" (5 commitments) and "What makes us different" (honest comparison table vs Zety, Resume.io, Canva).
  • /ats-guide gains 4 deep-dive sections: parser step-by-step, per-system tuning (Workday, Greenhouse, Lever, iCIMS, Taleo, SmartRecruiters), manual testing workflow, 7-question FAQ.
  • /cover-letter gains 5 new sections: complete 266-word example with annotations, length rules, email body vs attached, 8 explained mistakes, 8-question FAQ.
  • /resume-tips gains 4 sections: filename + format rules, length discipline cut-test, 4-step proofreading, 8-question FAQ.
  • /faq expanded from 17 to 26 questions; FAQPage JSON-LD now auto-generates from the full array (was hardcoded to 6).
v1.20.1April 19, 2026

Welcome Email Pipeline + Lighthouse Accessibility 100

Added

  • Welcome email pipeline: send-welcome Supabase Edge Function posts branded HTML to Resend, gated by a shared-secret bearer. A Postgres trigger on auth.users fires it exactly once on email confirmation via pg_net.http_post, so the confirmation flow is never blocked by Resend latency. Dormant until domain verification and secrets are set.
  • RESEND_SETUP.html: standalone, offline-friendly setup guide covering Resend signup, Namecheap DNS (MX, SPF, DKIM, DMARC) with the "send" subdomain gotcha, Supabase SMTP config, SQL trigger wiring, and a 7-point end-to-end smoke test.
  • /account added to robots.ts disallow list so private settings pages never surface in search.

Improved

  • Lighthouse Accessibility 91 mobile / 95 desktop to 100 / 100. Fixed heading-order skips across pricing, changelog, templates, blog/company-guides, builder, and footer. Bumped footer body text, CTA, and placeholder from gray-400/500 to gray-300/400 for AA-compliant contrast on the near-black gradient. Added aria-label to the hero "[1]" citation link so screen readers announce the source.
  • supabase/README.md: removed the outdated SUPABASE_SERVICE_ROLE_KEY secrets-set step (reserved prefix, auto-injected into every deployed function). Documented the new send-welcome deploy and trigger wiring.
  • .gitignore: ignore .claude/ and supabase/.temp/ tooling state (never meant for commit).
v1.20.0April 18, 2026

Account Settings: Tabbed /account Page + Extended Profile Schema

Added

  • /account tabbed settings page with seven sections: Profile (avatar upload via Supabase Storage, 2MB cap, JPG/PNG/WebP), Job Search (target role, seniority, industry, locations, open-to-work), Builder Defaults (template, font, accent colour, language, mask-phone toggle), Links (LinkedIn/GitHub/portfolio, https-only), Notifications (ATS tips, product updates), Security (password change, TOTP 2FA enrol/verify/remove, Google connection, sign-out-everywhere), Billing (read-only plan, invoice email).
  • lib/accountUpdate.ts field-whitelisted updateProfile helper so forms cannot smuggle extra columns.
  • lib/accountSchema.ts Zod validators for every form with length caps and URL/hex/email checks.
  • docs/SUPABASE_ACCOUNT_SCHEMA.md migration doc: idempotent SQL for new columns, RLS policies, and owner-only avatars storage bucket.
  • Each /account tab is a separate file under components/account/ lazy-loaded via next/dynamic so Turbopack compiles on demand.

Improved

  • Navbar profile dropdown: "Manage Plan" to "Account Settings" pointing at /account. Upgrade and Reset Password preserved.
  • Profile type in hooks/useAuth.ts extended with 21 nullable fields matching the new schema; .select('*') so all fields hydrate on load.
v1.19.2April 17, 2026

Navbar + Footer Redesign — Notion White + Newsletter Takeover

Added

  • Newsletter subscribe form in footer with live email validation (green/red border on input).
  • Sitemap link added to footer Legal column + bottom nav bar so users can find the site map without hunting.

Improved

  • Navbar: inverted from dark gray-900 to clean white (Notion-style), blue-500 logo chip, blue hover states, blue-500 "Get started free" CTA. Mega-dropdown (4 blog clusters + Help footer), auth profile menu, mobile menu all preserved.
  • Footer: dark from-gray-900 via-slate-900 to-black gradient matches existing homepage hero for visual continuity. Blue-400→blue-600 gradient headline. 4-column link grid (Product, Resources, Company, Legal).
  • Supabase guest-mode stub extended with .maybeSingle, .upsert, .insert, .update — covers every call path in useCloudSync so guest-mode boot is fully defensive.
  • Auth pages (/login, /forgot-password) added to robots.ts disallow so they don't outrank product pages on brand queries.
  • Removed internal design-selection preview pages (/design-previews, /preview-final) — were accidentally shipping to production builds.
v1.19.1April 16, 2026

Stability Fixes — Guest-Mode Boot, Script Tag, Lint Clean

Added

  • Typed env accessors (lib/env.ts) replace process.env.FOO! non-null assertions with lazy getters that throw clear "Missing required env var" errors at access time.
  • Auth error normalization (lib/authErrors.ts) — raw Supabase messages never reflected into URL params or UI; all errors pass through stable codes with friendly labels.

Improved

  • Guest-mode boot: Supabase client + server + proxy + auth callback now detect missing NEXT_PUBLIC_SUPABASE_* env vars and fall back to a no-op stub instead of crashing on first render.
  • Dark-mode init script moved from next/script (body child) to plain inline <script> in <head> — kills React "script tag while rendering component" warning in Next 16 while still running before hydration.
  • Lint clean: 3 set-state-in-effect errors suppressed with targeted per-line disables + comments; 16 warnings resolved (unused imports, stale eslint-disable directives, dead hook calls).
  • Canonical URLs corrected: siteConfig fallback now resume-forge-orcin.vercel.app (the actual Vercel project URL); all GitHub references fixed to Surya8991/ResumeBuildz (proper casing). Affects sitemap, JSON-LD, footer, and README.
v1.19.0April 16, 2026

Security Hardening — 10 Cybersecurity Fixes

Added

  • Content-Security-Policy header with frame-ancestors none, strict default-src, allowlisted connect-src.
  • In-memory rate limiter (lib/rateLimit.ts) — 10 sessions/hour/IP on /api/checkout.
  • CSRF defense: Origin verification on /api/checkout rejects cross-origin POSTs.
  • Photo upload magic-byte validation (lib/imageMagic.ts) — MIME spoofing no longer accepted.
  • maxLength support in RichTextarea + 2000-char cap on summary.
  • Referrer-Policy: no-referrer on /r/* share pages.
  • Stripe webhook signature stub with 4 event-type routing at /api/stripe/webhook.
  • BYOK security warning banner in AI tab (XSS/extension risk + rotation guidance).
  • Production-safe logger (lib/logger.ts) scrubs password/token/secret/api_key/auth/cookie keys.

Improved

  • Narrowed Supabase proxy matcher to /builder, /auth/*, /api/*, /login, /pricing. Marketing pages no longer hit auth refresh.
  • Added Cross-Origin-Opener-Policy + Cross-Origin-Resource-Policy headers.
  • /pdfjs/ worker served with correct Content-Type and 1-year immutable cache.
  • useAuth, useCloudSync, proxy, webhook handler all use logger instead of console.
v1.18.0April 16, 2026

8 Roadmap Features: LinkedIn Import, Versions, Share, JD Tailor, Diff, Tones, Trend

Added

  • PDF.js worker bundled locally — PDF import now works behind corporate firewalls that block unpkg CDN.
  • LinkedIn JSON import — auto-detects LinkedIn Data Export, Voyager API, and JSON Resume formats.
  • Resume version history — up to 30 named snapshots, auto-save hourly, one-click restore with pre-restore backup.
  • Shareable read-only link /r#<payload> — gzip+base64url encoded, zero backend, no PII leaves the browser.
  • JD-tailored rewrite in AI tab — paste JD, AI rewrites summary + top bullets with side-by-side diff preview.
  • Resume diff viewer — word-level LCS diff, inline or side-by-side rendering.
  • Cover letter tone variants — Professional, Formal, Casual, Concise with per-tone temperature tuning.
  • ATS score trend — SVG sparkline of score history with debounced snapshots.

Improved

  • Toolbar gains LinkedIn, Versions, and Share buttons (desktop).
  • New shared libs: shareLink.ts, diffText.ts, atsTrend.ts, versionHistory.ts, importLinkedIn.ts.
  • JD tailor and LinkedIn import both auto-snapshot to version history before applying.
v1.17.0April 16, 2026

Feature Shipping: Markdown/Text Export, Streaming AI, Shortcuts, RSS

Added

  • Markdown export (.md) — dev-friendly, GitHub-renderable resume dumps.
  • ATS plain-text export (.txt) — pure UTF-8 for Workday/Greenhouse/Naukri paste boxes.
  • Streaming AI: streamGroqAI() with SSE parser. Cover letter now streams live instead of 3-5s blank wait.
  • Keyboard shortcut cheatsheet dialog (Ctrl+/ or ?). Shows all 11 shortcuts grouped by category.
  • Last-edited timestamp in builder footer ("Saved 2m ago"). Auto-refreshes every 30s.
  • 404 page with live search across all pages, blog posts, and company guides.
  • ShareButton component on blog posts — copy link + LinkedIn/X/email intents.
  • Changelog RSS feed at /changelog/rss.xml for power users.
  • Status page at /status (service health dashboard).
  • Roadmap page at /roadmap (public feature tracker).
  • Sitemap auto-discovers blog posts from lib/blogPosts.ts registry.
  • Dark mode now persists across sessions via localStorage and init-before-paint script.

Improved

  • Removed duplicate Ctrl+E shortcut (previously bound to the same PDF export as Ctrl+P).
  • Footer shortcut hint ("⌨ Shortcuts") for discoverability on desktop.
  • Changelog data extracted to lib/changelogData.ts as single source for page + RSS.
v1.16.0April 16, 2026

Full-Project Codereview — 40+ Findings Fixed

Added

  • safePhotoSrc(): rejects remote photo URLs — only data:image/* allowed. Wired into ResumePreview for all 20 templates.
  • safePrimaryColor(): validates hex format before CSS interpolation. Wired into ResumePreview.
  • ensureUrl() blocks javascript:, data:, and vbscript: URI schemes.

Improved

  • Security: callGroqAI wrapped in try/catch/finally in ATSScoreChecker, AISuggestions, and CoverLetterForm. No more permanent loading on network failure.
  • Security: fetchProfile uses explicit select() instead of select(*), logs errors. exportUserData picks only safe fields.
  • Bugs: SectionReorder indexOf guard, .doc import clear error, AI JSON schema validation, DateConsistency null check.
  • Bugs: InfographicTemplate deterministic skill bars, ModernTemplate custom sections, exportDocx/Html empty date handling.
  • Bugs: PasteImportModal 100k limit enforced, MultiJDMatching collision-safe IDs, BoldTemplate "to" → "-", MonochromeTemplate empty proficiency.
  • UX: deleteProfile + ErrorBoundary require confirm(). Toast ARIA live region. Contact form honest success text.
  • Cleanup: Removed dead SiteNavbar branch, redundant preconnect links. localStorage try/catch in WhatsNew + OnboardingGuide.
  • siteConfig.ts fallback URL updated to resumebuildz.vercel.app.
v1.15.1April 16, 2026

Codereview Pass #2 — 13 Findings Fixed

Improved

  • Groq AI: GROQ_MODEL + fetch logic consolidated into single callGroqAI() helper. Removed 3 duplicate declarations and 3 duplicate fetch implementations (AISuggestions, CoverLetterForm, importResume).
  • callGroqAI() now returns HTTP status on errors (for granular 401/429/402 handling) and accepts optional apiKey override.
  • ResumePreview: overrideCSS sanitized via sanitizeCSS() that strips <script>, expression(), and url(javascript:) patterns.
  • Clipboard: navigator.clipboard.writeText() wrapped in try/catch in AISuggestions and CoverLetterForm.
  • /hero-preview and /loader-preview: noindex,nofollow now server-rendered via Next.js layout.tsx metadata. Removed client-side useEffect injection.
  • LoaderCard: accepts size prop (sm/md). Loader7_BottomRightCard reuses shared component instead of duplicating markup.
  • hero-preview: familyLabel correctly shows "Combined" with amber badge for combined-family options.
  • Loader10_SparkleCursor: documented pointer-events constraint for production contexts.
v1.15.0April 16, 2026

PageLoader Hardening (Codereview Pass)

Added

  • Shared LoaderCard component used by both production PageLoader and the loader preview gallery (single source of truth for brand visuals).

Improved

  • PageLoader: 8-second safety timeout auto-hides the loader if a navigation never completes. No more stuck overlays.
  • PageLoader: respects prefers-reduced-motion via motion-safe: / motion-reduce: Tailwind variants.
  • PageLoader: SVG <a> elements now type-guarded with instanceof check.
  • PageLoader: relative URLs resolved correctly via new URL(href, location.href).
  • PageLoader: aria-live="polite" + visually-hidden announcement for screen readers.
  • PageLoaderOptions: all <style jsx> keyframes extracted to globals.css with loader- prefixed names to avoid collisions.
  • PageLoaderOptions: Loader4_SkeletonCard now imports shared LoaderCard.
  • /loader-preview and /hero-preview now noindex,nofollow with robots.txt disallow as defense-in-depth.
v1.14.0April 15, 2026

Centered Skeleton Card Page Loader + Loader Preview

Added

  • /loader-preview gallery with 10 page-loader animation options (Stripe, Vercel, Spotify, Apple, GitHub, Linear, Notion, Material Design inspirations).

Improved

  • Page loader replaced with the centered skeleton card design (Option 4). Mirrors the homepage Fill7_Ultimate hero aesthetic so every page transition reinforces the resume-building brand metaphor.
  • Top progress bar removed entirely. The new loader is a centered card on a soft white backdrop with skeletal resume bars filling in.
  • 150ms grace period before the loader shows — quick navigations that complete in under 150ms never flash the loader.
v1.13.0April 15, 2026

Page Loader + Codereview Cleanup

Added

  • Global page transition loader (PageLoader.tsx) wired into the root layout.
  • Top blue gradient progress bar that trickles during navigation and snaps to 100% on completion.
  • Floating mini "resume building" card in the bottom-right with skeletal bars filling in (matches the homepage hero aesthetic).
  • Detects navigation start via global click listener on <a> elements; responds to browser back/forward via popstate; completes via usePathname.

Improved

  • All 16 issues from the codereview pass fixed: WhatsNew APP_VERSION bumped to 1.12.0, ESLint enforcement moved to CI, setState-in-effect warnings resolved on login + CookieBanner + WhatsNew, hardcoded Vercel URL centralized via lib/siteConfig.ts (9 replacements), JSON-LD blocks consolidated via jsonLd() helper, unused SUPABASE_SERVICE_ROLE_KEY removed, MonochromeTemplate dead code removed, Fill4 type cast cleaned up, Fill7_Ultimate now pauses animations offscreen via IntersectionObserver, eslint-config silences <img> warnings for resume templates.
  • Lint result: 0 errors, 13 warnings (down from 5 errors / 35 warnings).
v1.12.0April 15, 2026

Ahrefs-style Blog Taxonomy + Mega-dropdown

Added

  • Ahrefs-style 2-tier blog taxonomy: 4 parent groups (Resume & ATS, Job Search, India Hiring, Company Guides) containing 7 child clusters.
  • New "Interviews & Cover Letters" category — closes the biggest content gap vs. every direct resume/career competitor.
  • Cover Letter page added as a blog post in the new Interviews & Cover Letters cluster.
  • PARENT_GROUPS array + parentGroup field in lib/blogCategories.ts with getCategoriesByParent helper.
  • Mega-dropdown in the Resources navbar menu: 4-column grid on desktop, nested accordion on mobile.
  • Parent-grouped blog hub at /blog showing categories under 4 pillar headers instead of a flat grid.

Improved

  • Footer Blog column restructured into 3 visual groups matching the new parent taxonomy.
  • Research-backed structure: HubSpot, Ahrefs, Indeed, Zety, Enhancv, Kickresume, Teal, LinkedIn Talent, Canva, Notion all studied. Ahrefs nested model picked as the only scalable approach for 7+ clusters.
v1.11.0April 15, 2026

Project Renamed to ResumeBuildz + Navbar Restructure

Added

  • Navbar Resources dropdown restructured with two nested sections: "Blog — topic clusters" (6 clusters) and "Help" (FAQ + Company Guides Hub).
  • Blog column added to the footer (All Articles + 4 cluster pages + FAQ).

Improved

  • Main nav simplified: Templates, Resources, About, Pricing, Contact. FAQ moved out of top-level nav into the Resources dropdown and the footer.
  • Brand renamed from ResumeForge to ResumeBuildz across 43 files.
  • package.json name changed from "resumeforge" to "resumebuildz".
v1.10.0April 15, 2026

Blog Section with Topic Clusters + Ultimate Hero

Added

  • Blog hub at /blog with featured strip, topic-cluster cards, and filterable post grid.
  • Dynamic /blog/category/[category] route with 6 topic clusters.
  • Ultimate hero on the homepage (Fill7_Ultimate) with 3D parallax tilt.
  • Sitemap expanded with /blog + 6 category URLs.

Improved

  • Resources dropdown in navbar now points to blog categories instead of flat page links.
v1.9.0April 15, 2026

Article Scaffolding, Deep Content & Hero Preview Gallery

Added

  • Sticky TOC (desktop sidebar + mobile accordion) on all 28 long-form pages.
  • Breadcrumbs + JSON-LD BreadcrumbList schema on every content page.
  • JSON-LD Article + FAQPage + HowTo schemas for rich Google results.
  • Scroll progress bar and back-to-top button (scoped to long-form pages only).

Improved

  • Sitemap covers all new URLs. Homepage now has lower visual noise at rest.
v1.8.0April 14, 2026

SEO Expansion: 22 Company Guides + 6 Situation Pages

Added

  • Company resume guides hub at /resume-for with 22 curated employers (10 global + 12 India).
  • Dynamic /resume-for/[company] route with 22 statically generated pages.
  • 6 situation-specific pages: fresher, campus placement, Naukri tips, post-layoff, career gap, career change.
  • Resources dropdown in navbar exposing all 9 new resource pages.

Improved

  • SiteNavbar layout: Templates link is now the first item, followed by a Resources dropdown.
v1.7.0April 14, 2026

Analytics, Privacy Compliance & Page Review

Added

  • Vercel Web Analytics (cookieless, GDPR-safe, free on Hobby plan).
  • Login Gateway expanded to all builder CTAs across all pages.
  • Paste Import workflow for LinkedIn or any plain text resume.
  • Cookie consent banner (GDPR safety net).

Improved

  • Privacy Policy rewritten for accuracy.
  • About page mission statement, stats, and tech stack updated.
v1.6.0April 14, 2026

Undo/Redo, Shortcuts & Polish

Added

  • Undo/Redo system with 50-snapshot history.
  • Keyboard shortcuts: Ctrl+E for PDF export, Ctrl+1-5 to jump tabs.
  • Login Gateway modal on Build Resume CTAs.
  • Email verification banner in builder for unverified users.

Improved

  • Debounced localStorage writes (1s) reduce battery drain on mobile.
  • React.memo on ResumePreview prevents re-renders on every keystroke.
v1.5.0April 13, 2026

Auth, Pricing & Pro Plans

Added

  • Supabase authentication with Google OAuth and email/password sign-in.
  • Pricing page with 5 tiers: Free, Starter ($5), Pro ($9), Team ($19), Lifetime ($49).
  • Freemium gates: 1 AI rewrite/day and 3 PDF exports/day on free tier.
  • Toast notification system.
  • GDPR controls: Export My Data and Delete Account.

Improved

  • Email verification now required for Pro features.
  • SEO: dynamic robots.ts, sitemap.ts, OG image, and Organization schema.
v1.4.0April 11, 2026

Skill Suggestions, Auth & Pricing

Added

  • Skill suggestions based on your job title. 201 roles across 20 industries.
  • Section completion dots.
  • Cover letter auto-fills your job title.

Improved

  • Improved skill matching accuracy.
v1.3.0March 28, 2026

PDF Import & Multi-Profile Support

Added

  • PDF import via pdfjs-dist.
  • Multiple resume profiles — save up to 10 different versions.
  • Template preview modal.
  • Drag-and-drop reordering for Experience, Education, Projects.

Improved

  • Better print quality across all 20 templates.
v1.2.0March 14, 2026

UI Modernization

Improved

  • Redesigned help dialog with icons and cards.
  • Improved onboarding flow with progress bar.
  • Updated documentation.
v1.1.0February 22, 2026

ATS Tools & AI Gap Analysis

Added

  • 12 ATS analysis tools.
  • Industry keyword database: 20 industries, 201 roles.
  • AI Gap Analysis — paste JD, see missing skills.
  • Clickable contact links in all 20 templates.

Improved

  • Navbar redesign with better navigation.
v1.0.0February 1, 2026

Initial Release

Added

  • 20 professionally designed ATS-optimized resume templates.
  • AI writing assistant powered by Groq.
  • Cover letter builder.
  • ATS score checker with JD keyword matching.
  • Multi-format import (DOCX, TXT, HTML, MD) and export (PDF, DOCX, HTML).
  • Dark mode. PWA support. 100% client-side.