Release History

Changelog

What's been built, how it was solved, and why it matters — written for developers and clients equally.

LaunchFeatureInfrastructureSecurityFix
v1.5.0LatestFeature

Metrics Dashboard, Animated Blog Components & Auto-Refresh

Live YouTube metrics with animated dashboard visualizations, scroll-triggered components, daily cron refresh, and a new showcase blog post proving the pipeline works.

What shipped

YouTube metrics auto-refresh with Blob caching

Video statistics (views, likes, comments) are now cached in Vercel Blob and refreshed automatically. Two refresh paths:

  • Cron job — runs daily at 06:00 UTC via /api/cron/refresh-metrics, fetching public statistics using a YouTube API key
  • Admin visit — live OAuth fetch on every dashboard load, with results cached for the cron fallback

The metrics dashboard now shows a "Last updated" timestamp and a manual Refresh button.

Animated blog components

Four new client-side components for visually rich blog posts:

  • DashboardShowcase — animated recreation of the YouTube metrics dashboard with count-up animations, gradient border, macOS window chrome, and staggered reveal
  • PipelineFlow — 5-step content pipeline visualization (horizontal on desktop, vertical on mobile) with animated gradient connection line
  • ImpactGrid / ImpactMetric — scroll-triggered counting stat cards with glow effects and color-coded borders

All components use IntersectionObserver for reveal-on-scroll and requestAnimationFrame for smooth counting animations.

Admin-only feature gating

YouTube publish buttons, newsletter notifications, and LinkedIn copy are now visible only when the admin is authenticated. Public users see article video links but not publishing controls.

Interactive 3D architecture visualization

A React Three Fiber scene renders the full js17.dev architecture — 17 provider nodes with orbital rings, connection lines, cost labels, and auto-rotating camera. Embedded in the blog via dynamic import with ssr: false.

New blog post: "The Machine That Builds Itself"

A showcase post demonstrating the full pipeline with real YouTube metrics data, animated dashboard, pipeline flow visualization, impact stats, and the 3D architecture scene — the most visually rich entry on the site.

Public article video links

Blog readers can now see YouTube Short and Long video links on published articles, even without authentication.

What this means for you as a client

YouTube video performance is now tracked automatically with a live metrics dashboard showing views, likes, and comments across all published videos. Metrics refresh daily via cron and on every admin visit. A new blog post demonstrates the full content pipeline with animated visualizations — proof of capability for prospective clients.

Developer notes▼ expand

Metrics are cached in Vercel Blob (youtube/metrics-cache.json) and refreshed via /api/cron/refresh-metrics using a YouTube API key for public statistics. The admin dashboard fetches live via OAuth and updates the cache, falling back to cache on failure. New client components (DashboardShowcase, PipelineFlow, ImpactGrid, ImpactMetric) use IntersectionObserver for scroll-triggered reveal and useAnimatedValue for count-up animations. MDX passes numeric props as strings — ImpactMetric coerces with Number(). Vercel Hobby cron runs daily at 06:00 UTC.

Skills demonstrated

YouTube Data API v3 statisticsVercel Cron JobsIntersectionObserver animationsVercel Blob cachingReact Three Fiber (3D architecture)MDX custom component system
v1.4.0Feature

YouTube Publishing Pipeline & Newsletter Intelligence

Every blog post can now become a narrated video on YouTube — generated, composed, and uploaded without leaving the admin panel.

What shipped

AI-powered YouTube video publishing

Every blog post now has a "Publish to YouTube" button visible to the admin. One click triggers the full pipeline: GPT-4o generates a narration script tailored to the article, OpenAI TTS converts it to audio (onyx voice), Shotstack composes a video with custom slides, and the result uploads directly to YouTube — all server-side, no manual editing required.

Two formats are supported per article: Short (1080x1920, vertical, under 60 seconds) and Long (1280x720, horizontal, full narration). Each format tracks its own YouTube URL to prevent duplicate uploads.

Brand video management page

A dedicated admin page at /admin/youtube manages brand-level videos (logo animations) in both short and long formats. Publishing status, YouTube URLs, and format metadata are all visible in one place.

Newsletter post notifications with AI synopsis

When a new blog post is published, the admin can notify all subscribers with a single click. GPT-4o-mini generates a concise synopsis of the article, which is embedded in a redesigned email template. Sent posts are tracked in Vercel Blob to prevent double-sends.

