# Company Website Template React + shadcn/ui + Express + PostgreSQL + Redis scaffold for SAAC deployment. ## Stack - **Frontend**: React 19 + Vite + TypeScript + TailwindCSS v4 + shadcn/ui - **Backend**: Express.js (Node 20) - **Database**: PostgreSQL 16 - **Cache**: Redis 7 - **Deploy**: Docker Compose via `saac deploy` ## Structure ``` ├── server.js # Express backend (API + serves React build) ├── client/ # React frontend (Vite + shadcn/ui) │ ├── src/ │ │ ├── components/ui/ # shadcn/ui components (Button, Card, Input, etc.) │ │ ├── lib/utils.ts # cn() utility for Tailwind class merging │ │ ├── pages/ # Page components │ │ ├── App.tsx # Router │ │ └── main.tsx # Entry point │ ├── components.json # shadcn/ui config │ ├── vite.config.ts # Vite config with path aliases │ └── package.json # Client dependencies ├── docker-compose.yml # PostgreSQL + Redis + App (see comments inside) ├── Dockerfile # Multi-stage: build React → serve with Express ├── SAAC_DEPLOYMENT.md # Deployment rules — READ THIS FIRST └── package.json # Server dependencies ``` ## Development ```bash # Install all dependencies (postinstall auto-installs client deps) npm install # Run in dev mode (watches server.js + client/src, auto-rebuilds on changes) npm run dev # Or for local development with Vite HMR (browser hot-reload): npm run dev:local # Express :3000 + Vite :5173 concurrently # Or run separately: npm run dev:server # Express on :3000 (with nodemon auto-restart) npm run dev:client # Vite on :5173 (proxies /api to :3000) ``` ## Adding shadcn/ui Components ```bash cd client npx shadcn@latest add dialog # Add Dialog component npx shadcn@latest add table # Add Table component npx shadcn@latest add select # Add Select component ``` Import: `import { Button } from "@/components/ui/button"` ## Deploy ```bash saac deploy ``` See `SAAC_DEPLOYMENT.md` for deployment rules, common mistakes, and debugging commands. ## API Routes - `GET /health` — Health check (PostgreSQL + Redis) - `GET /api/status` — Example API endpoint - `GET /*` — React SPA (served from client/dist)