Platform Architecture
Overview
This article provides the complete architectural blueprint for the uzdavines.ai platform -- a monorepo containing three independently deployed web applications unified by shared infrastructure, a consistent design language, and automated CI/CD pipelines.
- Why it matters: Understanding the platform's architecture is essential for making informed decisions about development, deployment, and scaling. This document serves as the single source of truth for how the system is structured and why.
- What you will learn: The application stack and framework choices, DNS and hosting configuration via Cloudflare and Render, the CI/CD deployment pipeline, monorepo directory structure, and the shared design language across all applications.
The uzdavines.ai platform is built as a monorepo with three independently deployed applications, unified by shared infrastructure and a consistent design language.
High-Level Architecture
┌─────────────────────────┐
│ Cloudflare DNS │
│ (Proxy + SSL/TLS) │
└────┬─────┬─────┬────────┘
│ │ │
┌───────────┘ │ └───────────┐
│ │ │
v v v
┌──────────────┐ ┌─────────────┐ ┌──────────────┐
│ Homepage │ │ Docs │ │ Resume │
│ (Render │ │ (Render │ │ (Render │
│ Web Svc) │ │ Static) │ │ Web Svc) │
└──────────────┘ └─────────────┘ └──────────────┘
uzdavines.ai docs.uzdavines resume.uzdavines
.ai .ai
Application Stack
| Application | Framework | Render Type | Key Features |
|---|---|---|---|
| Homepage | Next.js + Tailwind CSS | Web Service (SSR) | AI chatbot, scroll-snap sections, /coffee route |
| Docs | Docusaurus + TypeScript | Static Site | Knowledge base, dual-tier content |
| Resume | Next.js + Tailwind CSS | Web Service (SSR) | Interactive resume, Pierre chatbot |
Why SSR for Homepage and Resume?
Both the homepage and resume applications require server-side rendering because they include API routes (/api/chat) that proxy requests to the Claude API. The API key must stay server-side.
Why Static for Docs?
Docusaurus generates static HTML/CSS/JS at build time. No server-side logic is needed — the content is pre-rendered and served directly.
Infrastructure
DNS and CDN — Cloudflare
uzdavines.ai CNAME --> Render homepage service
docs.uzdavines.ai CNAME --> Render docs service
resume.uzdavines.ai CNAME --> Render resume service
- SSL/TLS mode: Full
- Proxy status: Proxied (after Render TLS cert validation)
- Cloudflare handles DNS resolution, CDN caching, and SSL termination
Hosting — Render
Each application is deployed as a separate Render service. Auto-deploy is disabled — deployments are triggered by GitHub Actions via deploy hooks.
CI/CD — GitHub Actions
Path-filtered workflows ensure only the affected application is built and deployed when changes are pushed to main.
Push to main
│
├── apps/homepage/** changed? --> deploy-homepage.yml
├── apps/docs/** changed? --> deploy-docs.yml
└── apps/resume/** changed? --> deploy-resume.yml
Monorepo Structure
uzdavines-platform/
├── apps/
│ ├── homepage/ # Next.js — uzdavines.ai
│ │ ├── src/app/ # App router pages
│ │ │ ├── api/chat/ # AI chatbot API route
│ │ │ ├── coffee/ # Cloud City Roasters page
│ │ │ ├── layout.tsx # Root layout
│ │ │ └── page.tsx # Homepage
│ │ ├── public/ # Static assets
│ │ └── package.json
│ │
│ ├── docs/ # Docusaurus — docs.uzdavines.ai
│ │ ├── docs/ # Public Markdown docs (Tier 1)
│ │ ├── static/ # Static assets
│ │ │ └── private/ # Hidden docs (Tier 2)
│ │ ├── src/css/ # Custom styling
│ │ └── package.json
│ │
│ └── resume/ # Next.js — resume.uzdavines.ai
│ ├── src/app/ # App router pages
│ │ └── api/chat/ # Pierre chatbot API route
│ └── package.json
│
├── packages/
│ └── shared/ # Shared utilities
│
├── .github/
│ └── workflows/ # CI/CD pipelines
│ ├── deploy-homepage.yml
│ ├── deploy-docs.yml
│ ├── deploy-resume.yml # (future)
│ ├── pr-check-homepage.yml
│ ├── pr-check-docs.yml
│ └── pr-check-resume.yml # (future)
│
└── package.json # npm workspaces root
Design Language
All applications share a consistent visual identity:
| Aspect | Standard |
|---|---|
| Color palette | Monochrome (black, white, grays) + dark navy (#0a1628 → #1a2744) |
| Mode | Dark mode default |
| Typography | Plus Jakarta Sans |
| Layout | Mobile-first |
| Aesthetic | Sleek, professional, modern, understated |