Skip to content
MCP ThesaurusMCP Thesaurus

thechrisgrey

CommunityIncomplete39/100Claim

streamable-httpupdated 8d ago

Personal website for Christian Perez (@thechrisgrey) | Founder & CEO of Altivum Inc. | Former Green Beret (18D Special Forces Medical Sergeant) | Bronze Star Recipient | Host of The Vector Podcast | Author of "Beyond the Assessment"

SourceWebsite

What can you do with thechrisgrey?

thechrisgrey.com

TypeScript React Vite Tailwind CSS AWS Amplify Amazon Bedrock CI License

Personal website for Christian Perez (@thechrisgrey) | Founder & CEO of Altivum Inc. | Former Green Beret (18D Special Forces Medical Sergeant) | Bronze Star Recipient | Host of The Vector Podcast | Author of "Beyond the Assessment"

https://thechrisgrey.com


Table of Contents


Technology Stack

Layer Technology
Frontend React 19, TypeScript 5, Vite 5 (Vitest 4, ESLint 10 flat config)
Styling Tailwind CSS 4 (CSS-first @theme config, Oxide engine)
Routing React Router 7
CMS Sanity.io (blog content)
AI Chat Amazon Bedrock (Claude Haiku 4.5) + RAG
Auth Amazon Cognito (admin panel)
Hosting AWS Amplify
CDN/Analytics Cloudflare Web Analytics
Testing Vitest + React Testing Library + Cypress
Code Quality ESLint, strict TypeScript

Features

Pages

  • Home : Scroll-based animations with sticky profile sections
  • About : Personal biography and military background
  • Altivum Inc : Company showcase and services
  • The Vector Podcast : YouTube embeds, Spotify player, collapsible episode list
  • Beyond the Assessment : Book information and purchase links
  • Blog : Sanity CMS-powered with categories, tags, series, and reading progress
  • AI Chat : Full-viewport conversational AI with RAG-enhanced responses
  • Claude : AWS certifications and Claude expertise showcase
  • AWS : AWS partnership and community builder profile
  • Admin : Cognito-authenticated KB management and site health dashboard
  • Links : Linktree-style quick links
  • Contact : Contact form, speaking topics, downloadable press kit

Technical Highlights

  • SEO : JSON-LD structured data, Open Graph, dynamic sitemap, RSS feed
  • AI Chat with RAG : Bedrock Knowledge Base retrieval with streaming responses
  • Podcast Auto-Sync : YouTube Data API fetches episodes at build time
  • Chat Widget : Floating chat widget available across all pages
  • Metrics Dashboard : CloudWatch and DynamoDB-backed operational metrics
  • Error Boundaries : Page-level error handling with custom fallback UIs
  • Accessibility : Focus trapping, keyboard navigation, ARIA labels, skip links
  • Performance : Image optimization (Sharp/SVGO), lazy loading, code splitting, manual chunking

Architecture

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                        FRONTEND (React)                         │
│  ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā” ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”           │
│  │   Home   │ │  Podcast │ │   Blog   │ │   Chat   │   ...     │
│  ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜ ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜           │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
        │               │              │              │
        ā–¼               ā–¼              ā–¼              ā–¼
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”   ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”   ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”   ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│  Amplify  │   │  YouTube  │   │  Sanity   │   │    Bedrock    │
│  Hosting  │   │  Data API │   │    CMS    │   │  + RAG (KB)   │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜   ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜   ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜   ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
                (build-time)     (runtime)       (Lambda stream)

AI Chat Request Flow

User Message
    │
    ā–¼
Lambda Function URL (streaming)
    │
    ā”œā”€ā”€> Bedrock Knowledge Base (retrieve context)
    │         │
    │         ā–¼
    │    S3 Vectors (autobiography chunks)
    │
    ā”œā”€ā”€> Bedrock Guardrails (content filtering)
    │
    └──> Bedrock ConverseStream API (Claude Haiku 4.5)
              │
              ā–¼
         Streaming Response -> Client

AWS Infrastructure