Newsletter email redesign

Both the welcome email and post notification emails received a visual overhaul — branded header, clean typography, prominent CTA buttons, and proper unsubscribe links compliant with RFC 8058 one-click unsubscribe.

OAuth token auto-refresh

Google OAuth access tokens (1-hour TTL) are now refreshed automatically in auth.ts using the stored refresh token. YouTube uploads no longer fail silently after 60 minutes of session time.

Admin auth hardening

All admin API routes now use verifyAdmin(req) with getToken from next-auth/jwt instead of getServerSession, which cannot read cookies reliably in Next.js 14 App Router route handlers. This fixed 401 errors on all admin endpoints.

Environment variable hygiene

All Vercel environment variables were re-added using printf '%s' to prevent trailing newline characters (%0A) that caused silent authentication failures with Google OAuth and the Shotstack API.

What this means for you as a client

Blog content now reaches audiences on YouTube automatically. Subscribers receive AI-summarized email notifications when new posts are published. The entire content distribution pipeline — from written article to narrated video to email blast — runs from a single admin interface.

Developer notes▼ expand

The video pipeline chains four API calls: GPT-4o generates a narration script from the article, OpenAI TTS (onyx voice) produces audio stored in Vercel Blob, Shotstack composes the video with slides rendered via a Next.js API route, and the final video uploads to YouTube server-side. Per-article tracking in Blob (youtube/article-videos.json) prevents duplicate publishing. OAuth token auto-refresh in auth.ts handles the 1-hour Google token expiry. All OpenAI/Shotstack clients are instantiated inside handlers (not module-level) to avoid build-time errors. The admin auth layer uses getToken from next-auth/jwt instead of getServerSession, which fails in App Router route handlers.

Skills demonstrated

GPT-4o script generationOpenAI TTS (onyx voice)Shotstack video composition APIYouTube Data API v3OAuth 2.0 token refreshVercel Blob storageServer-side video uploadAI-powered newsletter synopsis
v1.3.0Security

Security, Credentials & Quality Gates

Every proposal is now screened for abuse. Your certifications are live. The codebase has its first automated test suite.

What shipped

Scam & abuse detection on the proposal form

Hostile submissions — insults, spam, discriminatory content — are silently blocked before any email reaches the inbox. The filter runs three layers: keyword matching, an AI content policy check (OpenAI Moderation API, free endpoint), and an autonomous learning system that extracts new block-terms from flagged content and persists them to cloud storage for future fast-path blocking.

Admin moderation dashboard

A private dashboard at /admin/submissions shows every proposal ever submitted — clean and blocked alike — with detection source, categories flagged, confidence scores, and a submission excerpt. No personal data stored beyond what's needed for observability.

Certified credentials section

Your 10 verified badges from MongoDB, Google Cloud, Certiprof, and others now appear on the homepage, pulled live from the Credly API and cached for 24 hours. Each badge links back to the verified credential on credly.com.

Newsletter security hardening

The subscribe endpoint now validates that the email domain actually accepts mail (DNS MX check), rejects 20+ known disposable/throwaway providers (mailinator, guerrillamail, yopmail…), and enforces a per-IP rate limit of 2 subscriptions per hour — all without a third-party service.

Google OAuth fixed

Root cause: environment variable set with a trailing newline character (%0A), making Google's client lookup fail with invalid_client. Re-added all credentials using printf '%s' to prevent shell newline injection. Both production and sandbox now authenticate correctly.

Proposal flow integration tests

8 automated test cases run against the live API: valid submission, validation errors (short title, invalid email, empty currency, no price), silent moderation block, rate limit enforcement, and malformed JSON. Run with npm run test:proposal:sandbox or npm run test:proposal:prod.

What this means for you as a client

Your inbox is protected by a multi-layer content filter — hostile submissions are silently blocked before any email is sent. Verified credentials from MongoDB, Google Cloud, and Certiprof are now visible to anyone evaluating your profile.

Developer notes▼ expand

Moderation runs three layers: a hardcoded keyword blocklist (seeded from a real abuse case), a custom Vercel Blob blocklist that grows autonomously when OpenAI flags new patterns, and the OpenAI Moderation API as a final layer. The system fails open — if the API is unavailable, legitimate proposals still go through. The newsletter endpoint gained MX record DNS resolution to reject fake domains without any external API dependency.

