Professional personal website built with Next.js App Router + TypeScript + TailwindCSS.
| File | Description |
|---|---|
CLAUDE.md |
Claude Code quickstart — commands, env vars, gotchas |
docs/architecture.md |
Full architecture reference — components, data flows, design decisions |
docs/diagrams/c4_architecture.puml |
C4 Context + Container diagrams (PlantUML source) |
docs/diagrams/c4_context.png |
C4 Context diagram (rendered PNG) |
docs/diagrams/c4_containers.png |
C4 Container diagram (rendered PNG) |
docs/diagrams/aws_architecture.puml |
AWS service diagram with local icons (PlantUML source) |
docs/diagrams/aws_architecture.png |
AWS architecture diagram (rendered PNG) |
docs/diagrams/c4lib/ |
Locally downloaded C4-PlantUML stdlib (no remote URLs) |
docs/diagrams/awslib/ |
Locally cloned AWS icons for PlantUML (awslabs/aws-icons-for-plantuml) |
# Install dependencies (first time only)
sudo apt-get install -y default-jre graphviz
wget -q https://github.com/plantuml/plantuml/releases/latest/download/plantuml.jar -O /usr/local/bin/plantuml.jar
# Render all diagrams from docs/diagrams/
cd docs/diagrams
java -jar /usr/local/bin/plantuml.jar -tpng c4_architecture.puml -o ./
java -jar /usr/local/bin/plantuml.jar -tpng aws_architecture.puml -o ./- Deep-link pages:
/home landing page with pill-style navigation cards/store,/website,/portfolio,/blog,/appointment,/newsletter
- Reusable design system components (
PageShell,Section,Card,PillLink,Badge,Button,Input) - SEO metadata per page + OpenGraph
sitemap.xmlandrobots.txt- Newsletter mock API route with in-memory storage
- Appointment page reads Zoom details from environment variables
- Web3 wallet connection (Injected, WalletConnect, Coinbase Wallet) + SIWE session auth
- Protected recruiter area (
/recruiter) with SIWE gate - Onchain identity pages (
/proof,/onchain) - Portfolio projects are generated at build time from GitHub GraphQL into
public/projects.json(static-export safe).
- Install dependencies:
npm install- Copy environment variables:
cp .env.example .env.local- Run dev server:
npm run devAdd the following to .env.local:
NEXT_PUBLIC_ZOOM_PERSONAL_LINK=https://zoom.us/j/your-meeting-id
NEXT_PUBLIC_ZOOM_MEETING_ID=your-meeting-id
NEXT_PUBLIC_SIWE_API_BASE=https://<api-id>.execute-api.<region>.amazonaws.com/<stage>
NEXT_PUBLIC_RPC_URL=https://polygon-amoy.g.alchemy.com/v2/your-key
NEXT_PUBLIC_CHAIN_ID=80002
NEXT_PUBLIC_RECRUITER_PASS_CONTRACT_ADDRESS=0x0000000000000000000000000000000000000000
WALLETCONNECT_PROJECT_ID=your-walletconnect-project-id
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your-walletconnect-project-id-
NEXT_PUBLIC_SIWE_API_BASEis required and is called directly by the browser for SIWE nonce/verify/session/me. -
NEXT_PUBLIC_RPC_URL,NEXT_PUBLIC_CHAIN_ID=80002, andNEXT_PUBLIC_RECRUITER_PASS_CONTRACT_ADDRESSare optional and enable client-side RecruiterPass holder checks for the Verified+ badge and resume proof metadata. -
Configure API Gateway CORS to allow your Amplify domain (and localhost during development), including
GET, POSTmethods andcontent-type, authorizationheaders. -
WALLETCONNECT_PROJECT_IDis required for WalletConnect v2. -
NEXT_PUBLIC_WALLETCONNECT_PROJECT_IDmirrors the same value for client-side WalletConnect/Web3Modal initialization. -
NEXT_PUBLIC_ADMIN_API_BASEis required for the client-side admin dashboard under/admin. It should point to your API Gateway REST API base URL (for examplehttps://{REST_API_ID}.execute-api.us-east-1.amazonaws.com/prod). -
NEXT_PUBLIC_AGENT_MANAGEMENT_API_BASEis required for the admin agent management UI under/adminand should point to the same API Gateway base URL used for agent management endpoints. -
NEXT_PUBLIC_API_BASE_URLis required for the blog page (/blog), which is statically exported and fetches list/detail data at runtime from/site/postsendpoints in the browser. -
GITHUB_TOKENis required at build time (Amplify env var) to read repositories via GitHub GraphQL. -
GITHUB_OWNERis the GitHub user/org login to sync from. -
GITHUB_OWNER_TYPEmust beuserororg.
- Set
NEXT_PUBLIC_SIWE_API_BASEin.env.local. - Start the app with
npm run dev. - Connect your wallet and click Sign in with Ethereum.
- In browser devtools, confirm these API Gateway calls succeed from the client:
POST {NEXT_PUBLIC_SIWE_API_BASE}/siwe/noncePOST {NEXT_PUBLIC_SIWE_API_BASE}/siwe/verifyGET {NEXT_PUBLIC_SIWE_API_BASE}/siwe/sessionwithAuthorization: Bearer <token>GET {NEXT_PUBLIC_SIWE_API_BASE}/siwe/mewithAuthorization: Bearer <token>
The portfolio page reads static data from public/projects.json. This file is generated during build by scripts/sync-github-projects.mjs and never calls GitHub from the browser.
Set these in Amplify Console → App settings → Environment variables:
GITHUB_TOKEN=<fine-grained PAT with read-only repo metadata access>
GITHUB_OWNER=<github user or org login>
GITHUB_OWNER_TYPE=user # or orgCategory chips are derived from repository topics first (case-insensitive):
genai→GenAIbackend→Backendfrontend→Frontendcloud→Cloud
If no mapped topic exists, language fallback is used:
- TypeScript/JavaScript → Frontend
- Java/Go → Backend
- Python → GenAI
- HCL/Terraform → Cloud
Forked and archived repositories are excluded.
npm run sync:projects
npm run buildSecurity note: GITHUB_TOKEN is only used by the build script and is never shipped to client-side JavaScript.
npm run build
npm run start- Import the repository in Vercel.
- Configure all required environment variables in Project Settings → Environment Variables.
- Deploy (auto-detected Next.js build settings).
- Connect repository in Amplify Hosting.
- Use the existing
amplify.yml(or default Next.js settings). - Set environment variables in Amplify Console.
- Trigger build + deploy.
- Blog routing is static-export safe: there is no
/blog/[id]page; selecting a post opens details on the same/blogpage via client-side fetching. - Newsletter subscription currently stores emails in memory via
/api/newsletterand includes a TODO for provider integration (Mailchimp/ConvertKit). - SIWE implementation is intentionally MVP-level and includes TODO comments for production hardening (nonce/session persistence, stronger replay defenses, session rotation/revocation).
npm run lint
npm run lint:fix
npm run format
npm run format:check