Service Resource Region Purpose
Amplify d3du8eg39a9peo us-east-2 Hosting, CI/CD
Lambda thechrisgrey-chat-stream us-east-1 AI chat streaming
Lambda thechrisgrey-contact-email us-east-2 Contact form
Lambda thechrisgrey-newsletter-subscription us-east-2 Newsletter
Lambda thechrisgrey-kb-sync us-east-1 KB auto-sync on S3 changes
Lambda thechrisgrey-kb-builder us-east-1 KB admin CRUD operations
Lambda thechrisgrey-metrics us-east-1 Metrics collection and reporting
Bedrock KB ARFYABW8HP us-east-1 RAG knowledge base
Cognito User Pool us-east-1 Admin authentication
S3 thechrisgrey-kb-source us-east-1 KB source documents
S3 thechrisgrey-vectors us-east-1 Vector embeddings
DynamoDB thechrisgrey-chat-ratelimit us-east-1 Rate limiting (20 req/hr/IP)
Secrets Manager thechrisgrey/youtube-api-key us-east-1 YouTube API key
CloudWatch tcg-AI-chat us-east-1 Bedrock invocation logs

Getting Started

Prerequisites

  • Node.js 20.x (see .nvmrc)
  • npm
  • AWS CLI (for deployment)

Installation

git clone https://github.com/thechrisgrey/thechrisgrey.git
cd thechrisgrey
npm install

Development

npm run dev             # Start dev server at http://localhost:5173
npm run build           # Full production build
npm run preview         # Preview production build
npm run lint            # Run ESLint

Build Pipeline

The production build runs these steps in sequence:

validate-env -> podcast-episodes -> lint -> tsc -> vite build -> sitemap -> rss

Testing

Framework Scope Command
Vitest Unit + Integration npm test
Vitest Watch mode npm run test:watch
Vitest Coverage report npm run test:coverage
Cypress E2E (headless) npm run cy:run
Cypress E2E (interactive) npm run cy:open
node:test Lambda unit + contract npm run test:lambda

The test suite includes unit tests for components, hooks, and utilities; integration tests for page-level behavior; and end-to-end tests covering navigation, chat, blog, and contact flows.

Live-API contract tests (opt-in)

Critical external boundaries — Cognito admin auth, the live Sanity client, Bedrock KB retrieval, and the Bedrock guardrail — are also covered by opt-in contract tests that exercise the real services (green mocks alone can drift from reality). They skip cleanly during npm run test:lambda and CI, and only run when their flag + AWS/Sanity credentials are present:

COGNITO_CONTRACT_TESTS=1 COGNITO_CLIENT_ID=… COGNITO_TEST_EMAIL=… COGNITO_TEST_PASSWORD=… \
  node --test lambda/shared/__tests__/cognito-contract.test.mjs
SANITY_CONTRACT_TESTS=1      node --test lambda/chat-stream/__tests__/sanity-contract.test.mjs
KB_RETRIEVE_CONTRACT_TESTS=1 node --test lambda/chat-stream/__tests__/kb-retrieve-contract.test.mjs
BEDROCK_CONTRACT_TESTS=1     node --test lambda/blueprint/__tests__/guardrail-contract.test.mjs

See .env.example for the full list of flags and required permissions. Run these before a release (or on a scheduled job) to catch response-shape/schema drift that unit mocks can't.


Environment Variables

Set in AWS Amplify console or in a local .env file:

Variable Description Required
VITE_CHAT_ENDPOINT Lambda Function URL for AI chat Yes
VITE_CONTACT_ENDPOINT Lambda Function URL for contact form Yes
VITE_NEWSLETTER_ENDPOINT Lambda Function URL for newsletter Yes
VITE_COGNITO_USER_POOL_ID Cognito User Pool ID (admin auth) Yes
VITE_COGNITO_CLIENT_ID Cognito App Client ID Yes
VITE_KB_BUILDER_ENDPOINT Lambda Function URL for KB admin Yes
VITE_CHAT_SIGNING_KEY HMAC signing key for chat requests Yes
VITE_METRICS_ENDPOINT Lambda Function URL for metrics Yes
YOUTUBE_API_KEY YouTube Data API v3 key (build-time only) Yes