Skills demonstrated

OpenAI Moderation APIDNS MX validationVercel Blob storageOAuth 2.0 debuggingCredly REST APIIntegration testingRate limiting
v1.2.0Feature

Brand Identity, Themes & Proposal UX

A real visual identity. Seven colour palettes. A proposal form that actually works end-to-end.

What shipped

Circuit tree logo & brand mark

A geometric circuit-tree SVG mark — monochromatic, currentColor, fully theme-adaptive. The icon appears in the header alongside the wordmark and in the footer as the full mark. One SVG responds correctly to every theme and dark/light mode without extra CSS.

Seven visual themes

Forest Node (default for first-time visitors), Circuit Dark, Circuit Light, Terminal Green, Plasma Purple, Titanium Gray, and Aurora. Each palette is a complete design token set — headings, code blocks, gradients, borders, and prose typography all adapt. Returning visitors get a random theme on each session.

Theme picker

A popover component with colour swatches, theme names, and descriptions. The active theme shows a live primary-colour dot on the trigger button. Replaces the plain dark/light toggle with something that expresses the breadth of the visual system.

Multi-step proposal form (5 steps)

Client info → Project details → Budget → Contact → Schedule. Each step validates independently with Zod before advancing. The budget step accepts both hourly and fixed-price inputs in USD and EUR, with a flexibility selector. Error messages are inline and field-level.

Cal.com discovery call scheduler (Step 5)

Embedded Cal.com calendar on the final step with loading skeleton, MutationObserver-based ready detection, and a fallback direct-booking link if the embed times out. The script preloads from step 3 to eliminate cold-start latency.

Web push notifications

Visitors can opt into push notifications for new blog posts. A service worker handles delivery. VAPID key pair configured for both production and sandbox environments.

Newsletter sign-up

Minimalist inline and banner variants on the blog index and per-article header. Subscribers stored in Vercel Blob with deduplication.

Prose readability on dark themes

Custom --tw-prose-* CSS variable overrides for every dark palette class, so article text, headings, links, and code blocks are readable regardless of which theme is active — not just the built-in .dark class that Tailwind Typography assumes.

What this means for you as a client

The site now has a distinctive brand that looks intentional across every device and theme. Potential clients can submit a detailed project proposal and book a discovery call — all in a single guided flow without leaving the page.

Developer notes▼ expand

The palette system uses CSS custom property blocks per theme class on <html>. Each palette defines 12 semantic tokens (background, foreground, primary, accent, gradient-from/to, etc.) — no Tailwind class changes needed when switching themes. The Cal.com embed has a MutationObserver-based ready detection (no native callback exists) with a 10s timeout fallback to a direct booking link. The preloader starts injecting the Cal script at step 3 so it's warm by step 5.

Skills demonstrated

Design systemsCSS custom propertiesNext.js App RouterCal.com embed APIMulti-step form patternsWeb Push APICloudinary CDNSVG icon systems
v1.1.0Infrastructure

YouTube Pipeline & DevOps Infrastructure

Blog posts can now become YouTube videos in one click. The codebase got branch protection, CI/CD, and conventional versioning — in 23 minutes.

What shipped

AI-powered blog-to-YouTube pipeline

Every blog post gets a "Publish to YouTube" button visible only to the admin. The pipeline:

  1. GPT-4o reads the post and writes a structured video script
  2. OpenAI TTS (onyx voice) narrates each section
  3. Shotstack composes the audio with animated slide visuals
  4. The finished video uploads directly to the YouTube channel via the Data API v3

All processing is server-side. The UI shows live progress with per-step status indicators.

Google OAuth with automatic token refresh

Admin authentication via Google OAuth 2.0. Access tokens (1-hour lifespan) are automatically refreshed using the stored refresh_token — no re-authentication required mid-session.

Branch protection & CI/CD (23 minutes)

Established via the GitHub REST API in a single directed session:

  • main branch requires PR + 3 passing CI checks + linear history + no force push
  • GitHub Actions CI: TypeScript type-check, ESLint, and Next.js build on every PR
  • GitHub Actions release: standard-version auto-bumps version + generates CHANGELOG on every merge to main
  • Conventional Commits enforced via commitlint + Husky pre-commit hook

