Your Actual Folder Layout

📁 Your Repository Structure - Optimized Workflow Guide

Your Actual Folder Layout

bayezid_portfolio/
├── .github/
│   └── workflows/              ✅ NEW - Your CI/CD pipelines
│       ├── ci-cd.yml
│       ├── code-quality.yml
│       └── deploy.yml
│
├── client/                     ✅ Frontend (React + Vite)
│   └── src/
│       ├── components/
│       ├── pages/
│       └── styles/
│
├── server/                     ✅ Backend (Express.js)
│   └── index.ts
│
├── shared/                     ✅ Shared code (types, utils)
│   └── ...shared files
│
├── patches/                    ✅ pnpm patches
│   └── wouter@3.7.1.patch
│
├── Configuration Files
│   ├── vite.config.ts         ✅ Vite build config
│   ├── tsconfig.json          ✅ TypeScript config
│   ├── tsconfig.node.json
│   ├── package.json           ✅ All dependencies
│   ├── pnpm-lock.yaml
│   ├── railway.json           ✅ Railway deployment
│   ├── template.json
│   └── components.json
│
├── Ignore Files
│   ├── .gitignore
│   └── .prettierignore
│
├── Format Config
│   └── .prettierrc
│
└── Documentation
    └── README.md

🏗️ Your Tech Stack Breakdown

Frontend (client/)

React 19.2.1
├── Vite 7.1.7 (build tool)
├── TailwindCSS 4.1.14
├── Radix UI (21 components)
├── Framer Motion (animations)
├── React Hook Form (forms)
├── Zod (validation)
└── Wouter (routing)

Backend (server/)

Node.js 20
├── Express 4.21.2
├── TypeScript 5.6.3
└── esbuild (bundling)

Shared (shared/)

Shared types, utilities, and constants
Used by both client and server

🚀 Build Process (How It Works)

Step 1: Install Dependencies

pnpm install --frozen-lockfile
├─ Installs all client/ dependencies
├─ Installs all server/ dependencies
└─ Applies patches/ (wouter fix)

Step 2: Type Check

pnpm check
├─ TypeScript compiles client/
├─ TypeScript compiles server/
├─ TypeScript compiles shared/
└─ ~3 seconds (no output files)

Step 3: Build Frontend (client/)

pnpm build
├─ Vite processes client/
├─ Outputs to: dist/public/
├─ Includes: JS, CSS, assets
└─ ~20 seconds

Step 4: Build Backend (server/)

esbuild server/index.ts --platform=node ...
├─ Bundles server/ code
├─ Outputs to: dist/index.js
├─ Includes: all dependencies
└─ ~3 seconds

Step 5: Final Output

dist/
├── index.js              ← Server entry point
├── public/               ← Frontend assets
│   ├── index.html
│   ├── assets/
│   │   ├── index-xxx.js
│   │   ├── vendor-xxx.js
│   │   └── style-xxx.css
│   └── ...
└── ...other files

📋 Build Command Breakdown

Your package.json has:

{
  "scripts": {
    "build": "vite build && esbuild server/index.ts --platform=node --packages=external --bundle --format=esm --outdir=dist",
    "start": "NODE_ENV=production node dist/index.js",
    "dev": "vite --host",
    "preview": "vite preview --host"
  }
}

This means:

  1. vite build - Builds React app to dist/public/
  2. && - Then (if successful)
  3. esbuild server/... - Bundles Express server to dist/index.js
  4. Result - Full-stack app ready to run

🔄 CI/CD Flow for Your Structure

Push to GitHub
    ↓
Check all TypeScript
├─ client/
├─ server/
└─ shared/
    ↓ (~3 sec)
Build Frontend
├─ client/ → dist/public/
└─ Include assets
    ↓ (~20 sec)
Build Backend
├─ server/ → dist/index.js
└─ Include dependencies
    ↓ (~3 sec)
Verify Output
├─ dist/index.js exists
├─ dist/public/ exists
└─ Count files
    ↓ (~2 sec)
Run Tests
├─ Security scan
└─ Dependency audit
    ↓ (~5 sec)
Deploy (if main branch)
├─ Docker build with dist/
├─ SSH to server
└─ Start with: node dist/index.js
    ↓ (~10 sec)
✅ Done! (~40-50 seconds total)

🐳 How Docker Handles Your Structure

Build Stage (in Dockerfile)

FROM node:20-alpine AS builder

WORKDIR /app
COPY pnpm-lock.yaml package.json ./
COPY patches ./patches
COPY client/ ./client
COPY server/ ./server
COPY shared/ ./shared
COPY vite.config.ts tsconfig*.json ./

RUN pnpm install --frozen-lockfile
RUN pnpm build
# Output: dist/index.js + dist/public/

Runtime Stage

FROM node:20-alpine

COPY dist/ ./dist
COPY package.json pnpm-lock.yaml ./

RUN pnpm install --frozen-lockfile --prod
# Only prod dependencies, smaller image

CMD ["node", "dist/index.js"]
# Runs Express server on port 3000
# Serves static files from dist/public/

📊 Folder Organization for CI/CD

What Gets Built

client/         → ✅ Vite builds to dist/public/
server/         → ✅ esbuild bundles to dist/index.js
shared/         → ✅ Included in both builds
patches/        → ✅ Applied during install

What Gets Deployed

dist/
├── index.js                    ← Server code
└── public/                     ← Frontend assets
    ├── index.html
    └── assets/

