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 │ │ API │
│ (Render │ │ (Render │ │ (Render │
│ Web Svc) │ │ Static) │ │ Web Svc) │
└──────────────┘ └─────────────┘ └──────────────┘
uzdavines.ai docs.uzdavines api.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 + /resume routes |
| Docs | Docusaurus + TypeScript | Static Site | Knowledge base, dual-tier content |
| API | Express (Node.js) | Web Service | OTP-gated private docs (email + JWT) |
The interactive resume (with the Pierre chatbot) is served by the homepage app at
uzdavines.ai/resume. It previously had its ownapps/resumeapp andresume.uzdavines.aisubdomain; that was retired in favor of the/resumeroute.
Why SSR for the Homepage?
The homepage requires server-side rendering because it includes API routes (/api/chat, /api/pierre) 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
api.uzdavines.ai CNAME --> Render API 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/api/** changed? --> deploy-api.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
│ │ │ ├── resume/ # Interactive resume + Pierre chatbot
│ │ │ ├── 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
│ │
│ └── api/ # Express — api.uzdavines.ai
│ ├── src/ # Routes, middleware, lib
│ │ └── routes/ # OTP: access, chat, otp
│ └── package.json
│
├── packages/
│ └── shared/ # Shared utilities
│
├── .github/
│ └── workflows/ # CI/CD pipelines
│ ├── deploy-homepage.yml
│ ├── deploy-docs.yml
│ ├── deploy-api.yml
│ ├── pr-check-homepage.yml
│ ├── pr-check-docs.yml
│ └── pr-check-api.yml
│
└── 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 |