VITE_ prefixed variables are bundled into the frontend. YOUTUBE_API_KEY is only used during the build step.


Deployment

Push to main triggers automatic Amplify deployment:

git push origin main

Manual Rebuild

aws amplify start-job \
  --app-id d3du8eg39a9peo \
  --branch-name main \
  --job-type RELEASE \
  --region us-east-2

Lambda Deployment

Each Lambda function is deployed independently via a single verified script. The script installs from the lockfile, dereferences the lambda-shared symlink into the bundle, and verifies the entire module graph resolves before upload — so a deploy can no longer ship a Lambda that crashes on cold start.

# Verify the bundle builds and resolves, without uploading:
npm run deploy:lambda -- chat-stream --dry-run

# Deploy for real:
npm run deploy:lambda -- chat-stream

Works for any Lambda under lambda/ (e.g. chat-stream, blueprint, kb-builder, metrics, kb-sync, mcp-server). Pass --region <r> to override the default (us-east-1). Do not hand-build function.zip — the manual zip glob omits the sibling modules each handler imports and produces a broken artifact.


Project Structure

thechrisgrey/
ā”œā”€ā”€ public/                          # Static assets (served as-is)
│   ā”œā”€ā”€ assets/documents/            # Downloadable PDFs
│   ā”œā”€ā”€ press-kit/                   # Press materials + archive
│   ā”œā”€ā”€ .well-known/security.txt
│   ā”œā”€ā”€ robots.txt
│   ā”œā”€ā”€ og.png                       # Open Graph image
│   └── favicon.png
│
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ components/
│   │   ā”œā”€ā”€ admin/                   # Admin panel (login, KB entries, site health)
│   │   ā”œā”€ā”€ chat/                    # AI chat (message, input, suggestions, widget)
│   │   ā”œā”€ā”€ ui/                      # Base UI (Button, FormInput, IconButton)
│   │   ā”œā”€ā”€ Navigation.tsx
│   │   ā”œā”€ā”€ Footer.tsx
│   │   ā”œā”€ā”€ SEO.tsx                  # Meta tags + JSON-LD
│   │   ā”œā”€ā”€ ErrorBoundary.tsx
│   │   ā”œā”€ā”€ ErrorFallbacks.tsx
│   │   ā”œā”€ā”€ EpisodeCard.tsx
│   │   ā”œā”€ā”€ NewsletterForm.tsx
│   │   ā”œā”€ā”€ ReadingProgressBar.tsx
│   │   └── ...
│   │
│   ā”œā”€ā”€ pages/                       # Route-level page components
│   │   ā”œā”€ā”€ Home.tsx, About.tsx, Altivum.tsx, Podcast.tsx
│   │   ā”œā”€ā”€ BeyondTheAssessment.tsx, Blog.tsx, BlogPost.tsx
│   │   ā”œā”€ā”€ Chat.tsx, Claude.tsx, AWS.tsx, Admin.tsx
│   │   ā”œā”€ā”€ Contact.tsx, Links.tsx, Privacy.tsx
│   │   └── NotFound.tsx
│   │
│   ā”œā”€ā”€ hooks/                       # Custom React hooks
│   │   ā”œā”€ā”€ useAuth.ts               # Cognito authentication
│   │   ā”œā”€ā”€ useChatEngine.ts         # Chat state and streaming
│   │   ā”œā”€ā”€ useFocusTrap.ts          # Modal focus management
│   │   ā”œā”€ā”€ useKbAdmin.ts            # KB admin operations
│   │   ā”œā”€ā”€ usePageContext.ts        # Page-level context for chat
│   │   ā”œā”€ā”€ useSessionStorage.ts     # Typed sessionStorage with Date revival
│   │   └── useSiteHealth.ts         # Site health monitoring
│   │
│   ā”œā”€ā”€ sanity/                      # Sanity CMS client, queries, types, cache
│   ā”œā”€ā”€ utils/                       # Typography, schemas, validators, web vitals
│   ā”œā”€ā”€ constants/                   # Social links
│   ā”œā”€ā”€ types/                       # TypeScript interfaces
│   ā”œā”€ā”€ data/                        # Podcast episode data (generated + fallback)
│   ā”œā”€ā”€ assets/                      # Optimized images (Vite processed)
│   │
│   ā”œā”€ā”€ __tests__/
│   │   ā”œā”€ā”€ integration/             # Page-level integration tests
│   │   └── setup.ts
│   │
│   ā”œā”€ā”€ App.tsx                      # Routes, layout, error boundaries
│   ā”œā”€ā”€ main.tsx                     # Entry point
│   └── index.css                    # Tailwind directives
│
ā”œā”€ā”€ lambda/
│   ā”œā”€ā”€ shared/                      # Shared utilities (auth, rate limiting, response)
│   ā”œā”€ā”€ chat-stream/                 # Bedrock streaming Lambda
│   ā”œā”€ā”€ kb-sync/                     # Knowledge Base auto-sync
│   ā”œā”€ā”€ kb-builder/                  # KB admin CRUD
│   └── metrics/                     # Metrics collection
│
ā”œā”€ā”€ scripts/
│   ā”œā”€ā”€ validate-env.js              # Build-time env validation
│   ā”œā”€ā”€ generate-podcast-episodes.js # YouTube API fetch
│   ā”œā”€ā”€ generate-sitemap.js          # Sitemap from Sanity
│   └── generate-rss.js             # RSS feed from Sanity
│
ā”œā”€ā”€ cypress/                         # E2E tests
│   ā”œā”€ā”€ e2e/                         # Test specs
│   ā”œā”€ā”€ fixtures/                    # Test data
│   └── support/                     # Custom commands
│
ā”œā”€ā”€ docs/                            # Internal documentation and plans
ā”œā”€ā”€ .github/workflows/ci.yml        # GitHub Actions CI
ā”œā”€ā”€ amplify.yml                      # Amplify build config
ā”œā”€ā”€ tailwind.config.js
ā”œā”€ā”€ vite.config.ts
ā”œā”€ā”€ vitest.config.ts
ā”œā”€ā”€ cypress.config.ts
└── tsconfig.json