Sandbox environment

A sandbox branch deploys automatically to sandbox.js17.dev on Vercel — a complete staging environment with its own env vars, domain, and deployment pipeline. All new features ship to sandbox first.

Security hardening

  • YouTube upload moved server-side (eliminated CORS vulnerability)
  • Proxy video route restricted to Shotstack CDN hostnames only (SSRF mitigation)
  • MDX CVE patch: upgraded next-mdx-remote to v6 (CVE-2026-0969)

What this means for you as a client

A single 'Publish to YouTube' button on any blog post triggers a full AI-powered video production pipeline: GPT-4o writes a script, OpenAI TTS narrates it in a professional voice, Shotstack renders slides with motion graphics, and the result uploads directly to YouTube. The entire DevOps foundation took 23 minutes to establish — the kind of velocity available when working with AI-augmented engineering.

Developer notes▼ expand

The YouTube upload is server-side via a Next.js API route — a critical fix from the original client-side approach which hit CORS blocks. The Shotstack job is polled via a /video-status/[jobId] route until complete. OAuth token refresh is handled in the NextAuth JWT callback: refresh_token stored on initial sign-in, auto-refreshed when accessTokenExpires is past. The SSRF vulnerability in the proxy-video route is mitigated by a Shotstack CDN hostname allowlist.

Skills demonstrated

YouTube Data API v3OpenAI GPT-4o + TTSShotstack video renderingGitHub Actions CI/CDBranch protection strategyOAuth 2.0 token refreshVercel Blob storageServer-side media pipeline
v1.0.0Launch

Platform Launch

js17.dev goes live — a full-stack personal command centre built with Next.js 14, AI-augmented from day one.

What shipped

Full-stack Next.js 14 site

Built on the App Router with a clear separation between server components (data fetching, OG images, GitHub stats), client components (animations, forms, theme), and edge functions (OG image rendering). TypeScript throughout — no any.

MDX blog engine

Author posts in Markdown + JSX. Frontmatter drives metadata, OG images, and the post list. Syntax highlighting via rehype-pretty-code. Reading time calculated automatically. Posts live in src/content/blog/ as .mdx files — no CMS, no database, no subscription.

Live GitHub activity

Contribution graph and repository stats fetched server-side from the GitHub API with a 1-hour ISR cache. Displays real commit history, language breakdown, and streak data — auto-updating without any manual maintenance.

Multi-step proposal form

A guided 5-step contact flow with per-step Zod validation, email delivery via Resend, and a confirmation email to the sender. Covers client info, project scope, budget expectations, contact preferences, and optional discovery call scheduling.

Dynamic OG images

Every page and every blog post generates a branded Open Graph image at request time using the Edge runtime — no image editing, no static files to maintain. Correct previews on Twitter, LinkedIn, Slack, and iMessage automatically.

Transactional email

Proposal submissions trigger two emails: a structured HTML brief to the inbox (with client info, project details, budget, contact, and notes) and a professional confirmation to the client with next steps. Powered by Resend with lazy initialization.

Performance & SEO baseline

  • Lighthouse score: 95+ across all pages
  • robots.txt and sitemap.xml generated at build time
  • Semantic HTML throughout
  • All images with explicit width/height to prevent CLS
  • Inter + JetBrains Mono loaded via next/font (zero layout shift)

What this means for you as a client

A production-grade personal site built to the same standards as client projects: typed end-to-end, server-rendered where it matters, static where it's fast, with email infrastructure, dynamic OG images, and a multi-step contact flow. Every component here is a real-world example of the quality you get when you hire this engineer.

Developer notes▼ expand

The MDX pipeline uses next-mdx-remote for dynamic compilation with gray-matter for frontmatter. GitHub stats use ISR with a 1-hour revalidation window against the GitHub REST API. Resend is lazily initialized at handler time (not module level) to avoid build-time errors when RESEND_API_KEY is absent. All OG images are Edge-runtime-rendered dynamically — no static PNG needed.

Skills demonstrated

Next.js 14 App RouterTypeScriptTailwind CSSMDX blog engineGitHub API integrationResend transactional emailZod validationFramer MotionEdge runtime

Want to see what gets built next? Follow along or start a project.