A full-stack, cloud-native AI experience that turns professional context, project history, and communication style into a conversational digital twin.
This project is an interactive digital twin of Jeremy Demers. Visitors can ask about Jeremy's experience, projects, approach to AI, and working style through a responsive chat interface backed by Amazon Bedrock. The application combines a statically exported Next.js frontend with a serverless FastAPI backend and infrastructure managed entirely with Terraform.
- Context-aware conversation β grounds responses in curated professional facts, summaries, writing style, and LinkedIn history.
- Persistent sessions β keeps conversation history in local JSON files during development and Amazon S3 in AWS.
- Production-focused interface β responsive design, dark and light themes, accessible controls, suggested prompts, and Markdown responses.
- Interactive architecture viewer β lazy-loads a Mermaid diagram so visitors can inspect the AWS system without increasing the initial bundle.
- Serverless AWS deployment β uses Lambda, API Gateway, Bedrock, S3, CloudFront, IAM, and optional Route 53/ACM resources.
- Infrastructure as code β provisions repeatable environments with Terraform and isolated remote-state keys.
| Layer | Technology |
|---|---|
| Frontend | Next.js 16, React 19, TypeScript, Tailwind CSS 4 |
| Interface | Lucide React, React Markdown, Remark GFM, Mermaid |
| API | FastAPI, Pydantic, Mangum |
| AI | Amazon Bedrock Converse API, Amazon Nova |
| Runtime | Python 3.14, AWS Lambda |
| Storage | Amazon S3 for conversation memory and static hosting |
| Delivery | API Gateway HTTP API, Amazon CloudFront |
| Infrastructure | Terraform, AWS IAM, optional Route 53 and ACM |
flowchart LR
visitor[Visitor] --> cloudfront[CloudFront]
cloudfront --> frontend[S3 static frontend]
visitor --> gateway[API Gateway]
gateway --> lambda[Lambda + FastAPI]
lambda --> bedrock[Amazon Bedrock]
lambda --> memory[S3 conversation memory]
The browser loads the exported Next.js application through CloudFront and sends chat requests directly to API Gateway. Lambda runs the FastAPI application through Mangum, calls Amazon Bedrock for a response, and persists session history in a private S3 bucket. Local development uses filesystem-based memory instead.
See AWS Deployment Architecture for the complete resource diagram, conditional custom-domain path, IAM relationships, and Terraform state flow.
- Node.js 20 or newer
- Python 3.14
- uv
- AWS credentials with access to the configured Amazon Bedrock model
Clone the repository and prepare the environment:
git clone https://github.com/JeremyDemers/digital-twin.git
cd digital-twin
cp .env.example .envStart the API in one terminal:
cd backend
uv sync
uv run uvicorn server:app --reload --port 8000Start the frontend in another terminal:
cd frontend
npm install
npm run devOpen http://localhost:3000. The frontend uses http://localhost:8000 as its default API URL.
| Variable | Purpose | Default |
|---|---|---|
DEFAULT_AWS_REGION |
AWS region used by the Bedrock client and deployment scripts | us-east-1 |
BEDROCK_MODEL_ID |
Bedrock model used for chat responses | global.amazon.nova-2-lite-v1:0 locally |
NEXT_PUBLIC_API_URL |
Browser-facing FastAPI/API Gateway base URL | http://localhost:8000 |
CORS_ORIGINS |
Comma-separated browser origins allowed by FastAPI | http://localhost:3000 |
USE_S3 |
Store conversation memory in S3 instead of local files | false |
S3_BUCKET |
S3 bucket used when persistent memory is enabled | Empty |
MEMORY_DIR |
Local conversation-memory directory | ../memory |
PROJECT_NAME |
Resource naming prefix | digital-twin |
Never commit .env files, AWS credentials, Terraform state, or conversation memory. The repository's .gitignore excludes these paths.
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Returns service and storage information |
GET |
/health |
Reports API, storage, and model status |
POST |
/chat |
Sends a message and returns the twin's response and session ID |
GET |
/conversation/{session_id} |
Retrieves the stored conversation for a session |
Example chat request:
curl -X POST http://localhost:8000/chat \
-H "Content-Type: application/json" \
-d '{"message":"What kind of AI work have you done?"}'Example response:
{
"response": "...",
"session_id": "a generated UUID"
}Pass the returned session_id with later messages to continue the same conversation.
The deployment script packages the Python application for Lambda, applies the Terraform configuration, exports the frontend, syncs it to S3, and reports the resulting CloudFront and API Gateway URLs.
Before deploying infrastructure locally, install and authenticate the AWS CLI, install Terraform and uv, enable access to the selected Bedrock model, and provision the encrypted, versioned S3 state bucket referenced by scripts/deploy.sh.
Then deploy and approve the Terraform plan:
./scripts/deploy.sh prod digital-twinProduction settings, including the optional custom domain, live in backend/terraform/prod.tfvars. Review the Terraform plan and expected AWS costs before applying infrastructure.
Application code deploys automatically after merged changes reach main. GitHub Actions uses short-lived OIDC credentials scoped to twin-prod-api, the frontend bucket, and its CloudFront distribution. It cannot modify Terraform infrastructure or conversation storage.
Environment destruction is intentionally not exposed through GitHub Actions. Run a reviewed Terraform destroy locally only when removal and data loss are explicitly intended.
digital-twin/
βββ frontend/ # Next.js interface and static assets
β βββ app/ # App Router layout, page, and global styles
β βββ components/ # Chat, Markdown, and architecture UI
β βββ public/ # Profile and social preview images
βββ backend/ # FastAPI application and twin context
β βββ data/ # Curated facts, summary, style, and profile data
β βββ terraform/ # AWS infrastructure and architecture docs
βββ scripts/ # Local infrastructure deployment workflow
βββ .env.example # Safe local configuration template
- Chat messages are sent to Amazon Bedrock for inference.
- Local sessions are written beneath
memory/; deployed sessions are stored in the configured private S3 bucket. - The system prompt instructs the twin to distinguish itself from the human when asked directly and to avoid inventing details that are not present in its context.
- Treat profile documents and conversation history as personal data. Apply appropriate retention, access-control, and logging policies before a public production deployment.
# Frontend quality checks
cd frontend && npm run lint
cd frontend && npm run build
# Backend development server
cd backend && uv run uvicorn server:app --reload
# Terraform formatting and validation
terraform -chdir=backend/terraform fmt -check
terraform -chdir=backend/terraform validateBuilt as a practical exploration of personalized AI, serverless application design, and production infrastructure on AWS.