What's Not in Docker

client/src/                     ← Source (not needed)
server/                         ← Source (bundled into dist/index.js)
shared/                         ← Source (bundled)
patches/                        ← Only for install
.github/                        ← CI/CD config
node_modules/                   ← Prod deps only installed
tsconfig.json                   ← Build config (not needed)
vite.config.ts                  ← Build config (not needed)

✅ Workflow Compatibility Check

File Purpose Used by Workflows Status
vite.config.ts Frontend build ✅ Yes ✅ Configured
server/index.ts Backend entry ✅ Yes ✅ Bundled
client/src/ Frontend source ✅ Yes ✅ Built
shared/ Shared types ✅ Yes ✅ Included
package.json Dependencies ✅ Yes ✅ Locked
pnpm-lock.yaml Dependency lock ✅ Yes ✅ Verified
patches/ Patches ✅ Yes ✅ Applied
railway.json Deployment config ⚠️ Optional See below
tsconfig.json TypeScript config ✅ Yes ✅ Used
template.json Template config ❌ No Not needed
components.json Component config ❌ No Not needed

🚢 Deployment Options

Option 1: Manual SSH (Default in our workflows)

GitHub → Build → SSH to server → Deploy → Running

Pros: Full control, no vendor lock-in
Cons: Need to manage server

Option 2: Railway (You have railway.json!)

GitHub → Build → Push to Railway → Deploy → Running

Pros: Easier, managed platform
Cons: Vendor lock-in, need Railway account

Option 3: Docker Registry

GitHub → Build → Build Docker → Push to registry → Deploy

Pros: Platform-agnostic
Cons: More complex setup

📈 Expected Build Times

Step Time Details
Install 30-60s First run cached after
Type Check 2-3s client/ + server/ + shared/
Vite Build 15-20s client/ with TailwindCSS
esbuild 2-3s server/ bundling
Verify 2s Check output files
Security 3-5s Audit + scan
Total 40-50s First run with cache

🎯 What Workflows Do Now

1. Type Checking

pnpm check

Checks:

  • ✅ client/src/** TypeScript
  • ✅ server/** TypeScript
  • ✅ shared/** TypeScript

2. Build

pnpm build

Produces:

  • ✅ dist/public/** (Frontend)
  • ✅ dist/index.js (Server)

3. Deployment

node dist/index.js

Runs:

  • ✅ Express server on port 3000
  • ✅ Serves dist/public/** as static
  • ✅ API routes from server/

🔍 What Gets Deployed to Server

/home/deploy/app/
├── dist/
│   ├── index.js              ← Server starts here
│   └── public/               ← Static files served
├── package.json
├── pnpm-lock.yaml
├── node_modules/             ← Prod deps only
└── ...

📝 GitHub Actions Integration

Your workflows handle:

1. Setup
   ├─ Checkout code
   ├─ Setup Node 20
   └─ Cache dependencies

2. Check
   ├─ Type check (pnpm check)
   ├─ Format check (prettier)
   └─ Build check (pnpm build)

3. Security
   ├─ Dependency audit
   └─ Vulnerability scan

4. Deploy (main branch only)
   ├─ SSH to server
   ├─ Git pull
   ├─ Install deps
   ├─ Build (pnpm build)
   └─ Restart (pm2 restart)

🎁 Your Specific Advantages

  1. Full-Stack in One Repo

    • Single pnpm install installs everything
    • Single build command creates both
  2. Shared Code

    • Types in shared/ used by client & server
    • No duplication
    • Built-in consistency
  3. Single Docker Image

    • One image contains everything
    • Easy to scale
    • Easy to deploy
  4. pnpm Workspace Ready

    • Already has patches/
    • Can add workspaces later if needed
    • Performance-optimized

✨ What's Already Configured

Build: pnpm build handles both client & server
Run: node dist/index.js starts the server
TypeScript: Works across all folders
Vite: Configured for client/ only
esbuild: Configured for server/ only
Patches: Applied automatically
Dependencies: Single lock file

🚀 Next Steps

  1. Verify locally (before pushing)

    pnpm install
    pnpm check
    pnpm build
    node dist/index.js
    
  2. Push workflows to GitHub

    git add .github/
    git commit -m "ci: add workflows"
    git push origin main
    
  3. Configure secrets (see GITHUB_ACTIONS_SETUP.md)

    STAGING_SERVER_HOST
    PRODUCTION_SERVER_HOST
    (etc...)
    
  4. Monitor first run

    https://github.com/bayzed123/bayezid_portfolio/actions
    

📚 Document Reading Order

  1. THIS FILE ← You are here
  2. CUSTOMIZATION_SUMMARY.md - What we customized
  3. VITE_QUICK_REFERENCE.md - Build specifics
  4. GITHUB_ACTIONS_SETUP.md - Deploy setup
  5. COMPLETE_WORKFLOWS_GUIDE.md - Full reference

✅ Checklist Before Deploying

  • Workflows are in .github/workflows/
  • pnpm build works locally
  • node dist/index.js starts your server
  • dist/public/ has your frontend
  • Secrets configured in GitHub
  • Server is accessible via SSH
  • Server has Node 20 + pnpm installed

TL;DR: Your repo has:

  • client/ → Vite builds this to dist/public/
  • server/ → esbuild bundles this to dist/index.js
  • shared/ → Included in both builds
  • Workflows build both, Docker packages both ✅

Ready to deploy! 🚀