
Portfolio Jitin K
Portfolio d'ingénieur full-stack mettant en valeur architectures microservices, systèmes distribués et technologies web modernes.
Problème et solution
Concevoir une interface remarquable avec animations fluides, internationalisation intégrale et d'excellents scores Core Web Vitals.
Fonctionnalités
- Next.js App Router et next-intl avec 9 langues supportées
- Diagrammes d'architecture interactifs propulsés par React Flow
- Typographie cinétique et écran de chargement immersif
- API de contact sécurisée avec limitation de débit et envoi SMTP
- Visualiseur interactif de l'arborescence du projet
Stack technique
| Technologie | Version | Objectif | Pourquoi ce choix |
|---|---|---|---|
| Next.js | ^16.1.6 | App Router framework | Server Components, file-based routing, API routes, image optimization |
| React | ^19.2.4 | UI library | Server Components and concurrent rendering |
| TypeScript | ^5 | Type safety | Typed project content catches slug/data mismatches at compile time |
| Tailwind CSS | ^4 | Utility-first styling | CSS-first config with @theme/oklch tokens, no JS config file |
| Framer Motion | ^12 | Animations | Stagger/fade/hover primitives with useInView and useReducedMotion |
| @xyflow/react + dagre | ^12.11.5 / ^0.8.5 | Architecture diagrams | Data-driven interactive graphs with automatic layout |
| Nodemailer | ^7.0.11 | Contact email delivery | Simple Gmail SMTP transport from a single API route |
| @upstash/ratelimit + @vercel/kv | ^2.1.0 / ^3.0.0 | Distributed rate limiting | Shared sliding-window counter across serverless instances |
| Radix UI + shadcn/ui | primitives + copied source | Accessible UI primitives | Accessible tooltips/labels with full style control via copied components |
| Vercel | — | Hosting & analytics | Zero-config Next.js deploys, CDN, Web Analytics |
Architecture
App Router Pages
- Root layout (server): fonts, metadata, Providers, Navbar, Footer, hexagon background
- Home (server): composes Profile, Recent Projects (first 4), Techstack, About sections
- /projects (client): stagger-animated grid of all ProjectCards
- /projects/[slug] (server): joins projects[] + projectDetails[] by slug at request time
- /about, /contact (client) and styled not-found page
Component Layer
- components/projects/: Project, ProjectCard, ReactFlowDiagram, FolderTree, MermaidDiagram
- components/animation/: Framer Motion wrappers (stagger, fade-up, hover glow, border trail)
- components/pattern/: InteractiveHexagonBg (rAF-optimized SVG grid), CssPattern, AnimatedHero
- components/ui/: shadcn/ui primitives (Badge, Button, Input, Label, Textarea, Tooltip)
- components/terminal/: Terminal typing preview component
Data & API Layer
- lib/projects/*.ts: one file per project exporting ProjectType + ProjectDetailType
- lib/projects/index.ts: aggregates projects[] and projectDetails[] arrays
- lib/types.ts: TECH_ICONS registry, PROFILE_DATA, and all content type definitions
- POST /api/contact: server-side validation, rate limiting, Nodemailer → Gmail SMTP
Structure du projet
Points d'API
Portfolio API (port 3000)
| Méthode | Route | Objectif |
|---|---|---|
| POST | /api/contact | Validate contact form input, rate-limit by IP, send email via Gmail SMTP |
Décisions de conception clés
Static TypeScript Data Instead of CMS
Décision : Store all project content as typed constants in lib/projects/*.ts joined by slug
Pourquoi : Type safety, zero runtime fetch cost, no database or CMS dependency
Avantages : Compile-time checks, ships with bundle, server-renderable, free hosting footprint
Compromis : Content changes require code changes and redeployment
Server/Client Component Split
Décision : Detail pages and layout are server components; lists, diagrams, and forms are client components
Pourquoi : Minimize client JS while keeping interactive features
Avantages : Smaller bundle, faster first paint, SEO-friendly detail pages
Compromis : Mental overhead of the serialization boundary
Tailwind CSS v4 CSS-First Config
Décision : Configure theme via @theme directives in globals.css instead of tailwind.config.js
Pourquoi : Tailwind v4 removes the JS config in favor of CSS-native tokens
Avantages : One file for design tokens, oklch dark/light variables, simpler setup
Compromis : Different from v3 muscle memory
React Flow + Dagre for Diagrams
Décision : Derive architecture diagrams from data (nodes/edges) with Dagre auto-layout
Pourquoi : Diagrams stay consistent with content and render interactively
Avantages : No hand-drawn images, zoom/pan, themable, ER table nodes supported
Compromis : Client bundle cost on pages that render diagrams
Layered Contact API Protection
Décision : Validate + HTML-escape inputs, then rate-limit via Upstash sliding window with in-memory fallback
Pourquoi : Serverless instances don't share memory; shared KV store gives consistent limits
Avantages : XSS-safe output, 5 req/min/IP abuse protection, graceful degradation
Compromis : Requires KV env vars for full protection; no CSRF token yet
Gmail SMTP via Nodemailer
Décision : Send contact emails through an existing Gmail account
Pourquoi : Simplest delivery path for a personal portfolio with no backend infra
Avantages : One route handler, no third-party email SaaS
Compromis : App password rotation, self-email only, SMTP rate limits
Tests
Ce qui est testé
Couverture manquante
- Unit tests for contact API validation and escapeHtml()
- Unit tests for slug join logic between projects[] and projectDetails[]
- Component tests for ProjectCard and detail page sections
- E2E tests for contact form and project navigation flows
- CI pipeline with lint, typecheck, and build gates (GitHub Actions)
Défis clés
- Éviter les erreurs d'hydratation entre thème sombre et changement de langue
- Adapter les animations aux préférences de réduction de mouvement
Apprentissages clés
- Architectures d'internationalisation avancées avec Next.js App Router
- Optimisation des performances web selon les normes Vercel