Key Integrations

Sanity CMS (Blog)

  • Project ID: k5950b3w | Dataset: production
  • Content includes blog posts with categories, tags, series, and Portable Text rich content
  • Client-side caching via postCache.ts with Date revival

YouTube Data API (Podcast)

Episodes are fetched at build time from the @AltivumPress channel.

  1. generate-podcast-episodes.js runs during the build step
  2. Fetches channel, uploads playlist, and video details
  3. Generates src/data/generatedEpisodes.json
  4. Falls back to static data if the API is unavailable

Amazon Bedrock (AI Chat)

  • Model: Claude Haiku 4.5 (us.anthropic.claude-haiku-4-5-20251001-v1:0)
  • Knowledge Base: ARFYABW8HP (autobiography chunks)
  • Guardrail: 5kofhp46ssob (content filtering)
  • Rate Limit: 20 requests/hour per IP (DynamoDB-backed)
  • Streaming responses via Lambda Function URL with RAG retrieval (5 chunks per query)

Cloudflare Web Analytics

Privacy-friendly, cookie-free analytics with no personal data collection.


Design System

Color Palette

Name Hex Usage
altivum-dark #0A0F1C Backgrounds
altivum-navy #1A2332 Cards, nav
altivum-blue #2E4A6B Accents
altivum-slate #4A5A73 Borders, muted
altivum-silver #9BA6B8 Body text
altivum-gold #C5A572 Highlights, CTAs

Typography

SF Pro Display with system font fallbacks. Ultra-light weight (200) throughout. Defined in src/utils/typography.ts.

Animations

  • animate-fade-in : Hero entrance (1.2s)
  • animate-nav-fade-in : Nav delayed entrance (0.8s, 2s delay)
  • shimmer : Background shimmer effect
  • widget-open : Chat widget expansion (250ms)

License

Copyright 2026 Christian Perez. All rights reserved.

For inquiries, use the contact form or email via the website.