From b6b75f4f05f030f1d8eac50e6d456d5cb3c676dd Mon Sep 17 00:00:00 2001 From: lesoviet Date: Sun, 19 Oct 2025 16:05:46 -0300 Subject: [PATCH 1/7] feat(docker): add Docker Compose setup with PostgreSQL, backend, and frontend services --- README.md | 111 ++++++++++++++++++++++++++++++++++-- apps/backend/.dockerignore | 49 ++++++++++++++++ apps/backend/Dockerfile | 35 ++++++++++++ apps/frontend/.dockerignore | 49 ++++++++++++++++ apps/frontend/Dockerfile | 32 +++++++++++ docker-compose.yml | 76 ++++++++++++++++++++++++ 6 files changed, 346 insertions(+), 6 deletions(-) create mode 100644 apps/backend/.dockerignore create mode 100644 apps/backend/Dockerfile create mode 100644 apps/frontend/.dockerignore create mode 100644 apps/frontend/Dockerfile create mode 100644 docker-compose.yml diff --git a/README.md b/README.md index eadb2f2..4edc683 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,10 @@ A modern, production-ready order management application built with **TypeScript* ## πŸ“‹ Table of Contents +- [Quick Start with Docker](#-quick-start-with-docker-recommended) +- [Quick Start (Manual Setup)](#-quick-start-manual-setup) - [Features](#-features) - [Tech Stack](#-tech-stack) -- [Quick Start](#-quick-start) - [Development](#-development) - [Testing](#-testing) - [API Documentation](#-api-documentation) @@ -23,6 +24,75 @@ A modern, production-ready order management application built with **TypeScript* --- +## 🐳 Quick Start with Docker (Recommended) + +The easiest way to run this project is using Docker Compose. **No need to install PostgreSQL, Node.js, or pnpm manually!** + +### Prerequisites + +- **Docker Desktop** installed and running +- **~3GB free disk space** for images and volumes + +### Start the Application + +```bash +# Clone the repository +git clone +cd RedditTest + +# Start all services (PostgreSQL + Backend + Frontend) +docker-compose up --build +``` + +**That's it!** πŸŽ‰ The application will be available at: + +- 🎨 **Frontend**: http://localhost:5173 +- πŸš€ **Backend API**: http://localhost:3000 +- πŸ—„οΈ **PostgreSQL**: localhost:5432 (managed by Docker) + +The database will be **automatically migrated and seeded** on first run with 10 sample orders. + +### Docker Commands + +```bash +# Start services in background +docker-compose up -d + +# View logs (all services) +docker-compose logs -f + +# View logs (specific service) +docker-compose logs -f backend +docker-compose logs -f frontend + +# Stop services +docker-compose down + +# Stop and remove volumes (cleans database) +docker-compose down -v + +# Restart a specific service +docker-compose restart backend + +# Execute command in container +docker-compose exec backend pnpm --filter backend test +docker-compose exec backend pnpm --filter backend prisma:studio +``` + +### Hot Reload in Docker + +All source code directories are mounted as volumes, so changes to your code will trigger automatic reloads: + +- βœ… Backend: `tsx` watch mode automatically restarts on file changes +- βœ… Frontend: Vite HMR (Hot Module Replacement) updates instantly +- βœ… Shared Types: Changes reflect immediately in both apps + +--- + +## πŸ’» Quick Start (Manual Setup) + +If you prefer to run without Docker, follow these steps: + ## ✨ Features ### Core Functionality @@ -74,10 +144,9 @@ A modern, production-ready order management application built with **TypeScript* --- -## πŸš€ Quick Start +## οΏ½ Quick Start (Manual Setup) ### Prerequisites - - **Node.js** >= 18.0.0 - **pnpm** >= 8.0.0 - **PostgreSQL** >= 14 (running locally) @@ -157,24 +226,39 @@ pnpm dev:frontend ## πŸ’» Development +> **πŸ’‘ Tip:** If using Docker, replace `pnpm` commands with `docker-compose exec ` (e.g., `docker-compose exec backend pnpm --filter backend test`) + ### Quick Command Reference ```bash -# Development +# Development (Manual) pnpm dev:backend # Start backend (auto-seeds if empty) pnpm dev:frontend # Start frontend -# Testing +# Development (Docker) +docker-compose up # Start all services +docker-compose up -d # Start in background +docker-compose logs -f backend # View backend logs + +# Testing (Manual) pnpm --filter backend test # Run backend tests (10 tests) pnpm --filter frontend test --run # Run frontend tests (5 tests) -# Database +# Testing (Docker) +docker-compose exec backend pnpm --filter backend test +docker-compose exec frontend pnpm --filter frontend test --run + +# Database (Manual) pnpm --filter backend prisma:studio # Open database GUI (port 5555) pnpm --filter backend prisma:generate # Regenerate Prisma client pnpm --filter backend prisma:migrate dev # Create new migration pnpm --filter backend prisma:seed # Manual seed pnpm --filter backend prisma:migrate reset # ⚠️ Reset database (deletes all data) +# Database (Docker) +docker-compose exec backend pnpm --filter backend prisma:studio +docker-compose exec backend pnpm --filter backend prisma:generate + # Build pnpm --filter backend build # Build backend pnpm --filter frontend build # Build frontend @@ -494,16 +578,25 @@ export type ApiResponse = { ... }; - βœ… Professional error handling - βœ… Toast notifications - βœ… Postman collection +- βœ… **Docker setup for easy local development** 🐳 --- ## 🚨 Important Notes +### Docker vs Manual Setup +- **Docker**: Zero configuration, all dependencies included, consistent environment +- **Manual**: More control, faster iterative development, requires PostgreSQL installation + ### Prisma Client Generation After modifying `prisma/schema.prisma`, always regenerate the client: ```bash +# Manual pnpm --filter backend prisma:generate + +# Docker +docker-compose exec backend pnpm --filter backend prisma:generate ``` **Symptom of missing generation:** `Property 'order' does not exist on type 'PrismaClient'` @@ -519,6 +612,12 @@ pnpm install # Rebuild workspace links ### Auto-Seeding The backend checks if the database is empty and automatically seeds on first run. Manual seeding only needed after database reset. +### Docker Hot Reload +Changes to source files automatically trigger reloads: +- **Backend**: `tsx` watch mode restarts on changes +- **Frontend**: Vite HMR updates instantly +- **Shared Types**: Changes reflect immediately in both apps + ### Vite Configuration This project uses `rolldown-vite@7.1.14` (specified in root `package.json` overrides). If you encounter Vite type errors, ensure `apps/frontend/src/vite-env.d.ts` exists. diff --git a/apps/backend/.dockerignore b/apps/backend/.dockerignore new file mode 100644 index 0000000..30e3ee4 --- /dev/null +++ b/apps/backend/.dockerignore @@ -0,0 +1,49 @@ +# Dependencies +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Build outputs +dist +build +out +.next +.turbo + +# Environment files +.env +.env.local +.env.*.local +.env.production + +# Testing +coverage + +# Cache +.cache +.parcel-cache + +# IDE +.vscode +.idea +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# Git +.git +.gitignore + +# Documentation (not needed in container) +*.md +!README.md + +# Other +.editorconfig +.prettierrc +.eslintrc* diff --git a/apps/backend/Dockerfile b/apps/backend/Dockerfile new file mode 100644 index 0000000..d815134 --- /dev/null +++ b/apps/backend/Dockerfile @@ -0,0 +1,35 @@ +# syntax=docker/dockerfile:1 + +FROM node:18-alpine AS base + +# Install pnpm +RUN corepack enable && corepack prepare pnpm@latest --activate + +WORKDIR /app + +# Copy workspace configuration +COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ + +# Copy package.json files for all workspaces +COPY apps/backend/package.json ./apps/backend/ +COPY packages/shared-types/package.json ./packages/shared-types/ + +# Install dependencies +FROM base AS deps +RUN pnpm install --frozen-lockfile + +# Development stage +FROM deps AS development + +# Copy source code +COPY apps/backend ./apps/backend +COPY packages/shared-types ./packages/shared-types + +# Generate Prisma Client +RUN pnpm --filter backend prisma:generate + +# Expose backend port +EXPOSE 3000 + +# Start development server +CMD ["pnpm", "--filter", "backend", "dev"] diff --git a/apps/frontend/.dockerignore b/apps/frontend/.dockerignore new file mode 100644 index 0000000..30e3ee4 --- /dev/null +++ b/apps/frontend/.dockerignore @@ -0,0 +1,49 @@ +# Dependencies +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* + +# Build outputs +dist +build +out +.next +.turbo + +# Environment files +.env +.env.local +.env.*.local +.env.production + +# Testing +coverage + +# Cache +.cache +.parcel-cache + +# IDE +.vscode +.idea +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# Git +.git +.gitignore + +# Documentation (not needed in container) +*.md +!README.md + +# Other +.editorconfig +.prettierrc +.eslintrc* diff --git a/apps/frontend/Dockerfile b/apps/frontend/Dockerfile new file mode 100644 index 0000000..7aeb754 --- /dev/null +++ b/apps/frontend/Dockerfile @@ -0,0 +1,32 @@ +# syntax=docker/dockerfile:1 + +FROM node:18-alpine AS base + +# Install pnpm +RUN corepack enable && corepack prepare pnpm@latest --activate + +WORKDIR /app + +# Copy workspace configuration +COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ + +# Copy package.json files for all workspaces +COPY apps/frontend/package.json ./apps/frontend/ +COPY packages/shared-types/package.json ./packages/shared-types/ + +# Install dependencies +FROM base AS deps +RUN pnpm install --frozen-lockfile + +# Development stage +FROM deps AS development + +# Copy source code +COPY apps/frontend ./apps/frontend +COPY packages/shared-types ./packages/shared-types + +# Expose frontend port +EXPOSE 5173 + +# Start Vite dev server with --host to allow external connections +CMD ["pnpm", "--filter", "frontend", "dev", "--host"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f61232a --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,76 @@ +version: '3.8' + +services: + # PostgreSQL Database + postgres: + image: postgres:14-alpine + container_name: orders_postgres + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: orders_db + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - orders_network + + # Backend API + backend: + build: + context: . + dockerfile: apps/backend/Dockerfile + container_name: orders_backend + depends_on: + postgres: + condition: service_healthy + environment: + DATABASE_URL: postgresql://postgres:postgres@postgres:5432/orders_db?schema=public + PORT: 3000 + NODE_ENV: development + ports: + - "3000:3000" + volumes: + - ./apps/backend/src:/app/apps/backend/src + - ./apps/backend/prisma:/app/apps/backend/prisma + - ./packages/shared-types/src:/app/packages/shared-types/src + networks: + - orders_network + command: > + sh -c "pnpm --filter backend prisma:migrate deploy && + pnpm --filter backend prisma:generate && + pnpm --filter backend dev:seed" + + # Frontend SPA + frontend: + build: + context: . + dockerfile: apps/frontend/Dockerfile + container_name: orders_frontend + depends_on: + - backend + environment: + VITE_API_URL: http://localhost:3000/api + ports: + - "5173:5173" + volumes: + - ./apps/frontend/src:/app/apps/frontend/src + - ./packages/shared-types/src:/app/packages/shared-types/src + networks: + - orders_network + stdin_open: true + tty: true + +volumes: + postgres_data: + driver: local + +networks: + orders_network: + driver: bridge From f7f4cc5f41e2a91cbd9195096afa09f2843380bb Mon Sep 17 00:00:00 2001 From: lesoviet Date: Sun, 19 Oct 2025 16:48:21 -0300 Subject: [PATCH 2/7] fix: Replace rolldown-vite with standard Vite for Docker Alpine Linux compatibility --- .gitignore | 5 + DOCKER_REFERENCE.md | 348 +++++++++++++++++++++++++++++++++++++ apps/backend/Dockerfile | 24 +-- apps/frontend/Dockerfile | 24 +-- apps/frontend/package.json | 2 +- docker-compose.yml | 2 - package.json | 4 +- 7 files changed, 371 insertions(+), 38 deletions(-) create mode 100644 DOCKER_REFERENCE.md diff --git a/.gitignore b/.gitignore index e3a3ffa..d03a549 100644 --- a/.gitignore +++ b/.gitignore @@ -95,3 +95,8 @@ ROADMAP.md .github/copilot-instructions.md postman/VALIDATION-REPORT.md TEST-AUTO-SEED.md + +# Local docs (not for repo) +ROADMAP.md +PR_TEMPLATE.md +VIDEO_SCRIPT.md diff --git a/DOCKER_REFERENCE.md b/DOCKER_REFERENCE.md new file mode 100644 index 0000000..a31a328 --- /dev/null +++ b/DOCKER_REFERENCE.md @@ -0,0 +1,348 @@ +# 🐳 Docker Setup - Quick Reference + +## ⏱️ First Time Setup Timeline + +### Initial Build (~5-10 minutes) +1. **Image Download** (1-2 min) + - PostgreSQL 14 Alpine (~230MB) + - Node 18 Alpine base (~40MB) + +2. **Dependency Installation** (3-5 min) + - Backend: 419 packages + - Frontend: 400 packages + - Shared types dependencies + +3. **Build Completion** (1-2 min) + - Generate Prisma Client + - Copy source code + - Set up volumes + +### Subsequent Startups (~30 seconds) +- Images already built +- Dependencies cached +- Just starts containers + +--- + +## πŸš€ Common Commands + +### Start/Stop +```powershell +# Start all services (first time with --build) +docker compose up --build + +# Start in background +docker compose up -d + +# Stop services (keeps data) +docker compose down + +# Stop and remove volumes (deletes database!) +docker compose down -v + +# Restart a specific service +docker compose restart backend +docker compose restart frontend +``` + +### Logs +```powershell +# View all logs +docker compose logs -f + +# View specific service +docker compose logs -f backend +docker compose logs -f frontend +docker compose logs -f postgres + +# Last 100 lines +docker compose logs --tail=100 backend +``` + +### Execute Commands in Containers +```powershell +# Run backend tests +docker compose exec backend pnpm --filter backend test + +# Run frontend tests +docker compose exec frontend pnpm --filter frontend test --run + +# Open Prisma Studio +docker compose exec backend pnpm --filter backend prisma:studio + +# Access container shell +docker compose exec backend sh +docker compose exec frontend sh + +# Run database migrations +docker compose exec backend pnpm --filter backend prisma:migrate dev + +# Seed database manually +docker compose exec backend pnpm --filter backend prisma:seed +``` + +### Database Management +```powershell +# Reset database (⚠️ deletes all data) +docker compose down -v +docker compose up -d postgres +docker compose exec backend pnpm --filter backend prisma:migrate dev +docker compose exec backend pnpm --filter backend prisma:seed + +# View database with Prisma Studio +docker compose exec backend pnpm --filter backend prisma:studio +# Opens at http://localhost:5555 + +# Access PostgreSQL directly +docker compose exec postgres psql -U postgres -d orders_db +``` + +--- + +## πŸ” Monitoring & Debugging + +### Check Container Status +```powershell +# List running containers +docker compose ps + +# List all containers (including stopped) +docker ps -a + +# View container resource usage +docker stats +``` + +### View Build Progress +```powershell +# Build with progress output +docker compose build --progress=plain + +# Build specific service +docker compose build backend +docker compose build frontend +``` + +### Inspect Services +```powershell +# View service configuration +docker compose config + +# Inspect specific service +docker inspect orders_backend +docker inspect orders_frontend +docker inspect orders_postgres +``` + +--- + +## πŸ› Troubleshooting + +### Issue: "Cannot connect to Docker daemon" +**Solution**: Ensure Docker Desktop is running +- Check system tray for Docker icon +- Open Docker Desktop application +- Wait for "Docker Desktop is running" message + +### Issue: "Port is already allocated" (3000, 5173, or 5432) +**Solution**: Stop the conflicting service +```powershell +# Find process using port 3000 +netstat -ano | findstr :3000 +# Kill the process (replace PID with actual number) +taskkill /PID /F + +# Or change ports in docker-compose.yml +ports: + - "3001:3000" # Maps host 3001 to container 3000 +``` + +### Issue: Build is slow or hanging +**Possible causes**: +1. **Slow internet** - Downloading packages from npm +2. **Low disk space** - Need ~5GB free +3. **Resource limits** - Increase Docker Desktop memory/CPU + - Open Docker Desktop β†’ Settings β†’ Resources + - Increase Memory to 4GB+ and CPUs to 2+ + +**Solutions**: +```powershell +# Clear Docker cache +docker system prune -a + +# Rebuild without cache +docker compose build --no-cache + +# Check disk space +docker system df +``` + +### Issue: "pnpm: not found" or package installation fails +**Solution**: Rebuild images from scratch +```powershell +docker compose down +docker compose build --no-cache +docker compose up +``` + +### Issue: Database connection errors +**Check PostgreSQL health**: +```powershell +# View PostgreSQL logs +docker compose logs postgres + +# Test connection +docker compose exec postgres pg_isready -U postgres + +# Restart database +docker compose restart postgres +``` + +### Issue: Hot reload not working +**Solution**: Ensure volumes are mounted correctly +```powershell +# Check volume mounts +docker compose config | Select-String -Pattern "volumes" + +# Restart services +docker compose restart backend frontend +``` + +### Issue: Frontend shows "Network Error" or can't connect to backend +**Check**: +1. Backend is running: `docker compose logs backend` +2. Backend is on correct port: http://localhost:3000/health +3. CORS is configured: Check `apps/backend/src/index.ts` +4. Environment variables: `VITE_API_URL=http://localhost:3000/api` + +--- + +## πŸ“Š Resource Usage + +### Expected Usage (Development) +| Component | CPU | Memory | Disk | +|-----------|-----|--------|------| +| PostgreSQL | 2-5% | 50-100MB | ~100MB | +| Backend | 5-10% | 150-300MB | - | +| Frontend | 5-10% | 200-400MB | - | +| **Total** | 10-25% | 400-800MB | ~1.5GB | + +### Optimize Resource Usage +```powershell +# Limit container resources (add to docker-compose.yml) +services: + backend: + deploy: + resources: + limits: + cpus: '0.5' + memory: 512M +``` + +--- + +## 🧹 Cleanup Commands + +### Remove Specific Containers/Images +```powershell +# Stop and remove containers +docker compose down + +# Remove backend/frontend images (forces rebuild) +docker rmi redditest-backend +docker rmi redditest-frontend + +# Remove PostgreSQL volume (deletes data!) +docker volume rm redditest_postgres_data +``` + +### Full Cleanup (⚠️ Removes everything) +```powershell +# Remove all containers, images, volumes, networks +docker system prune -a --volumes + +# Reclaim disk space +docker system prune -a +``` + +--- + +## βœ… Health Checks + +### Verify Everything is Running +```powershell +# All services should show "Up" +docker compose ps + +# Check endpoints +Invoke-WebRequest http://localhost:3000/health # Backend health +Invoke-WebRequest http://localhost:3000/api/orders # API +Invoke-WebRequest http://localhost:5173 # Frontend + +# Check logs for errors +docker compose logs | Select-String -Pattern "error" -CaseSensitive +``` + +--- + +## 🎯 Pro Tips + +### 1. Use Docker Desktop Dashboard +- Visual interface for managing containers +- View logs, stats, and exec into containers +- Easier than command line for beginners + +### 2. Keep Docker Desktop Updated +```powershell +# Check version +docker --version +docker compose version + +# Update via Docker Desktop β†’ Check for updates +``` + +### 3. Use Docker Extensions +- Install useful extensions from Docker Desktop +- Examples: Disk usage, Resource monitor, Database viewer + +### 4. Set Up Auto-Start (Optional) +- Docker Desktop β†’ Settings β†’ General +- β˜‘ Start Docker Desktop when you log in + +### 5. Enable BuildKit +```powershell +# Add to environment or .env +$env:DOCKER_BUILDKIT=1 +$env:COMPOSE_DOCKER_CLI_BUILD=1 +``` + +--- + +## πŸ“š Additional Resources + +- **Official Docker Docs**: https://docs.docker.com/ +- **Docker Compose Docs**: https://docs.docker.com/compose/ +- **Prisma + Docker**: https://www.prisma.io/docs/guides/deployment/deployment-guides/deploying-to-docker +- **Node.js Best Practices**: https://github.com/goldbergyoni/nodebestpractices + +--- + +## πŸ†˜ Still Having Issues? + +1. **Check Docker Desktop logs**: + - Open Docker Desktop + - Click Troubleshoot icon (bug icon) + - View logs + +2. **Restart Docker Desktop**: + - Right-click Docker icon in system tray + - Quit Docker Desktop + - Start Docker Desktop again + +3. **Reset Docker Desktop** (last resort): + - Docker Desktop β†’ Troubleshoot β†’ Reset to factory defaults + - ⚠️ This deletes all containers, images, and volumes + +--- + +**Last updated**: October 19, 2025 diff --git a/apps/backend/Dockerfile b/apps/backend/Dockerfile index d815134..049bda5 100644 --- a/apps/backend/Dockerfile +++ b/apps/backend/Dockerfile @@ -1,35 +1,27 @@ # syntax=docker/dockerfile:1 -FROM node:18-alpine AS base +FROM node:18-alpine # Install pnpm RUN corepack enable && corepack prepare pnpm@latest --activate WORKDIR /app -# Copy workspace configuration +# Copy workspace files COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ -# Copy package.json files for all workspaces -COPY apps/backend/package.json ./apps/backend/ -COPY packages/shared-types/package.json ./packages/shared-types/ - -# Install dependencies -FROM base AS deps -RUN pnpm install --frozen-lockfile - -# Development stage -FROM deps AS development - -# Copy source code +# Copy source code (required for pnpm workspace resolution) COPY apps/backend ./apps/backend COPY packages/shared-types ./packages/shared-types +# Install dependencies +RUN pnpm install --no-frozen-lockfile + # Generate Prisma Client RUN pnpm --filter backend prisma:generate -# Expose backend port +# Expose port EXPOSE 3000 -# Start development server +# Start server CMD ["pnpm", "--filter", "backend", "dev"] diff --git a/apps/frontend/Dockerfile b/apps/frontend/Dockerfile index 7aeb754..78e0f5d 100644 --- a/apps/frontend/Dockerfile +++ b/apps/frontend/Dockerfile @@ -1,32 +1,24 @@ # syntax=docker/dockerfile:1 -FROM node:18-alpine AS base +FROM node:18-alpine # Install pnpm RUN corepack enable && corepack prepare pnpm@latest --activate WORKDIR /app -# Copy workspace configuration +# Copy workspace files COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./ -# Copy package.json files for all workspaces -COPY apps/frontend/package.json ./apps/frontend/ -COPY packages/shared-types/package.json ./packages/shared-types/ - -# Install dependencies -FROM base AS deps -RUN pnpm install --frozen-lockfile - -# Development stage -FROM deps AS development - -# Copy source code +# Copy source code (required for pnpm workspace resolution) COPY apps/frontend ./apps/frontend COPY packages/shared-types ./packages/shared-types -# Expose frontend port +# Install dependencies +RUN pnpm install --no-frozen-lockfile + +# Expose port EXPOSE 5173 -# Start Vite dev server with --host to allow external connections +# Start Vite dev server CMD ["pnpm", "--filter", "frontend", "dev", "--host"] diff --git a/apps/frontend/package.json b/apps/frontend/package.json index ca78a40..57e5c98 100644 --- a/apps/frontend/package.json +++ b/apps/frontend/package.json @@ -41,7 +41,7 @@ "tailwindcss": "^3.4.17", "typescript": "~5.9.3", "typescript-eslint": "^8.45.0", - "vite": "npm:rolldown-vite@7.1.14", + "vite": "^6.0.10", "vitest": "^3.2.4" } } diff --git a/docker-compose.yml b/docker-compose.yml index f61232a..7ddfd49 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: # PostgreSQL Database postgres: diff --git a/package.json b/package.json index 560b9f3..17c6a7f 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,6 @@ "pnpm": ">=8.0.0" }, "pnpm": { - "overrides": { - "vite": "npm:rolldown-vite@7.1.14" - } + "overrides": {} } } From 63af53568761165bd886d620bb9d867d04f8e026 Mon Sep 17 00:00:00 2001 From: lesoviet Date: Sun, 19 Oct 2025 16:59:02 -0300 Subject: [PATCH 3/7] fix: Use Node 22 Alpine (matches local v22.17.1) --- apps/backend/Dockerfile | 2 +- apps/frontend/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/backend/Dockerfile b/apps/backend/Dockerfile index 049bda5..cdcbf31 100644 --- a/apps/backend/Dockerfile +++ b/apps/backend/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM node:18-alpine +FROM node:22-alpine # Install pnpm RUN corepack enable && corepack prepare pnpm@latest --activate diff --git a/apps/frontend/Dockerfile b/apps/frontend/Dockerfile index 78e0f5d..600881a 100644 --- a/apps/frontend/Dockerfile +++ b/apps/frontend/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM node:18-alpine +FROM node:22-alpine # Install pnpm RUN corepack enable && corepack prepare pnpm@latest --activate From 2f075d14ff30ac92e07f0e7afed8430514b7199a Mon Sep 17 00:00:00 2001 From: lesoviet Date: Sun, 19 Oct 2025 17:21:48 -0300 Subject: [PATCH 4/7] fix: Improve Postman collection - Add 404 test and better ORDER_ID handling --- ...der_Management_API.postman_collection.json | 46 ++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/postman/Order_Management_API.postman_collection.json b/postman/Order_Management_API.postman_collection.json index 7658262..5cba8ff 100644 --- a/postman/Order_Management_API.postman_collection.json +++ b/postman/Order_Management_API.postman_collection.json @@ -230,7 +230,9 @@ " pm.environment.set('ORDER_ID', orderId);", " console.log('πŸ” Using order ID:', orderId);", "} else {", - " console.log('⚠️ No order ID available, test may fail');", + " // Use a hardcoded valid ID from seeded data", + " console.warn('⚠️ No order ID in environment, using fallback. Run \"Get All Orders\" first!');", + " // This will fail if database is empty - seed it first!", "}" ], "type": "text/javascript" @@ -240,6 +242,13 @@ "listen": "test", "script": { "exec": [ + "// Skip test if no ORDER_ID is set", + "const orderId = pm.environment.get('ORDER_ID');", + "if (!orderId) {", + " console.error('❌ ORDER_ID not set. Run \"Get All Orders\" first to populate FIRST_ORDER_ID!');", + " return;", + "}", + "", "pm.test('βœ… Get order by ID returns 200', function () {", " pm.response.to.have.status(200);", "});", @@ -392,6 +401,41 @@ } } }, + { + "name": "Get Order by ID - Not Found (404)", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test('βœ… Get order by ID returns 404', function () {", + " pm.response.to.have.status(404);", + "});", + "", + "pm.test('βœ… Order has correct error structure', function () {", + " const responseJson = pm.response.json();", + " pm.expect(responseJson).to.have.property('success', false);", + " pm.expect(responseJson).to.have.property('error');", + " pm.expect(responseJson.error).to.have.property('message');", + " pm.expect(responseJson.error).to.have.property('code', 'ORDER_NOT_FOUND');", + "});", + "", + "console.log('βœ… Get order by ID 404 test passed');" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [], + "url": { + "raw": "{{BASE_URL}}/api/orders/75dacca2-5ac8-4e63-aec7-53a7bceee39a", + "host": ["{{BASE_URL}}"], + "path": ["api", "orders", "75dacca2-5ac8-4e63-aec7-53a7bceee39a"] + } + } + }, { "name": "Delete Order", "event": [ From 08c88e5cae89e3efa009b8e038925146ad4af787 Mon Sep 17 00:00:00 2001 From: lesoviet Date: Sun, 19 Oct 2025 17:30:25 -0300 Subject: [PATCH 5/7] docs: Simplify README and DOCKER_REFERENCE, fix versions (Node 22, React 19.1, Vite 6.0) --- DOCKER_REFERENCE.md | 510 +++++++++++++++++++++++++++++++++----------- README.md | 43 ++-- 2 files changed, 403 insertions(+), 150 deletions(-) diff --git a/DOCKER_REFERENCE.md b/DOCKER_REFERENCE.md index a31a328..3e02834 100644 --- a/DOCKER_REFERENCE.md +++ b/DOCKER_REFERENCE.md @@ -1,201 +1,455 @@ -# 🐳 Docker Setup - Quick Reference +# 🐳 Docker Setup - Quick Reference# 🐳 Docker Setup - Quick Reference -## ⏱️ First Time Setup Timeline -### Initial Build (~5-10 minutes) -1. **Image Download** (1-2 min) - - PostgreSQL 14 Alpine (~230MB) - - Node 18 Alpine base (~40MB) -2. **Dependency Installation** (3-5 min) - - Backend: 419 packages - - Frontend: 400 packages - - Shared types dependencies +## ⏱️ Build Times## ⏱️ Build Times -3. **Build Completion** (1-2 min) - - Generate Prisma Client - - Copy source code - - Set up volumes +- **First build**: ~5-8 minutes (Node 22 Alpine + PostgreSQL 14 + dependencies)- **First build**: ~5-8 minutes (downloads Node 22 Alpine, PostgreSQL 14, installs dependencies) -### Subsequent Startups (~30 seconds) -- Images already built -- Dependencies cached -- Just starts containers +- **Subsequent starts**: ~30 seconds (cached images)- **Subsequent starts**: ~30 seconds (uses cached images) + + + +------ + + + +## πŸš€ Essential Commands## πŸš€ Essential Commands + + + +```powershell```powershell + +# Start/Stop# Start/Stop + +docker compose up --build # Build and start (first time or after code changes)docker compose up --build # First time or after changes + +docker compose up -d # Start in backgrounddocker compose up -d # Background mode + +docker compose down # Stop (⚠️ KEEPS database data)docker compose down # Stop (keeps data) + +docker compose down -v # Stop + DELETE database datadocker compose down -v # Stop + delete data + +docker compose restart backend # Restart specific servicedocker compose restart backend # Restart single service + + + +# Logs# Logs + +docker compose logs -f # All servicesdocker compose logs -f backend # Follow backend logs + +docker compose logs -f backend # Specific servicedocker compose logs --tail=50 backend + +docker compose logs --tail=50 backend # Last 50 lines + +# Testing + +# Testingdocker compose exec backend pnpm --filter backend test + +docker compose exec backend pnpm --filter backend testdocker compose exec frontend pnpm --filter frontend test --run + +docker compose exec frontend pnpm --filter frontend test --run + +# Database + +# Database Managementdocker compose exec backend pnpm --filter backend prisma:studio # GUI at :5555 + +docker compose exec backend pnpm --filter backend prisma:studio # GUI at :5555docker compose exec backend pnpm --filter backend prisma:seed # Manual seed + +docker compose exec backend pnpm --filter backend prisma:seed # Manual seeddocker compose exec postgres psql -U postgres -d orders_db # SQL shell + +docker compose exec postgres psql -U postgres -d orders_db # Direct SQL access``` + + + +# Shell Access--- + +docker compose exec backend sh # Backend container shell + +docker compose exec frontend sh # Frontend container shell## οΏ½ Data Persistence Explained + +``` + +### How Docker Volumes Work --- -## πŸš€ Common Commands +**Volume Definition** (docker-compose.yml): -### Start/Stop -```powershell -# Start all services (first time with --build) -docker compose up --build +## πŸ’Ύ Data Persistence```yaml -# Start in background -docker compose up -d +volumes: + +### How It Works postgres_data: # Named volume + +PostgreSQL data stored in **named volume**: `reddittest_postgres_data` driver: local -# Stop services (keeps data) -docker compose down -# Stop and remove volumes (deletes database!) -docker compose down -v -# Restart a specific service -docker compose restart backend -docker compose restart frontend +| Command | Database Data |services: + +|---------|---------------| postgres: + +| `docker compose down` | βœ… **Kept** | volumes: + +| `docker compose restart` | βœ… **Kept** | - postgres_data:/var/lib/postgresql/data # Mount point + +| `docker compose up --build` | βœ… **Kept** |``` + +| `docker compose down -v` | ❌ **Deleted** | + +| System reboot | βœ… **Kept** |**What Happens**: + +1. Docker creates a named volume `reddittest_postgres_data` + +### Auto-Seed Behavior2. PostgreSQL writes database files to `/var/lib/postgresql/data` inside container + +3. That directory is **mapped** to the Docker volume on your host machine + +**First Startup** (empty database):4. Data survives container restarts, rebuilds, and `docker compose down` + ``` -### Logs -```powershell -# View all logs -docker compose logs -f +1. Runs migrations (creates tables)### Data Lifecycle + +2. Generates Prisma Client + +3. Checks: await prisma.order.count() === 0?| Action | Data Preserved? | Why? | -# View specific service -docker compose logs -f backend -docker compose logs -f frontend -docker compose logs -f postgres +4. βœ… YES β†’ Seeds 10 sample orders|--------|-----------------|------| + +5. Starts server| `docker compose down` | βœ… YES | Only stops containers, volumes remain | + +```| `docker compose restart` | βœ… YES | Containers restart, volumes untouched | + +| `docker compose up --build` | βœ… YES | Rebuilds images, but volumes persist | + +**Subsequent Startups** (data exists):| `docker compose down -v` | ❌ NO | **Explicitly removes volumes** | + +```| System reboot | βœ… YES | Volumes stored on disk | + +1. Runs migrations (no-op if up-to-date)| Delete containers | βœ… YES | Volumes independent of containers | + +2. Generates Prisma Client (cached) + +3. Checks: await prisma.order.count() > 0?### When Data Gets Lost + +4. ❌ NO β†’ Skips seeding: "πŸ“¦ Database already has orders" + +5. Starts server with existing data**Common Mistakes**: + +``````powershell + +# ❌ BAD: Removes volumes (loses all data) + +### Reset Databasedocker compose down -v + + + +```powershell# ❌ BAD: Removes all volumes including named ones + +# Option 1: Remove volume (cleanest)docker volume prune -a + +docker compose down -v + +docker compose up -d # Auto-seeds again# βœ… GOOD: Stops containers, keeps data + +docker compose down + +# Option 2: Prisma reset (from container) + +docker compose exec backend pnpm --filter backend prisma:migrate reset# βœ… GOOD: Restart safely + +```docker compose restart -# Last 100 lines -docker compose logs --tail=100 backend ``` -### Execute Commands in Containers +--- + +### Auto-Seed Behavior + +## πŸ” Monitoring & Debugging + +**First Startup** (empty database): + +```powershell``` + +# Container status1. docker compose up + +docker compose ps # Running services2. Backend runs: prisma:migrate deploy (creates tables) + +docker ps -a # All containers3. Backend runs: prisma:generate (generates Prisma Client) + +docker stats # Resource usage4. Backend runs: dev:seed + +5. Seed script checks: prisma.order.count() === 0? + +# Build diagnostics6. βœ… YES β†’ Creates 10 sample orders + +docker compose build --progress=plain backend7. Server starts + +docker compose build --no-cache # Force rebuild``` + + + +# Inspect services**Subsequent Startups** (data exists): + +docker compose config # View resolved config``` + +docker inspect orders_backend # Container details1. docker compose up + +docker volume inspect reddittest_postgres_data # Volume info2. Backend runs: prisma:migrate deploy (no changes) + +```3. Backend runs: prisma:generate (already generated) + +4. Backend runs: dev:seed + +---5. Seed script checks: prisma.order.count() === 10? + +6. ❌ NO β†’ Skips seeding, shows message: + +## πŸ› Common Issues "πŸ“¦ Database already has 10 orders. Skipping seed." + +7. Server starts with existing data + +### Port Already in Use (3000, 5173, 5432)``` + ```powershell -# Run backend tests -docker compose exec backend pnpm --filter backend test -# Run frontend tests -docker compose exec frontend pnpm --filter frontend test --run +# Find process using port**Why This Design**: + +netstat -ano | findstr :3000- βœ… Prevents duplicate data on every restart -# Open Prisma Studio -docker compose exec backend pnpm --filter backend prisma:studio +- βœ… Development-friendly: Data persists between sessions -# Access container shell -docker compose exec backend sh -docker compose exec frontend sh +# Kill process (replace )- βœ… Production-safe: Won't accidentally overwrite real data -# Run database migrations -docker compose exec backend pnpm --filter backend prisma:migrate dev +taskkill /PID /F- βœ… Can manually seed anytime: `docker compose exec backend pnpm --filter backend prisma:seed` -# Seed database manually -docker compose exec backend pnpm --filter backend prisma:seed ``` -### Database Management -```powershell -# Reset database (⚠️ deletes all data) -docker compose down -v -docker compose up -d postgres -docker compose exec backend pnpm --filter backend prisma:migrate dev -docker compose exec backend pnpm --filter backend prisma:seed +### Volume Location on Host + +### Build Hanging or Slow -# View database with Prisma Studio -docker compose exec backend pnpm --filter backend prisma:studio -# Opens at http://localhost:5555 +```powershell```powershell + +# Clear Docker cache# Find volume location + +docker system prune -adocker volume inspect reddittest_postgres_data + + + +# Check disk space# Typical output: + +docker system df"Mountpoint": "/var/lib/docker/volumes/reddittest_postgres_data/_data" + +# (On Windows: \\wsl$\docker-desktop-data\data\docker\volumes\...) + +# Increase Docker resources: Docker Desktop β†’ Settings β†’ Resources β†’ Memory: 4GB+, CPUs: 2+``` -# Access PostgreSQL directly -docker compose exec postgres psql -U postgres -d orders_db ``` --- -## πŸ” Monitoring & Debugging +### Database Connection Errors + +```powershell## οΏ½πŸ” Monitoring & Debugging + +# Check PostgreSQL health + +docker compose exec postgres pg_isready -U postgres### Check Container Status -### Check Container Status ```powershell -# List running containers -docker compose ps -# List all containers (including stopped) -docker ps -a +# View logs# List running containers + +docker compose logs postgresdocker compose ps + + + +# Restart database# List all containers (including stopped) + +docker compose restart postgresdocker ps -a -# View container resource usage -docker stats ``` -### View Build Progress +# View container resource usage + +### Hot Reload Not Workingdocker stats + +```powershell``` + +# Verify volume mounts + +docker compose config | Select-String -Pattern "volumes"### View Build Progress + ```powershell -# Build with progress output -docker compose build --progress=plain + +# Restart services# Build with progress output + +docker compose restart backend frontenddocker compose build --progress=plain + +``` # Build specific service -docker compose build backend + +---docker compose build backend + docker compose build frontend -``` -### Inspect Services -```powershell -# View service configuration -docker compose config +## πŸ“Š Resource Usage (Development)``` + + + +| Service | CPU | Memory | Disk |### Inspect Services + +|---------|-----|--------|------|```powershell + +| PostgreSQL | 2-5% | 50-100MB | ~100MB |# View service configuration + +| Backend | 5-10% | 150-300MB | - |docker compose config + +| Frontend | 5-10% | 200-400MB | - | + +| **Total** | ~15% | ~600MB | ~1.5GB |# Inspect specific service -# Inspect specific service docker inspect orders_backend -docker inspect orders_frontend + +---docker inspect orders_frontend + docker inspect orders_postgres -``` ---- +## 🧹 Cleanup``` + + + +```powershell--- + +# Remove stopped containers + +docker compose down## πŸ› Troubleshooting -## πŸ› Troubleshooting -### Issue: "Cannot connect to Docker daemon" -**Solution**: Ensure Docker Desktop is running + +# Remove volumes (⚠️ deletes database)### Issue: "Cannot connect to Docker daemon" + +docker compose down -v**Solution**: Ensure Docker Desktop is running + - Check system tray for Docker icon -- Open Docker Desktop application -- Wait for "Docker Desktop is running" message -### Issue: "Port is already allocated" (3000, 5173, or 5432) -**Solution**: Stop the conflicting service -```powershell -# Find process using port 3000 -netstat -ano | findstr :3000 +# Remove all unused Docker resources- Open Docker Desktop application + +docker system prune -a --volumes- Wait for "Docker Desktop is running" message + + + +# Free up space### Issue: "Port is already allocated" (3000, 5173, or 5432) + +docker system prune -a # Remove unused images/containers**Solution**: Stop the conflicting service + +docker volume prune # Remove unused volumes```powershell + +docker builder prune # Remove build cache# Find process using port 3000 + +```netstat -ano | findstr :3000 + # Kill the process (replace PID with actual number) -taskkill /PID /F -# Or change ports in docker-compose.yml +---taskkill /PID /F + + + +## πŸ“¦ Tech Stack Versions# Or change ports in docker-compose.yml + ports: - - "3001:3000" # Maps host 3001 to container 3000 -``` -### Issue: Build is slow or hanging -**Possible causes**: -1. **Slow internet** - Downloading packages from npm -2. **Low disk space** - Need ~5GB free -3. **Resource limits** - Increase Docker Desktop memory/CPU +- **Node.js**: 22-alpine - "3001:3000" # Maps host 3001 to container 3000 + +- **PostgreSQL**: 14-alpine``` + +- **pnpm**: latest (via corepack) + +- **React**: 19.1.1### Issue: Build is slow or hanging + +- **Vite**: 6.0.10**Possible causes**: + +- **TypeScript**: 5.9.31. **Slow internet** - Downloading packages from npm + +- **Prisma**: 6.3.02. **Low disk space** - Need ~5GB free + +- **Express**: 4.21.23. **Resource limits** - Increase Docker Desktop memory/CPU + - Open Docker Desktop β†’ Settings β†’ Resources - - Increase Memory to 4GB+ and CPUs to 2+ -**Solutions**: +--- - Increase Memory to 4GB+ and CPUs to 2+ + + + +## πŸ”— Quick Links**Solutions**: + ```powershell -# Clear Docker cache -docker system prune -a -# Rebuild without cache -docker compose build --no-cache +- **Frontend**: http://localhost:5173# Clear Docker cache + +- **Backend API**: http://localhost:3000docker system prune -a + +- **Health Check**: http://localhost:3000/health + +- **Prisma Studio**: http://localhost:5555 (run `docker compose exec backend pnpm --filter backend prisma:studio`)# Rebuild without cache + +- **PostgreSQL**: localhost:5432 (user: `postgres`, pass: `postgres`, db: `orders_db`)docker compose build --no-cache + + + +---# Check disk space -# Check disk space docker system df -``` -### Issue: "pnpm: not found" or package installation fails -**Solution**: Rebuild images from scratch -```powershell -docker compose down +## 🎯 Development Workflow``` + + + +```powershell### Issue: "pnpm: not found" or package installation fails + +# Day 1: Initial setup**Solution**: Rebuild images from scratch + +docker compose up --build```powershell + +# βœ… Database auto-migrated and seededdocker compose down + docker compose build --no-cache -docker compose up -``` + +# Day 2+: Continue developmentdocker compose up + +docker compose up``` + +# βœ… Data persists, no re-seeding ### Issue: Database connection errors -**Check PostgreSQL health**: -```powershell -# View PostgreSQL logs + +# After code changes**Check PostgreSQL health**: + +docker compose restart backend # If backend changed```powershell + +docker compose restart frontend # If frontend changed# View PostgreSQL logs + docker compose logs postgres -# Test connection +# After dependency changes + +docker compose up --build # Rebuild images# Test connection + docker compose exec postgres pg_isready -U postgres -# Restart database -docker compose restart postgres +# End of day + +docker compose down # Stop, keep data# Restart database + +# ORdocker compose restart postgres + +docker compose down -v # Stop, delete data (fresh start next time)``` + ``` ### Issue: Hot reload not working diff --git a/README.md b/README.md index 4edc683..642b514 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,11 @@ # πŸš€ Full-Stack Order Management System -[![TypeScript](https://img.shields.io/badge/TypeScript-5.6-blue?logo=typescript)](https://www.typescriptlang.org/) -[![React](https://img.shields.io/badge/React-19-61dafb?logo=react)](https://react.dev/) -[![Node.js](https://img.shields.io/badge/Node.js-18+-green?logo=node.js)](https://nodejs.org/) -[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-14+-blue?logo=postgresql)](https://www.postgresql.org/) +[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?logo=typescript)](https://www.typescriptlang.org/) +[![React](https://img.shields.io/badge/React-19.1-61dafb?logo=react)](https://react.dev/) +[![Node.js](https://img.shields.io/badge/Node.js-22-green?logo=node.js)](https://nodejs.org/) +[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-14-blue?logo=postgresql)](https://www.postgresql.org/) [![Prisma](https://img.shields.io/badge/Prisma-6.3-2D3748?logo=prisma)](https://www.prisma.io/) +[![Vite](https://img.shields.io/badge/Vite-6.0-646CFF?logo=vite)](https://vitejs.dev/) A modern, production-ready order management application built with **TypeScript**, **React 19**, **Express**, **Prisma**, and **PostgreSQL**. Features complete CRUD operations, pagination, filtering, end-to-end type safety, and professional UX patterns. @@ -52,33 +53,31 @@ docker-compose up --build The database will be **automatically migrated and seeded** on first run with 10 sample orders. -### Docker Commands +### Essential Commands ```bash -# Start services in background -docker-compose up -d - -# View logs (all services) -docker-compose logs -f - -# View logs (specific service) -docker-compose logs -f backend -docker-compose logs -f frontend +# Start (first time or after changes) +docker-compose up --build -# Stop services +# Stop (keeps data) docker-compose down -# Stop and remove volumes (cleans database) -docker-compose down -v - -# Restart a specific service -docker-compose restart backend +# View logs +docker-compose logs -f backend -# Execute command in container +# Run tests docker-compose exec backend pnpm --filter backend test -docker-compose exec backend pnpm --filter backend prisma:studio + +# Reset database (⚠️ deletes all data) +docker-compose down -v && docker-compose up -d ``` +### πŸ’Ύ Data Persistence +- βœ… `docker-compose down` β†’ **Keeps** database data +- ❌ `docker-compose down -v` β†’ **Deletes** database data +- First startup auto-seeds 10 sample orders +- Data persists between restarts + ### Hot Reload in Docker All source code directories are mounted as volumes, so changes to your code will trigger automatic reloads: From 778a780977981c1b1bfb1b1f66637e2cc8ee2d48 Mon Sep 17 00:00:00 2001 From: lesoviet Date: Sun, 19 Oct 2025 21:57:58 -0300 Subject: [PATCH 6/7] docs: Complete README rewrite with correct versions, Docker badge, and improved structure --- DOCKER_REFERENCE.md | 602 ----------------- README.md | 1527 ++++++++++++++++++++++++++++++------------- 2 files changed, 1075 insertions(+), 1054 deletions(-) delete mode 100644 DOCKER_REFERENCE.md diff --git a/DOCKER_REFERENCE.md b/DOCKER_REFERENCE.md deleted file mode 100644 index 3e02834..0000000 --- a/DOCKER_REFERENCE.md +++ /dev/null @@ -1,602 +0,0 @@ -# 🐳 Docker Setup - Quick Reference# 🐳 Docker Setup - Quick Reference - - - -## ⏱️ Build Times## ⏱️ Build Times - -- **First build**: ~5-8 minutes (Node 22 Alpine + PostgreSQL 14 + dependencies)- **First build**: ~5-8 minutes (downloads Node 22 Alpine, PostgreSQL 14, installs dependencies) - -- **Subsequent starts**: ~30 seconds (cached images)- **Subsequent starts**: ~30 seconds (uses cached images) - - - ------- - - - -## πŸš€ Essential Commands## πŸš€ Essential Commands - - - -```powershell```powershell - -# Start/Stop# Start/Stop - -docker compose up --build # Build and start (first time or after code changes)docker compose up --build # First time or after changes - -docker compose up -d # Start in backgrounddocker compose up -d # Background mode - -docker compose down # Stop (⚠️ KEEPS database data)docker compose down # Stop (keeps data) - -docker compose down -v # Stop + DELETE database datadocker compose down -v # Stop + delete data - -docker compose restart backend # Restart specific servicedocker compose restart backend # Restart single service - - - -# Logs# Logs - -docker compose logs -f # All servicesdocker compose logs -f backend # Follow backend logs - -docker compose logs -f backend # Specific servicedocker compose logs --tail=50 backend - -docker compose logs --tail=50 backend # Last 50 lines - -# Testing - -# Testingdocker compose exec backend pnpm --filter backend test - -docker compose exec backend pnpm --filter backend testdocker compose exec frontend pnpm --filter frontend test --run - -docker compose exec frontend pnpm --filter frontend test --run - -# Database - -# Database Managementdocker compose exec backend pnpm --filter backend prisma:studio # GUI at :5555 - -docker compose exec backend pnpm --filter backend prisma:studio # GUI at :5555docker compose exec backend pnpm --filter backend prisma:seed # Manual seed - -docker compose exec backend pnpm --filter backend prisma:seed # Manual seeddocker compose exec postgres psql -U postgres -d orders_db # SQL shell - -docker compose exec postgres psql -U postgres -d orders_db # Direct SQL access``` - - - -# Shell Access--- - -docker compose exec backend sh # Backend container shell - -docker compose exec frontend sh # Frontend container shell## οΏ½ Data Persistence Explained - -``` - -### How Docker Volumes Work - ---- - -**Volume Definition** (docker-compose.yml): - -## πŸ’Ύ Data Persistence```yaml - -volumes: - -### How It Works postgres_data: # Named volume - -PostgreSQL data stored in **named volume**: `reddittest_postgres_data` driver: local - - - -| Command | Database Data |services: - -|---------|---------------| postgres: - -| `docker compose down` | βœ… **Kept** | volumes: - -| `docker compose restart` | βœ… **Kept** | - postgres_data:/var/lib/postgresql/data # Mount point - -| `docker compose up --build` | βœ… **Kept** |``` - -| `docker compose down -v` | ❌ **Deleted** | - -| System reboot | βœ… **Kept** |**What Happens**: - -1. Docker creates a named volume `reddittest_postgres_data` - -### Auto-Seed Behavior2. PostgreSQL writes database files to `/var/lib/postgresql/data` inside container - -3. That directory is **mapped** to the Docker volume on your host machine - -**First Startup** (empty database):4. Data survives container restarts, rebuilds, and `docker compose down` - -``` - -1. Runs migrations (creates tables)### Data Lifecycle - -2. Generates Prisma Client - -3. Checks: await prisma.order.count() === 0?| Action | Data Preserved? | Why? | - -4. βœ… YES β†’ Seeds 10 sample orders|--------|-----------------|------| - -5. Starts server| `docker compose down` | βœ… YES | Only stops containers, volumes remain | - -```| `docker compose restart` | βœ… YES | Containers restart, volumes untouched | - -| `docker compose up --build` | βœ… YES | Rebuilds images, but volumes persist | - -**Subsequent Startups** (data exists):| `docker compose down -v` | ❌ NO | **Explicitly removes volumes** | - -```| System reboot | βœ… YES | Volumes stored on disk | - -1. Runs migrations (no-op if up-to-date)| Delete containers | βœ… YES | Volumes independent of containers | - -2. Generates Prisma Client (cached) - -3. Checks: await prisma.order.count() > 0?### When Data Gets Lost - -4. ❌ NO β†’ Skips seeding: "πŸ“¦ Database already has orders" - -5. Starts server with existing data**Common Mistakes**: - -``````powershell - -# ❌ BAD: Removes volumes (loses all data) - -### Reset Databasedocker compose down -v - - - -```powershell# ❌ BAD: Removes all volumes including named ones - -# Option 1: Remove volume (cleanest)docker volume prune -a - -docker compose down -v - -docker compose up -d # Auto-seeds again# βœ… GOOD: Stops containers, keeps data - -docker compose down - -# Option 2: Prisma reset (from container) - -docker compose exec backend pnpm --filter backend prisma:migrate reset# βœ… GOOD: Restart safely - -```docker compose restart - -``` - ---- - -### Auto-Seed Behavior - -## πŸ” Monitoring & Debugging - -**First Startup** (empty database): - -```powershell``` - -# Container status1. docker compose up - -docker compose ps # Running services2. Backend runs: prisma:migrate deploy (creates tables) - -docker ps -a # All containers3. Backend runs: prisma:generate (generates Prisma Client) - -docker stats # Resource usage4. Backend runs: dev:seed - -5. Seed script checks: prisma.order.count() === 0? - -# Build diagnostics6. βœ… YES β†’ Creates 10 sample orders - -docker compose build --progress=plain backend7. Server starts - -docker compose build --no-cache # Force rebuild``` - - - -# Inspect services**Subsequent Startups** (data exists): - -docker compose config # View resolved config``` - -docker inspect orders_backend # Container details1. docker compose up - -docker volume inspect reddittest_postgres_data # Volume info2. Backend runs: prisma:migrate deploy (no changes) - -```3. Backend runs: prisma:generate (already generated) - -4. Backend runs: dev:seed - ----5. Seed script checks: prisma.order.count() === 10? - -6. ❌ NO β†’ Skips seeding, shows message: - -## πŸ› Common Issues "πŸ“¦ Database already has 10 orders. Skipping seed." - -7. Server starts with existing data - -### Port Already in Use (3000, 5173, 5432)``` - -```powershell - -# Find process using port**Why This Design**: - -netstat -ano | findstr :3000- βœ… Prevents duplicate data on every restart - -- βœ… Development-friendly: Data persists between sessions - -# Kill process (replace )- βœ… Production-safe: Won't accidentally overwrite real data - -taskkill /PID /F- βœ… Can manually seed anytime: `docker compose exec backend pnpm --filter backend prisma:seed` - -``` - -### Volume Location on Host - -### Build Hanging or Slow - -```powershell```powershell - -# Clear Docker cache# Find volume location - -docker system prune -adocker volume inspect reddittest_postgres_data - - - -# Check disk space# Typical output: - -docker system df"Mountpoint": "/var/lib/docker/volumes/reddittest_postgres_data/_data" - -# (On Windows: \\wsl$\docker-desktop-data\data\docker\volumes\...) - -# Increase Docker resources: Docker Desktop β†’ Settings β†’ Resources β†’ Memory: 4GB+, CPUs: 2+``` - -``` - ---- - -### Database Connection Errors - -```powershell## οΏ½πŸ” Monitoring & Debugging - -# Check PostgreSQL health - -docker compose exec postgres pg_isready -U postgres### Check Container Status - -```powershell - -# View logs# List running containers - -docker compose logs postgresdocker compose ps - - - -# Restart database# List all containers (including stopped) - -docker compose restart postgresdocker ps -a - -``` - -# View container resource usage - -### Hot Reload Not Workingdocker stats - -```powershell``` - -# Verify volume mounts - -docker compose config | Select-String -Pattern "volumes"### View Build Progress - -```powershell - -# Restart services# Build with progress output - -docker compose restart backend frontenddocker compose build --progress=plain - -``` - -# Build specific service - ----docker compose build backend - -docker compose build frontend - -## πŸ“Š Resource Usage (Development)``` - - - -| Service | CPU | Memory | Disk |### Inspect Services - -|---------|-----|--------|------|```powershell - -| PostgreSQL | 2-5% | 50-100MB | ~100MB |# View service configuration - -| Backend | 5-10% | 150-300MB | - |docker compose config - -| Frontend | 5-10% | 200-400MB | - | - -| **Total** | ~15% | ~600MB | ~1.5GB |# Inspect specific service - -docker inspect orders_backend - ----docker inspect orders_frontend - -docker inspect orders_postgres - -## 🧹 Cleanup``` - - - -```powershell--- - -# Remove stopped containers - -docker compose down## πŸ› Troubleshooting - - - -# Remove volumes (⚠️ deletes database)### Issue: "Cannot connect to Docker daemon" - -docker compose down -v**Solution**: Ensure Docker Desktop is running - -- Check system tray for Docker icon - -# Remove all unused Docker resources- Open Docker Desktop application - -docker system prune -a --volumes- Wait for "Docker Desktop is running" message - - - -# Free up space### Issue: "Port is already allocated" (3000, 5173, or 5432) - -docker system prune -a # Remove unused images/containers**Solution**: Stop the conflicting service - -docker volume prune # Remove unused volumes```powershell - -docker builder prune # Remove build cache# Find process using port 3000 - -```netstat -ano | findstr :3000 - -# Kill the process (replace PID with actual number) - ----taskkill /PID /F - - - -## πŸ“¦ Tech Stack Versions# Or change ports in docker-compose.yml - -ports: - -- **Node.js**: 22-alpine - "3001:3000" # Maps host 3001 to container 3000 - -- **PostgreSQL**: 14-alpine``` - -- **pnpm**: latest (via corepack) - -- **React**: 19.1.1### Issue: Build is slow or hanging - -- **Vite**: 6.0.10**Possible causes**: - -- **TypeScript**: 5.9.31. **Slow internet** - Downloading packages from npm - -- **Prisma**: 6.3.02. **Low disk space** - Need ~5GB free - -- **Express**: 4.21.23. **Resource limits** - Increase Docker Desktop memory/CPU - - - Open Docker Desktop β†’ Settings β†’ Resources - ---- - Increase Memory to 4GB+ and CPUs to 2+ - - - -## πŸ”— Quick Links**Solutions**: - -```powershell - -- **Frontend**: http://localhost:5173# Clear Docker cache - -- **Backend API**: http://localhost:3000docker system prune -a - -- **Health Check**: http://localhost:3000/health - -- **Prisma Studio**: http://localhost:5555 (run `docker compose exec backend pnpm --filter backend prisma:studio`)# Rebuild without cache - -- **PostgreSQL**: localhost:5432 (user: `postgres`, pass: `postgres`, db: `orders_db`)docker compose build --no-cache - - - ----# Check disk space - -docker system df - -## 🎯 Development Workflow``` - - - -```powershell### Issue: "pnpm: not found" or package installation fails - -# Day 1: Initial setup**Solution**: Rebuild images from scratch - -docker compose up --build```powershell - -# βœ… Database auto-migrated and seededdocker compose down - -docker compose build --no-cache - -# Day 2+: Continue developmentdocker compose up - -docker compose up``` - -# βœ… Data persists, no re-seeding - -### Issue: Database connection errors - -# After code changes**Check PostgreSQL health**: - -docker compose restart backend # If backend changed```powershell - -docker compose restart frontend # If frontend changed# View PostgreSQL logs - -docker compose logs postgres - -# After dependency changes - -docker compose up --build # Rebuild images# Test connection - -docker compose exec postgres pg_isready -U postgres - -# End of day - -docker compose down # Stop, keep data# Restart database - -# ORdocker compose restart postgres - -docker compose down -v # Stop, delete data (fresh start next time)``` - -``` - -### Issue: Hot reload not working -**Solution**: Ensure volumes are mounted correctly -```powershell -# Check volume mounts -docker compose config | Select-String -Pattern "volumes" - -# Restart services -docker compose restart backend frontend -``` - -### Issue: Frontend shows "Network Error" or can't connect to backend -**Check**: -1. Backend is running: `docker compose logs backend` -2. Backend is on correct port: http://localhost:3000/health -3. CORS is configured: Check `apps/backend/src/index.ts` -4. Environment variables: `VITE_API_URL=http://localhost:3000/api` - ---- - -## πŸ“Š Resource Usage - -### Expected Usage (Development) -| Component | CPU | Memory | Disk | -|-----------|-----|--------|------| -| PostgreSQL | 2-5% | 50-100MB | ~100MB | -| Backend | 5-10% | 150-300MB | - | -| Frontend | 5-10% | 200-400MB | - | -| **Total** | 10-25% | 400-800MB | ~1.5GB | - -### Optimize Resource Usage -```powershell -# Limit container resources (add to docker-compose.yml) -services: - backend: - deploy: - resources: - limits: - cpus: '0.5' - memory: 512M -``` - ---- - -## 🧹 Cleanup Commands - -### Remove Specific Containers/Images -```powershell -# Stop and remove containers -docker compose down - -# Remove backend/frontend images (forces rebuild) -docker rmi redditest-backend -docker rmi redditest-frontend - -# Remove PostgreSQL volume (deletes data!) -docker volume rm redditest_postgres_data -``` - -### Full Cleanup (⚠️ Removes everything) -```powershell -# Remove all containers, images, volumes, networks -docker system prune -a --volumes - -# Reclaim disk space -docker system prune -a -``` - ---- - -## βœ… Health Checks - -### Verify Everything is Running -```powershell -# All services should show "Up" -docker compose ps - -# Check endpoints -Invoke-WebRequest http://localhost:3000/health # Backend health -Invoke-WebRequest http://localhost:3000/api/orders # API -Invoke-WebRequest http://localhost:5173 # Frontend - -# Check logs for errors -docker compose logs | Select-String -Pattern "error" -CaseSensitive -``` - ---- - -## 🎯 Pro Tips - -### 1. Use Docker Desktop Dashboard -- Visual interface for managing containers -- View logs, stats, and exec into containers -- Easier than command line for beginners - -### 2. Keep Docker Desktop Updated -```powershell -# Check version -docker --version -docker compose version - -# Update via Docker Desktop β†’ Check for updates -``` - -### 3. Use Docker Extensions -- Install useful extensions from Docker Desktop -- Examples: Disk usage, Resource monitor, Database viewer - -### 4. Set Up Auto-Start (Optional) -- Docker Desktop β†’ Settings β†’ General -- β˜‘ Start Docker Desktop when you log in - -### 5. Enable BuildKit -```powershell -# Add to environment or .env -$env:DOCKER_BUILDKIT=1 -$env:COMPOSE_DOCKER_CLI_BUILD=1 -``` - ---- - -## πŸ“š Additional Resources - -- **Official Docker Docs**: https://docs.docker.com/ -- **Docker Compose Docs**: https://docs.docker.com/compose/ -- **Prisma + Docker**: https://www.prisma.io/docs/guides/deployment/deployment-guides/deploying-to-docker -- **Node.js Best Practices**: https://github.com/goldbergyoni/nodebestpractices - ---- - -## πŸ†˜ Still Having Issues? - -1. **Check Docker Desktop logs**: - - Open Docker Desktop - - Click Troubleshoot icon (bug icon) - - View logs - -2. **Restart Docker Desktop**: - - Right-click Docker icon in system tray - - Quit Docker Desktop - - Start Docker Desktop again - -3. **Reset Docker Desktop** (last resort): - - Docker Desktop β†’ Troubleshoot β†’ Reset to factory defaults - - ⚠️ This deletes all containers, images, and volumes - ---- - -**Last updated**: October 19, 2025 diff --git a/README.md b/README.md index 642b514..61491c6 100644 --- a/README.md +++ b/README.md @@ -1,630 +1,1257 @@ -# πŸš€ Full-Stack Order Management System +# πŸš€ Full-Stack Order Management System# πŸš€ Full-Stack Order Management System -[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?logo=typescript)](https://www.typescriptlang.org/) -[![React](https://img.shields.io/badge/React-19.1-61dafb?logo=react)](https://react.dev/) -[![Node.js](https://img.shields.io/badge/Node.js-22-green?logo=node.js)](https://nodejs.org/) -[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-14-blue?logo=postgresql)](https://www.postgresql.org/) -[![Prisma](https://img.shields.io/badge/Prisma-6.3-2D3748?logo=prisma)](https://www.prisma.io/) -[![Vite](https://img.shields.io/badge/Vite-6.0-646CFF?logo=vite)](https://vitejs.dev/) + + +[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?logo=typescript)](https://www.typescriptlang.org/)[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?logo=typescript)](https://www.typescriptlang.org/) + +[![React](https://img.shields.io/badge/React-19.1-61dafb?logo=react)](https://react.dev/)[![React](https://img.shields.io/badge/React-19.1-61dafb?logo=react)](https://react.dev/) + +[![Node.js](https://img.shields.io/badge/Node.js-22-green?logo=node.js)](https://nodejs.org/)[![Node.js](https://img.shields.io/badge/Node.js-22-green?logo=node.js)](https://nodejs.org/) + +[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-14-blue?logo=postgresql)](https://www.postgresql.org/)[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-14-blue?logo=postgresql)](https://www.postgresql.org/) + +[![Prisma](https://img.shields.io/badge/Prisma-6.3-2D3748?logo=prisma)](https://www.prisma.io/)[![Prisma](https://img.shields.io/badge/Prisma-6.3-2D3748?logo=prisma)](https://www.prisma.io/) + +[![Vite](https://img.shields.io/badge/Vite-6.0-646CFF?logo=vite)](https://vitejs.dev/)[![Vite](https://img.shields.io/badge/Vite-6.0-646CFF?logo=vite)](https://vitejs.dev/) + +[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED?logo=docker)](https://www.docker.com/) A modern, production-ready order management application built with **TypeScript**, **React 19**, **Express**, **Prisma**, and **PostgreSQL**. Features complete CRUD operations, pagination, filtering, end-to-end type safety, and professional UX patterns. ---- +A modern, production-ready order management application built with **TypeScript**, **React 19**, **Express**, **Prisma**, and **PostgreSQL**. Features complete CRUD operations, pagination, filtering, end-to-end type safety, Docker support, and professional UX patterns. + +--- + +--- + +## πŸ“‹ Table of Contents + +## πŸ“‹ Table of Contents + +- [Quick Start with Docker](#-quick-start-with-docker-recommended) + +- [Quick Start with Docker](#-quick-start-with-docker-recommended)- [Quick Start (Manual Setup)](#-quick-start-manual-setup) + +- [Manual Setup](#-manual-setup-without-docker)- [Features](#-features) + +- [Features](#-features)- [Tech Stack](#-tech-stack) + +- [Tech Stack](#-tech-stack)- [Development](#-development) + +- [Development](#-development)- [Testing](#-testing) + +- [Testing](#-testing)- [API Documentation](#-api-documentation) + +- [API Documentation](#-api-documentation)- [Architecture](#-architecture) + +- [Project Structure](#-project-structure)- [Project Structure](#-project-structure) + + + +------ + + + +## 🐳 Quick Start with Docker (Recommended)## 🐳 Quick Start with Docker (Recommended) + + + +The easiest way to run this project is using Docker Compose. **No need to install PostgreSQL, Node.js, or pnpm manually!**The easiest way to run this project is using Docker Compose. **No need to install PostgreSQL, Node.js, or pnpm manually!** + + + +### Prerequisites### Prerequisites + + + +- [Docker Desktop](https://www.docker.com/products/docker-desktop/) installed and running- **Docker Desktop** installed and running + +- ~3GB free disk space- **~3GB free disk space** for images and volumes + + + +### Start the Application### Start the Application + + + +```bash```bash + +# Clone the repository# Clone the repository + +git clone https://github.com/LeSoviet/RedditTest.gitgit clone + +cd RedditTestcd RedditTest + + + +# Start all services (PostgreSQL + Backend + Frontend)# Start all services (PostgreSQL + Backend + Frontend) + +docker compose up --builddocker-compose up --build + +`````` + + + +**That's it!** πŸŽ‰ The application will be available at:**That's it!** πŸŽ‰ The application will be available at: + + + +- 🎨 **Frontend**: http://localhost:5173- 🎨 **Frontend**: http://localhost:5173 + +- πŸš€ **Backend API**: http://localhost:3000- πŸš€ **Backend API**: http://localhost:3000 + +- πŸ“š **API Health**: http://localhost:3000/health- πŸ—„οΈ **PostgreSQL**: localhost:5432 (managed by Docker) + + + +The database will be **automatically migrated and seeded** with 10 sample orders on first run.The database will be **automatically migrated and seeded** on first run with 10 sample orders. + + + +### Essential Docker Commands### Essential Commands + + + +```bash```bash + +# Start (first time or after code changes)# Start (first time or after changes) + +docker compose up --builddocker-compose up --build + + + +# Start in background# Stop (keeps data) + +docker compose up -ddocker-compose down + + + +# Stop (keeps database data)# View logs + +docker compose downdocker-compose logs -f backend + + + +# View backend logs (see database queries)# Run tests + +docker compose logs -f backenddocker-compose exec backend pnpm --filter backend test + + + +# Run tests# Reset database (⚠️ deletes all data) + +docker compose exec backend pnpm --filter backend testdocker-compose down -v && docker-compose up -d + +``` + +# Open Prisma Studio (database GUI) + +docker compose exec backend pnpm --filter backend prisma:studio### πŸ’Ύ Data Persistence + +# Opens at http://localhost:5555- βœ… `docker-compose down` β†’ **Keeps** database data + +- ❌ `docker-compose down -v` β†’ **Deletes** database data + +# Reset database (⚠️ deletes all data)- First startup auto-seeds 10 sample orders + +docker compose down -v && docker compose up -d- Data persists between restarts + +``` + +### Hot Reload in Docker + +### πŸ’Ύ Data Persistence + +All source code directories are mounted as volumes, so changes to your code will trigger automatic reloads: + +- βœ… `docker compose down` β†’ **Keeps** database data + +- ❌ `docker compose down -v` β†’ **Deletes** database data- βœ… Backend: `tsx` watch mode automatically restarts on file changes + +- First startup: Auto-migrates schema and seeds 10 orders- βœ… Frontend: Vite HMR (Hot Module Replacement) updates instantly + +- Subsequent startups: Keeps existing data (no re-seeding)- βœ… Shared Types: Changes reflect immediately in both apps + + + +### πŸ”„ Hot Reload--- + + + +All source code is mounted as volumes. Changes trigger automatic reloads:## πŸ’» Quick Start (Manual Setup) + + + +- **Backend**: `tsx` watch mode (auto-restart on save)If you prefer to run without Docker, follow these steps: + +- **Frontend**: Vite HMR (instant updates) + +- **Shared Types**: Changes reflect immediately in both apps## ✨ Features + + + +---### Core Functionality + +- βœ… **Full CRUD Operations** - Create, Read, Update, Delete orders + +## πŸ’» Manual Setup (Without Docker)- βœ… **Server-side Pagination** - Efficient data loading with configurable page size + +- βœ… **Status Filtering** - Filter orders by PENDING, COMPLETED, or CANCELLED status + +### Prerequisites- βœ… **Real-time Validation** - Zod schemas validate data on both client and server + +- βœ… **End-to-end Type Safety** - Shared types between frontend and backend + +- **Node.js** >= 22.0.0 ([download](https://nodejs.org/)) + +- **pnpm** >= 8.0.0 (`npm install -g pnpm`)### User Experience + +- **PostgreSQL** >= 14 ([download](https://www.postgresql.org/download/))- βœ… **Toast Notifications** - Professional feedback for all actions + +- βœ… **Status Badges** - Color-coded badges (🟑 Pending, 🟒 Completed, πŸ”΄ Cancelled) + +### 1. Clone & Install- βœ… **Delete Confirmation** - Modal dialog prevents accidental deletions + +- βœ… **Loading States** - Clear feedback during async operations + +```bash- βœ… **Error Handling** - User-friendly error messages + +git clone https://github.com/LeSoviet/RedditTest.git- βœ… **Responsive Design** - Mobile-friendly UI with TailwindCSS + +cd RedditTest + +pnpm install### Technical Excellence + +```- βœ… **Monorepo Architecture** - pnpm workspaces with shared types + +- βœ… **React Query** - Automatic caching, optimistic updates, cache invalidation + +### 2. Setup Environment Variables- βœ… **Type-First Development** - Zod schemas generate TypeScript types + +- βœ… **Testing** - 15 tests total (10 backend + 5 frontend) + +**Backend** (`apps/backend/.env`):- βœ… **Code Quality** - ESLint, Prettier, and strict TypeScript + + + +```env--- + +DATABASE_URL="postgresql://postgres:postgres@localhost:5432/orders_db?schema=public" + +PORT=3000## πŸ› οΈ Tech Stack + +NODE_ENV=development + +```### Backend + +- **Runtime**: Node.js 18+ with TypeScript + +**Frontend** (`apps/frontend/.env`):- **Framework**: Express.js + +- **Database**: PostgreSQL 14+ with Prisma ORM + +```env- **Validation**: Zod (runtime validation + types) + +VITE_API_URL=http://localhost:3000/api- **Testing**: Jest + Supertest (10 tests) + +``` + +### Frontend + +### 3. Setup Database- **Framework**: React 19 with TypeScript + +- **Build Tool**: Vite + +```bash- **Styling**: TailwindCSS + +# Generate Prisma Client- **State Management**: React Query (server state) + +pnpm --filter backend prisma:generate- **Forms**: React Hook Form + Zod resolver + +- **Notifications**: React Hot Toast + +# Run migrations (creates tables)- **Testing**: Vitest + React Testing Library (5 tests) + +pnpm --filter backend prisma:migrate dev + +### Shared + +# Seed database with sample data- **Monorepo**: pnpm workspaces + +pnpm --filter backend prisma:seed- **Types**: Shared Zod schemas in `@shared/types` + +```- **Code Quality**: ESLint + Prettier + + + +### 4. Start Development Servers--- + + + +```bash## οΏ½ Quick Start (Manual Setup) + +# Terminal 1: Backend (http://localhost:3000) + +pnpm dev:backend### Prerequisites + +- **Node.js** >= 18.0.0 + +# Terminal 2: Frontend (http://localhost:5173)- **pnpm** >= 8.0.0 + +pnpm dev:frontend- **PostgreSQL** >= 14 (running locally) + +``` + +### 1. Clone & Install + +--- + +```bash + +## ✨ Featuresgit clone + +cd RedditTest + +### Core Functionalitypnpm install + +- βœ… **Full CRUD Operations** - Create, Read, Update, Delete orders``` + +- βœ… **Server-side Pagination** - Efficient loading with configurable page size (default: 10, max: 100) + +- βœ… **Status Filtering** - Filter by PENDING, COMPLETED, or CANCELLED### 2. Setup Environment Variables + +- βœ… **Real-time Validation** - Zod schemas validate on client and server + +- βœ… **End-to-end Type Safety** - Shared types between frontend/backend**Backend** (`apps/backend/.env`): + + + +### User Experience```bash + +- βœ… **Toast Notifications** - Professional feedback for all actions# Copy example file + +- βœ… **Status Badges** - Color-coded (🟑 Pending, 🟒 Completed, πŸ”΄ Cancelled)cp apps/backend/.env.example apps/backend/.env + +- βœ… **Delete Confirmation** - Modal prevents accidental deletions``` + +- βœ… **Loading States** - Clear feedback during async operations + +- βœ… **Error Handling** - User-friendly error messagesEdit with your PostgreSQL credentials: + +- βœ… **Responsive Design** - Mobile-friendly with TailwindCSS + +```env + +### Developer ExperienceDATABASE_URL="postgresql://postgres:postgres@localhost:5432/orders_db?schema=public" + +- βœ… **Docker Support** - One command to start everythingPORT=3000 + +- βœ… **Monorepo Architecture** - pnpm workspaces with shared typesNODE_ENV=development + +- βœ… **React Query** - Automatic caching, optimistic updates, invalidation``` + +- βœ… **Type-First Development** - Zod schemas generate TypeScript types + +- βœ… **Comprehensive Testing** - 15 tests (10 backend + 5 frontend)**Frontend** (`apps/frontend/.env`): + +- βœ… **Hot Reload** - Instant feedback in dev mode + +- βœ… **Prisma Studio** - Visual database editor```bash + +# Copy example file + +---cp apps/frontend/.env.example apps/frontend/.env + +``` + +## πŸ› οΈ Tech Stack + +Default values should work: + +### Backend + +| Technology | Version | Purpose |```env + +|------------|---------|---------|VITE_API_URL=http://localhost:3000/api + +| **Node.js** | 22 (Alpine in Docker) | Runtime |``` + +| **TypeScript** | 5.9.3 | Type safety | + +| **Express** | 4.21.2 | Web framework |### 3. Setup Database + +| **PostgreSQL** | 14 (Alpine in Docker) | Database | + +| **Prisma** | 6.3.0 | ORM + migrations |```bash + +| **Zod** | 3.24.1 | Runtime validation |# Generate Prisma client + +| **Jest** | 29.7.0 | Testing (10 tests) |pnpm --filter backend prisma:generate + + + +### Frontend# Run migrations (creates tables) + +| Technology | Version | Purpose |pnpm --filter backend prisma:migrate dev + +|------------|---------|---------| + +| **React** | 19.1.1 | UI framework |# (Optional) Seed database + +| **TypeScript** | 5.9.3 | Type safety |pnpm --filter backend prisma:seed + +| **Vite** | 6.0.10 | Build tool + dev server |``` + +| **TailwindCSS** | 3.4.17 | Styling | + +| **React Query** | 5.63.1 | Server state management |### 4. Start Development Servers + +| **React Hook Form** | 7.54.2 | Form handling | + +| **React Hot Toast** | 2.6.0 | Notifications |**Terminal 1 - Backend:** + +| **Vitest** | 3.2.4 | Testing (5 tests) | + +```bash + +### Sharedpnpm dev:backend + +- **Monorepo**: pnpm workspaces``` + +- **Types**: Shared Zod schemas in `@shared/types` + +- **Validation**: Single source of truth for all data structuresπŸš€ Backend: http://localhost:3000 + + + +---**Terminal 2 - Frontend:** + + + +## πŸ”¨ Development```bash + +pnpm dev:frontend + +### Project Structure``` + + + +```🎨 Frontend: http://localhost:5173 + +RedditTest/ + +β”œβ”€β”€ apps/> **Note:** The backend automatically seeds the database with 10 sample orders on first run if the database is empty. + +β”‚ β”œβ”€β”€ backend/ # Express API + +β”‚ β”‚ β”œβ”€β”€ prisma/ # Schema, migrations, seed--- + +β”‚ β”‚ └── src/ + +β”‚ β”‚ β”œβ”€β”€ controllers/ # Request handlers## πŸ’» Development + +β”‚ β”‚ β”œβ”€β”€ middleware/ # Error handling, validation + +β”‚ β”‚ └── routes/ # API endpoints> **πŸ’‘ Tip:** If using Docker, replace `pnpm` commands with `docker-compose exec ` (e.g., `docker-compose exec backend pnpm --filter backend test`) + +β”‚ └── frontend/ # React SPA + +β”‚ └── src/### Quick Command Reference + +β”‚ β”œβ”€β”€ components/ # Reusable UI components + +β”‚ β”œβ”€β”€ hooks/ # React Query hooks```bash + +β”‚ β”œβ”€β”€ pages/ # Route pages# Development (Manual) + +β”‚ └── services/ # API clientpnpm dev:backend # Start backend (auto-seeds if empty) + +β”œβ”€β”€ packages/pnpm dev:frontend # Start frontend + +β”‚ └── shared-types/ # Zod schemas + TypeScript types + +└── docker-compose.yml # Docker orchestration# Development (Docker) + +```docker-compose up # Start all services + +docker-compose up -d # Start in background + +### Available Scriptsdocker-compose logs -f backend # View backend logs + + + +```bash# Testing (Manual) + +# Developmentpnpm --filter backend test # Run backend tests (10 tests) + +pnpm dev:backend # Start backend (http://localhost:3000)pnpm --filter frontend test --run # Run frontend tests (5 tests) + +pnpm dev:frontend # Start frontend (http://localhost:5173) + +# Testing (Docker) + +# Buildingdocker-compose exec backend pnpm --filter backend test + +pnpm build:backend # Compile TypeScript β†’ dist/docker-compose exec frontend pnpm --filter frontend test --run + +pnpm build:frontend # Build for production β†’ dist/ + +# Database (Manual) + +# Testingpnpm --filter backend prisma:studio # Open database GUI (port 5555) + +pnpm test:backend # Run Jest tests (10 tests)pnpm --filter backend prisma:generate # Regenerate Prisma client + +pnpm test:frontend # Run Vitest tests (5 tests)pnpm --filter backend prisma:migrate dev # Create new migration + +pnpm test # Run all testspnpm --filter backend prisma:seed # Manual seed + +pnpm --filter backend prisma:migrate reset # ⚠️ Reset database (deletes all data) + +# Database + +pnpm --filter backend prisma:generate # Regenerate Prisma Client# Database (Docker) + +pnpm --filter backend prisma:migrate # Create migrationdocker-compose exec backend pnpm --filter backend prisma:studio + +pnpm --filter backend prisma:seed # Seed databasedocker-compose exec backend pnpm --filter backend prisma:generate + +pnpm --filter backend prisma:studio # Open GUI (localhost:5555) + +# Build + +# Dockerpnpm --filter backend build # Build backend + +docker compose up --build # Start all servicespnpm --filter frontend build # Build frontend + +docker compose logs -f backend # View backend logs``` + +docker compose exec backend sh # Access backend shell + +```### Database Management + + + +### Environment Variables**Prisma Studio** - Visual database editor: + + + +#### Backend (`apps/backend/.env`)```bash + +```envpnpm --filter backend prisma:studio + +DATABASE_URL="postgresql://user:password@localhost:5432/orders_db?schema=public"``` + +PORT=3000 + +NODE_ENV=developmentOpens at http://localhost:5555 + +``` + +**Seeding Behavior:** + +#### Frontend (`apps/frontend/.env`)- Seed script checks if data exists before inserting + +```env- Only seeds if database is empty + +VITE_API_URL=http://localhost:3000/api- To reseed: `pnpm --filter backend prisma:migrate reset` + +``` + +--- + +--- + +## πŸ§ͺ Testing + +## πŸ§ͺ Testing + +### Run Tests + +### Run All Tests + +```bash + +```bash# Backend tests (Jest + Supertest) + +# Localpnpm --filter backend test + +pnpm test + +# Frontend tests (Vitest + React Testing Library) + +# Dockerpnpm --filter frontend test --run + +docker compose exec backend pnpm --filter backend test + +docker compose exec frontend pnpm --filter frontend test --run# All tests + +```pnpm --filter backend test && pnpm --filter frontend test --run + +``` + +### Test Coverage + +### Test Coverage + +**Backend (10 tests)** - Integration tests with real database: + +- βœ… Pagination with correct metadata**Backend (10 tests):** + +- βœ… Create order with valid/invalid data- βœ… Pagination with metadata + +- βœ… Get order by ID (success + 404)- βœ… Order creation with validation + +- βœ… Invalid UUID handling- βœ… Order retrieval by ID + +- βœ… Filter by status (PENDING, COMPLETED)- βœ… Status filtering + +- βœ… Combined filtering + pagination- βœ… Error handling (404, 400, validation) + + + +**Frontend (5 tests)** - Component and hook tests:**Frontend (5 tests):** + +- βœ… OrdersListPage renders without errors- βœ… Component rendering + +- βœ… Loading state displays correctly- βœ… Loading states + +- βœ… useOrders hook fetches data- βœ… React Query hook initialization + +- βœ… Pagination works correctly + +- βœ… Error handling### API Testing with Postman + + + +### Test Files1. Import `postman/Order_Management_API.postman_collection.json` + +- `apps/backend/src/__tests__/orders.test.ts`2. Import `postman/Order_Management_Dev.postman_environment.json` + +- `apps/frontend/src/pages/__tests__/OrdersListPage.test.tsx`3. Select "Order Management - Development" environment + +- `apps/frontend/src/hooks/__tests__/useOrders.test.ts`4. Run collection to test all endpoints + + + +------ + + + +## πŸ“š API Documentation## πŸ“– API Documentation + + + +### Base URL### Endpoints + +- **Development**: `http://localhost:3000/api` + +- **Docker**: `http://localhost:3000/api`| Method | Endpoint | Description | Query Parameters | + +| -------- | ----------------- | ------------------------- | ----------------------------- | + +### Endpoints| `GET` | `/health` | Health check | - | + +| `GET` | `/api/orders` | Get paginated orders | `page`, `page_size`, `status` | + +#### `GET /health`| `GET` | `/api/orders/:id` | Get order by ID | - | + +Health check endpoint.| `POST` | `/api/orders` | Create new order | - | + +| `PUT` | `/api/orders/:id` | Update order | - | + +**Response** (200):| `DELETE` | `/api/orders/:id` | Delete order | - | + +```json + +{### Query Parameters + + "status": "ok", + + "message": "Order Management API is running"- **page** - Page number (default: 1) + +}- **page_size** - Items per page (default: 10, max: 100) + +```- **status** - Filter by status: `PENDING`, `COMPLETED`, or `CANCELLED` + + + +#### `GET /api/orders`### Example Requests + +Get paginated orders with optional filtering. + +#### Get All Orders (Paginated) + +**Query Parameters**:```bash + +- `page` (number, default: 1) - Page numberGET http://localhost:3000/api/orders?page=1&page_size=10 + +- `page_size` (number, default: 10, max: 100) - Items per page``` + +- `status` (string, optional) - Filter by status: `PENDING`, `COMPLETED`, `CANCELLED` + +#### Filter by Status + +**Response** (200):```bash + +```jsonGET http://localhost:3000/api/orders?status=PENDING + +{``` + + "success": true, + + "data": {#### Create Order + + "data": [```bash + + {POST http://localhost:3000/api/orders + + "id": "uuid",Content-Type: application/json + + "customer_name": "John Doe", + + "item": "Laptop",{ + + "quantity": 2, "customer_name": "John Doe", + + "status": "PENDING", "item": "MacBook Pro", + + "created_at": "2025-10-19T20:00:00.000Z" "quantity": 2, + + } "status": "PENDING" + + ],} + + "pagination": {``` + + "page": 1, + + "page_size": 10,#### Update Order + + "total": 50,```bash + + "total_pages": 5PUT http://localhost:3000/api/orders/{id} + + }Content-Type: application/json + + } + +}{ + +``` "status": "COMPLETED" + +} + +#### `GET /api/orders/:id```` + +Get single order by ID. + +#### Delete Order + +**Response** (200):```bash + +```jsonDELETE http://localhost:3000/api/orders/{id} + +{``` + + "success": true, + + "data": {### Response Format + + "id": "uuid", + + "customer_name": "John Doe",**Success Response:** + + "item": "Laptop",```json + + "quantity": 2,{ + + "status": "PENDING", "success": true, + + "created_at": "2025-10-19T20:00:00.000Z" "data": { ... } + + }} + +}``` + +``` + +**Error Response:** + +**Error** (404):```json + +```json{ + +{ "success": false, + + "success": false, "error": { + + "error": { "message": "Error message", + + "message": "Order not found", "code": "ERROR_CODE", + + "code": "ORDER_NOT_FOUND" "details": { ... } + + } } + +}} + +`````` -## πŸ“‹ Table of Contents -- [Quick Start with Docker](#-quick-start-with-docker-recommended) -- [Quick Start (Manual Setup)](#-quick-start-manual-setup) -- [Features](#-features) -- [Tech Stack](#-tech-stack) -- [Development](#-development) -- [Testing](#-testing) -- [API Documentation](#-api-documentation) -- [Architecture](#-architecture) -- [Project Structure](#-project-structure) ---- +#### `POST /api/orders`--- -## 🐳 Quick Start with Docker (Recommended) +Create a new order. -The easiest way to run this project is using Docker Compose. **No need to install PostgreSQL, Node.js, or pnpm manually!** +## πŸ—οΈ Architecture -### Prerequisites +**Request Body**: -- **Docker Desktop** installed and running -- **~3GB free disk space** for images and volumes +```json### Monorepo Structure -### Start the Application +{ -```bash -# Clone the repository -git clone -cd RedditTest + "customer_name": "John Doe",``` -# Start all services (PostgreSQL + Backend + Frontend) -docker-compose up --build -``` + "item": "Laptop",RedditTest/ -**That's it!** πŸŽ‰ The application will be available at: + "quantity": 2,β”œβ”€β”€ apps/ -- 🎨 **Frontend**: http://localhost:5173 -- πŸš€ **Backend API**: http://localhost:3000 -- πŸ—„οΈ **PostgreSQL**: localhost:5432 (managed by Docker) + "status": "PENDING"β”‚ β”œβ”€β”€ backend/ # Express.js API + Prisma ORM -The database will be **automatically migrated and seeded** on first run with 10 sample orders. +}β”‚ β”‚ β”œβ”€β”€ src/ -### Essential Commands +```β”‚ β”‚ β”‚ β”œβ”€β”€ controllers/ # HTTP request handlers -```bash -# Start (first time or after changes) -docker-compose up --build +β”‚ β”‚ β”‚ β”œβ”€β”€ middleware/ # Error handling, validation + +**Response** (201):β”‚ β”‚ β”‚ β”œβ”€β”€ routes/ # API route definitions + +```jsonβ”‚ β”‚ β”‚ └── __tests__/ # Integration tests + +{β”‚ β”‚ └── prisma/ + + "success": true,β”‚ β”‚ β”œβ”€β”€ schema.prisma # Database schema + + "data": {β”‚ β”‚ └── seed.ts # Database seeding -# Stop (keeps data) -docker-compose down + "id": "uuid",β”‚ └── frontend/ # React 19 + Vite SPA -# View logs -docker-compose logs -f backend + "customer_name": "John Doe",β”‚ └── src/ -# Run tests -docker-compose exec backend pnpm --filter backend test + "item": "Laptop",β”‚ β”œβ”€β”€ components/ # Reusable UI components + + "quantity": 2,β”‚ β”œβ”€β”€ pages/ # Route pages + + "status": "PENDING",β”‚ β”œβ”€β”€ hooks/ # React Query hooks + + "created_at": "2025-10-19T20:00:00.000Z"β”‚ └── services/ # API client + + }β”œβ”€β”€ packages/ + +}β”‚ └── shared-types/ # Shared Zod schemas & TypeScript types + +```└── postman/ # API testing collection -# Reset database (⚠️ deletes all data) -docker-compose down -v && docker-compose up -d ``` -### πŸ’Ύ Data Persistence -- βœ… `docker-compose down` β†’ **Keeps** database data -- ❌ `docker-compose down -v` β†’ **Deletes** database data -- First startup auto-seeds 10 sample orders -- Data persists between restarts +**Error** (400): -### Hot Reload in Docker +```json### Type-First Development Flow -All source code directories are mounted as volumes, so changes to your code will trigger automatic reloads: +{ -- βœ… Backend: `tsx` watch mode automatically restarts on file changes -- βœ… Frontend: Vite HMR (Hot Module Replacement) updates instantly -- βœ… Shared Types: Changes reflect immediately in both apps + "success": false,1. **Define Zod schema** in `packages/shared-types/src/index.ts`: ---- + "error": { ```typescript -## πŸ’» Quick Start (Manual Setup) + "message": "Validation error", export const CreateOrderSchema = z.object({ -If you prefer to run without Docker, follow these steps: + "code": "VALIDATION_ERROR", customer_name: z.string().min(1).max(255), -## ✨ Features + "details": [ quantity: z.number().int().positive(), -### Core Functionality -- βœ… **Full CRUD Operations** - Create, Read, Update, Delete orders -- βœ… **Server-side Pagination** - Efficient data loading with configurable page size -- βœ… **Status Filtering** - Filter orders by PENDING, COMPLETED, or CANCELLED status -- βœ… **Real-time Validation** - Zod schemas validate data on both client and server -- βœ… **End-to-end Type Safety** - Shared types between frontend and backend + { status: OrderStatusSchema -### User Experience -- βœ… **Toast Notifications** - Professional feedback for all actions -- βœ… **Status Badges** - Color-coded badges (🟑 Pending, 🟒 Completed, πŸ”΄ Cancelled) -- βœ… **Delete Confirmation** - Modal dialog prevents accidental deletions -- βœ… **Loading States** - Clear feedback during async operations -- βœ… **Error Handling** - User-friendly error messages -- βœ… **Responsive Design** - Mobile-friendly UI with TailwindCSS + "path": ["customer_name"], }); -### Technical Excellence -- βœ… **Monorepo Architecture** - pnpm workspaces with shared types -- βœ… **React Query** - Automatic caching, optimistic updates, cache invalidation -- βœ… **Type-First Development** - Zod schemas generate TypeScript types -- βœ… **Testing** - 15 tests total (10 backend + 5 frontend) -- βœ… **Code Quality** - ESLint, Prettier, and strict TypeScript + "message": "Customer name is required" ``` ---- + } -## πŸ› οΈ Tech Stack + ]2. **Infer TypeScript type**: -### Backend -- **Runtime**: Node.js 18+ with TypeScript -- **Framework**: Express.js -- **Database**: PostgreSQL 14+ with Prisma ORM -- **Validation**: Zod (runtime validation + types) -- **Testing**: Jest + Supertest (10 tests) + } ```typescript -### Frontend -- **Framework**: React 19 with TypeScript -- **Build Tool**: Vite -- **Styling**: TailwindCSS -- **State Management**: React Query (server state) -- **Forms**: React Hook Form + Zod resolver -- **Notifications**: React Hot Toast -- **Testing**: Vitest + React Testing Library (5 tests) +} export type CreateOrderDTO = z.infer; -### Shared -- **Monorepo**: pnpm workspaces -- **Types**: Shared Zod schemas in `@shared/types` -- **Code Quality**: ESLint + Prettier +``` ``` ---- -## οΏ½ Quick Start (Manual Setup) -### Prerequisites -- **Node.js** >= 18.0.0 -- **pnpm** >= 8.0.0 -- **PostgreSQL** >= 14 (running locally) +#### `PUT /api/orders/:id`3. **Backend validates** with same schema: -### 1. Clone & Install +Update an existing order. ```typescript -```bash -git clone -cd RedditTest -pnpm install -``` + const validated = CreateOrderSchema.parse(req.body); -### 2. Setup Environment Variables +**Request Body** (all fields optional): ``` -**Backend** (`apps/backend/.env`): +```json -```bash -# Copy example file -cp apps/backend/.env.example apps/backend/.env -``` +{4. **Frontend uses** without duplication: -Edit with your PostgreSQL credentials: + "customer_name": "Jane Doe", ```typescript -```env -DATABASE_URL="postgresql://postgres:postgres@localhost:5432/orders_db?schema=public" -PORT=3000 -NODE_ENV=development -``` + "item": "Updated Item", import { CreateOrderDTO } from '@shared/types'; -**Frontend** (`apps/frontend/.env`): + "quantity": 5, const orderData: CreateOrderDTO = { ... }; -```bash -# Copy example file -cp apps/frontend/.env.example apps/frontend/.env -``` + "status": "COMPLETED" ``` -Default values should work: +} -```env -VITE_API_URL=http://localhost:3000/api -``` +```**Result:** Change validation once, get runtime safety + TypeScript types everywhere. No drift between frontend and backend. -### 3. Setup Database -```bash -# Generate Prisma client -pnpm --filter backend prisma:generate -# Run migrations (creates tables) -pnpm --filter backend prisma:migrate dev +**Response** (200): Same structure as GET### Key Architectural Decisions -# (Optional) Seed database -pnpm --filter backend prisma:seed -``` -### 4. Start Development Servers -**Terminal 1 - Backend:** +#### `DELETE /api/orders/:id`#### Why Monorepo? -```bash -pnpm dev:backend -``` +Delete an order.- Shared types eliminate duplication -πŸš€ Backend: http://localhost:3000 +- Single source of truth for validation -**Terminal 2 - Frontend:** +**Response** (200):- Changes instantly available across apps -```bash -pnpm dev:frontend -``` +```json -🎨 Frontend: http://localhost:5173 +{#### Why Zod? -> **Note:** The backend automatically seeds the database with 10 sample orders on first run if the database is empty. + "success": true,- Runtime validation catches errors at API boundaries ---- + "data": {- TypeScript types auto-generated from schemas -## πŸ’» Development + "id": "uuid",- Single schema for validation + types -> **πŸ’‘ Tip:** If using Docker, replace `pnpm` commands with `docker-compose exec ` (e.g., `docker-compose exec backend pnpm --filter backend test`) + "customer_name": "John Doe", -### Quick Command Reference + "item": "Laptop",#### Why React Query? -```bash -# Development (Manual) -pnpm dev:backend # Start backend (auto-seeds if empty) -pnpm dev:frontend # Start frontend + "quantity": 2,- Automatic caching reduces API calls -# Development (Docker) -docker-compose up # Start all services -docker-compose up -d # Start in background -docker-compose logs -f backend # View backend logs + "status": "PENDING",- Optimistic updates for instant UI feedback -# Testing (Manual) -pnpm --filter backend test # Run backend tests (10 tests) -pnpm --filter frontend test --run # Run frontend tests (5 tests) + "created_at": "2025-10-19T20:00:00.000Z"- Cache invalidation keeps data fresh -# Testing (Docker) -docker-compose exec backend pnpm --filter backend test -docker-compose exec frontend pnpm --filter frontend test --run + }- Replaces Redux/Zustand for server state -# Database (Manual) -pnpm --filter backend prisma:studio # Open database GUI (port 5555) -pnpm --filter backend prisma:generate # Regenerate Prisma client -pnpm --filter backend prisma:migrate dev # Create new migration -pnpm --filter backend prisma:seed # Manual seed -pnpm --filter backend prisma:migrate reset # ⚠️ Reset database (deletes all data) +} -# Database (Docker) -docker-compose exec backend pnpm --filter backend prisma:studio -docker-compose exec backend pnpm --filter backend prisma:generate +```#### Why Prisma? -# Build -pnpm --filter backend build # Build backend -pnpm --filter frontend build # Build frontend -``` +- Type-safe database access prevents SQL errors -### Database Management +### Postman Collection- Automatic migrations track schema changes -**Prisma Studio** - Visual database editor: +- Generated client provides autocomplete -```bash -pnpm --filter backend prisma:studio -``` +Import the collection from `postman/Order_Management_API.postman_collection.json` for ready-to-use API tests. -Opens at http://localhost:5555 +#### Why No Repository Layer? -**Seeding Behavior:** -- Seed script checks if data exists before inserting -- Only seeds if database is empty -- To reseed: `pnpm --filter backend prisma:migrate reset` +---- Simple domain (single entity) doesn't need abstraction ---- +- Prisma calls are clear and type-safe -## πŸ§ͺ Testing +## πŸ—οΈ Architecture- Easy to refactor when complexity grows -### Run Tests -```bash -# Backend tests (Jest + Supertest) -pnpm --filter backend test -# Frontend tests (Vitest + React Testing Library) -pnpm --filter frontend test --run +### Type-First Development--- -# All tests -pnpm --filter backend test && pnpm --filter frontend test --run -``` -### Test Coverage -**Backend (10 tests):** -- βœ… Pagination with metadata -- βœ… Order creation with validation -- βœ… Order retrieval by ID -- βœ… Status filtering -- βœ… Error handling (404, 400, validation) +All data structures originate as **Zod schemas** in `packages/shared-types/src/index.ts`:## πŸ“ Project Structure -**Frontend (5 tests):** -- βœ… Component rendering -- βœ… Loading states -- βœ… React Query hook initialization -### API Testing with Postman -1. Import `postman/Order_Management_API.postman_collection.json` -2. Import `postman/Order_Management_Dev.postman_environment.json` -3. Select "Order Management - Development" environment -4. Run collection to test all endpoints +```typescript### Backend Organization ---- +// Define once -## πŸ“– API Documentation +export const CreateOrderSchema = z.object({``` -### Endpoints + customer_name: z.string().min(1).max(255),apps/backend/src/ -| Method | Endpoint | Description | Query Parameters | -| -------- | ----------------- | ------------------------- | ----------------------------- | -| `GET` | `/health` | Health check | - | -| `GET` | `/api/orders` | Get paginated orders | `page`, `page_size`, `status` | -| `GET` | `/api/orders/:id` | Get order by ID | - | -| `POST` | `/api/orders` | Create new order | - | -| `PUT` | `/api/orders/:id` | Update order | - | -| `DELETE` | `/api/orders/:id` | Delete order | - | + item: z.string().min(1).max(255),β”œβ”€β”€ index.ts # Express app setup + middleware -### Query Parameters + quantity: z.number().int().positive(),β”œβ”€β”€ controllers/ -- **page** - Page number (default: 1) -- **page_size** - Items per page (default: 10, max: 100) -- **status** - Filter by status: `PENDING`, `COMPLETED`, or `CANCELLED` + status: OrderStatusSchemaβ”‚ └── orders.controller.ts # Order CRUD logic -### Example Requests +});β”œβ”€β”€ middleware/ -#### Get All Orders (Paginated) -```bash -GET http://localhost:3000/api/orders?page=1&page_size=10 -``` +β”‚ β”œβ”€β”€ errorHandler.ts # Centralized error handling -#### Filter by Status -```bash -GET http://localhost:3000/api/orders?status=PENDING -``` +// Use everywhereβ”‚ └── validateUUID.ts # UUID validation middleware -#### Create Order -```bash -POST http://localhost:3000/api/orders -Content-Type: application/json +export type CreateOrderDTO = z.infer;β”œβ”€β”€ routes/ -{ - "customer_name": "John Doe", - "item": "MacBook Pro", - "quantity": 2, - "status": "PENDING" -} -``` +```β”‚ └── orders.routes.ts # Route definitions -#### Update Order -```bash -PUT http://localhost:3000/api/orders/{id} -Content-Type: application/json +└── __tests__/ -{ - "status": "COMPLETED" -} -``` +**Backend** validates at runtime: β”œβ”€β”€ setup.ts # Test configuration -#### Delete Order -```bash -DELETE http://localhost:3000/api/orders/{id} -``` +```typescript └── orders.test.ts # Integration tests -### Response Format +const validated = CreateOrderSchema.parse(req.body); // throws ZodError if invalid``` -**Success Response:** -```json -{ - "success": true, - "data": { ... } -} ``` -**Error Response:** -```json -{ - "success": false, - "error": { - "message": "Error message", - "code": "ERROR_CODE", - "details": { ... } - } -} -``` +### Frontend Organization ---- +**Frontend** gets TypeScript types: -## πŸ—οΈ Architecture +```typescript``` -### Monorepo Structure +const orderData: CreateOrderDTO = { ... }; // Full type safetyapps/frontend/src/ -``` -RedditTest/ -β”œβ”€β”€ apps/ -β”‚ β”œβ”€β”€ backend/ # Express.js API + Prisma ORM -β”‚ β”‚ β”œβ”€β”€ src/ -β”‚ β”‚ β”‚ β”œβ”€β”€ controllers/ # HTTP request handlers -β”‚ β”‚ β”‚ β”œβ”€β”€ middleware/ # Error handling, validation -β”‚ β”‚ β”‚ β”œβ”€β”€ routes/ # API route definitions -β”‚ β”‚ β”‚ └── __tests__/ # Integration tests -β”‚ β”‚ └── prisma/ -β”‚ β”‚ β”œβ”€β”€ schema.prisma # Database schema -β”‚ β”‚ └── seed.ts # Database seeding -β”‚ └── frontend/ # React 19 + Vite SPA -β”‚ └── src/ -β”‚ β”œβ”€β”€ components/ # Reusable UI components -β”‚ β”œβ”€β”€ pages/ # Route pages -β”‚ β”œβ”€β”€ hooks/ # React Query hooks -β”‚ └── services/ # API client -β”œβ”€β”€ packages/ -β”‚ └── shared-types/ # Shared Zod schemas & TypeScript types -└── postman/ # API testing collection -``` +```β”œβ”€β”€ main.tsx # App entry point -### Type-First Development Flow +β”œβ”€β”€ App.tsx # Router setup -1. **Define Zod schema** in `packages/shared-types/src/index.ts`: - ```typescript - export const CreateOrderSchema = z.object({ - customer_name: z.string().min(1).max(255), - quantity: z.number().int().positive(), - status: OrderStatusSchema - }); - ``` +### Data Flowβ”œβ”€β”€ components/ -2. **Infer TypeScript type**: - ```typescript - export type CreateOrderDTO = z.infer; - ``` +β”‚ β”œβ”€β”€ ConfirmDialog.tsx # Delete confirmation modal -3. **Backend validates** with same schema: - ```typescript - const validated = CreateOrderSchema.parse(req.body); - ``` +```β”‚ β”œβ”€β”€ Layout.tsx # Page layout wrapper -4. **Frontend uses** without duplication: - ```typescript - import { CreateOrderDTO } from '@shared/types'; - const orderData: CreateOrderDTO = { ... }; - ``` +User Action (Frontend)β”‚ └── StatusBadge.tsx # Status display component -**Result:** Change validation once, get runtime safety + TypeScript types everywhere. No drift between frontend and backend. + β†“β”œβ”€β”€ pages/ -### Key Architectural Decisions +React Query Hook (useOrders)β”‚ β”œβ”€β”€ OrdersListPage.tsx # List view with pagination -#### Why Monorepo? -- Shared types eliminate duplication -- Single source of truth for validation -- Changes instantly available across apps + ↓│ β”œβ”€β”€ OrderDetailsPage.tsx # Single order view -#### Why Zod? -- Runtime validation catches errors at API boundaries -- TypeScript types auto-generated from schemas -- Single schema for validation + types +API Service (ordersApi.createOrder)β”‚ β”œβ”€β”€ CreateOrderPage.tsx # Create form -#### Why React Query? -- Automatic caching reduces API calls -- Optimistic updates for instant UI feedback -- Cache invalidation keeps data fresh -- Replaces Redux/Zustand for server state + ↓│ └── EditOrderPage.tsx # Edit form -#### Why Prisma? -- Type-safe database access prevents SQL errors -- Automatic migrations track schema changes -- Generated client provides autocomplete +Express Route (/api/orders)β”œβ”€β”€ hooks/ -#### Why No Repository Layer? -- Simple domain (single entity) doesn't need abstraction -- Prisma calls are clear and type-safe -- Easy to refactor when complexity grows + ↓│ └── useOrders.ts # React Query hooks ---- +Zod Validation (CreateOrderSchema.parse)β”œβ”€β”€ services/ -## πŸ“ Project Structure + ↓│ └── orders.service.ts # API client -### Backend Organization +Controller (createOrder)└── lib/ -``` -apps/backend/src/ -β”œβ”€β”€ index.ts # Express app setup + middleware -β”œβ”€β”€ controllers/ -β”‚ └── orders.controller.ts # Order CRUD logic -β”œβ”€β”€ middleware/ -β”‚ β”œβ”€β”€ errorHandler.ts # Centralized error handling -β”‚ └── validateUUID.ts # UUID validation middleware -β”œβ”€β”€ routes/ -β”‚ └── orders.routes.ts # Route definitions -└── __tests__/ - β”œβ”€β”€ setup.ts # Test configuration - └── orders.test.ts # Integration tests -``` + ↓ └── api.ts # Axios configuration -### Frontend Organization +Prisma Client (prisma.order.create)``` -``` -apps/frontend/src/ -β”œβ”€β”€ main.tsx # App entry point -β”œβ”€β”€ App.tsx # Router setup -β”œβ”€β”€ components/ -β”‚ β”œβ”€β”€ ConfirmDialog.tsx # Delete confirmation modal -β”‚ β”œβ”€β”€ Layout.tsx # Page layout wrapper -β”‚ └── StatusBadge.tsx # Status display component -β”œβ”€β”€ pages/ -β”‚ β”œβ”€β”€ OrdersListPage.tsx # List view with pagination -β”‚ β”œβ”€β”€ OrderDetailsPage.tsx # Single order view -β”‚ β”œβ”€β”€ CreateOrderPage.tsx # Create form -β”‚ └── EditOrderPage.tsx # Edit form -β”œβ”€β”€ hooks/ -β”‚ └── useOrders.ts # React Query hooks -β”œβ”€β”€ services/ -β”‚ └── orders.service.ts # API client -└── lib/ - └── api.ts # Axios configuration -``` + ↓ + +PostgreSQL Database### Shared Types + + ↓ + +Response with ApiResponse```typescript -### Shared Types + ↓// packages/shared-types/src/index.ts -```typescript -// packages/shared-types/src/index.ts +React Query Cache Update + + ↓// Schemas (validation + types) + +UI Update (automatic re-render)export const OrderStatusSchema = z.enum(['PENDING', 'COMPLETED', 'CANCELLED']); + +```export const CreateOrderSchema = z.object({ ... }); -// Schemas (validation + types) -export const OrderStatusSchema = z.enum(['PENDING', 'COMPLETED', 'CANCELLED']); -export const CreateOrderSchema = z.object({ ... }); export const UpdateOrderSchema = z.object({ ... }); +### Error Handling + // Types (inferred from schemas) -export type OrderStatus = z.infer; + +Centralized error middleware converts all errors to consistent `ApiError` format:export type OrderStatus = z.infer; + export type CreateOrderDTO = z.infer; -export type Order = { ... }; -export type ApiResponse = { ... }; -``` ---- +```typescriptexport type Order = { ... }; + +{export type ApiResponse = { ... }; + + success: false,``` + + error: { + + message: "Error description",--- -## 🎯 Requirements Checklist + code: "ERROR_CODE", -### βœ… Core Requirements (100%) + details?: any // For validation errors## 🎯 Requirements Checklist + + } + +}### βœ… Core Requirements (100%) + +``` **Backend:** -- βœ… All CRUD endpoints (POST, GET, PUT, DELETE) + +---- βœ… All CRUD endpoints (POST, GET, PUT, DELETE) + - βœ… Order structure with UUID, customer_name, item, quantity, status, created_at -- βœ… Pagination support with page and page_size + +## πŸ“¦ Docker Details- βœ… Pagination support with page and page_size + - βœ… Node.js + TypeScript + Express -- βœ… PostgreSQL database with Prisma ORM -**Frontend:** -- βœ… Order list view with pagination -- βœ… Order details view -- βœ… Create/Edit order forms -- βœ… Delete functionality +### Services- βœ… PostgreSQL database with Prisma ORM + + + +| Service | Port | Description |**Frontend:** + +|---------|------|-------------|- βœ… Order list view with pagination + +| **postgres** | 5432 | PostgreSQL 14 Alpine with persistent volume |- βœ… Order details view + +| **backend** | 3000 | Express API with auto-migration and seeding |- βœ… Create/Edit order forms + +| **frontend** | 5173 | Vite dev server with HMR |- βœ… Delete functionality + - βœ… Loading and error states -- βœ… TypeScript + React 19 -### ⭐ Bonus Features (100%) +### Volumes- βœ… TypeScript + React 19 + + + +- `postgres_data` - Persists database data across container restarts### ⭐ Bonus Features (100%) + +- Source code mounted for hot reload (backend/src, frontend/src, shared-types/src) - βœ… Status filtering (backend + frontend) -- βœ… Comprehensive testing (15 tests) + +### Networks- βœ… Comprehensive testing (15 tests) + - βœ… Shared types monorepo setup -- βœ… Comprehensive documentation + +- `orders_network` - Bridge network for service communication- βœ… Comprehensive documentation + - βœ… ESLint + Prettier configuration -- βœ… Professional error handling + +### Auto-Startup Process- βœ… Professional error handling + - βœ… Toast notifications -- βœ… Postman collection -- βœ… **Docker setup for easy local development** 🐳 ---- +```- βœ… Postman collection + +1. PostgreSQL starts and runs health check- βœ… **Docker setup for easy local development** 🐳 + +2. Backend waits for healthy PostgreSQL + +3. Backend runs: prisma migrate deploy--- + +4. Backend runs: prisma generate -## 🚨 Important Notes +5. Backend runs: seed script (only if DB empty)## 🚨 Important Notes + +6. Backend starts Express server + +7. Frontend starts Vite dev server### Docker vs Manual Setup + +```- **Docker**: Zero configuration, all dependencies included, consistent environment -### Docker vs Manual Setup -- **Docker**: Zero configuration, all dependencies included, consistent environment - **Manual**: More control, faster iterative development, requires PostgreSQL installation +--- + ### Prisma Client Generation -After modifying `prisma/schema.prisma`, always regenerate the client: -```bash -# Manual -pnpm --filter backend prisma:generate +## 🀝 ContributingAfter modifying `prisma/schema.prisma`, always regenerate the client: + + + +1. Fork the repository```bash + +2. Create a feature branch (`git checkout -b feat/amazing-feature`)# Manual + +3. Commit changes (`git commit -m 'feat: Add amazing feature'`)pnpm --filter backend prisma:generate + +4. Push to branch (`git push origin feat/amazing-feature`) + +5. Open a Pull Request# Docker -# Docker docker-compose exec backend pnpm --filter backend prisma:generate -``` -**Symptom of missing generation:** `Property 'order' does not exist on type 'PrismaClient'` +---``` + + + +## πŸ“„ License**Symptom of missing generation:** `Property 'order' does not exist on type 'PrismaClient'` + + + +This project is licensed under the MIT License.### Workspace Linking -### Workspace Linking Shared types use `workspace:*` protocol. Changes are immediately available without reinstalling. +--- + If you see stale types: -```bash + +## πŸ‘€ Author```bash + pnpm install # Rebuild workspace links -``` -### Auto-Seeding +**Daniel Khadour**``` + + + +- GitHub: [@LeSoviet](https://github.com/LeSoviet)### Auto-Seeding + The backend checks if the database is empty and automatically seeds on first run. Manual seeding only needed after database reset. +--- + ### Docker Hot Reload -Changes to source files automatically trigger reloads: + +## πŸ™ AcknowledgmentsChanges to source files automatically trigger reloads: + - **Backend**: `tsx` watch mode restarts on changes -- **Frontend**: Vite HMR updates instantly -- **Shared Types**: Changes reflect immediately in both apps -### Vite Configuration -This project uses `rolldown-vite@7.1.14` (specified in root `package.json` overrides). If you encounter Vite type errors, ensure `apps/frontend/src/vite-env.d.ts` exists. +Built as a technical challenge to demonstrate:- **Frontend**: Vite HMR updates instantly ---- +- Full-stack TypeScript development- **Shared Types**: Changes reflect immediately in both apps + +- Modern React patterns (19+) + +- Type-safe API design### Vite Configuration + +- Docker containerizationThis project uses `rolldown-vite@7.1.14` (specified in root `package.json` overrides). If you encounter Vite type errors, ensure `apps/frontend/src/vite-env.d.ts` exists. + +- Monorepo architecture + +- Test-driven development--- -## πŸ“š Additional Resources -- **Prisma Studio**: Visual database editor at http://localhost:5555 + +---## πŸ“š Additional Resources + + + +**⭐ If you found this project helpful, please consider giving it a star!**- **Prisma Studio**: Visual database editor at http://localhost:5555 + - **Postman Collection**: Pre-configured API tests in `/postman` directory - **Type Definitions**: All schemas in `packages/shared-types/src/index.ts` @@ -633,7 +1260,3 @@ This project uses `rolldown-vite@7.1.14` (specified in root `package.json` overr ## 🀝 Contributing This is a technical challenge project. For questions or issues, please open a GitHub issue. - ---- - -**Built with** ❀️ using TypeScript, React 19, Node.js, Express, PostgreSQL, and Prisma. From 0c184c97d71c9ab6994b63e261fc937def6b17ea Mon Sep 17 00:00:00 2001 From: lesoviet Date: Sun, 19 Oct 2025 22:01:04 -0300 Subject: [PATCH 7/7] docs: Update README for improved clarity and structure, add API documentation, and enhance quick start instructions --- README.md | 1313 ++++------------------------------------------------- 1 file changed, 81 insertions(+), 1232 deletions(-) diff --git a/README.md b/README.md index 61491c6..cf09c3b 100644 --- a/README.md +++ b/README.md @@ -1,1262 +1,111 @@ -# πŸš€ Full-Stack Order Management System# πŸš€ Full-Stack Order Management System +# πŸš€ Full-Stack Order Management System +A modern, production-ready **Full-Stack Order Management application** focused on end-to-end type safety, robust features, and professional UX. Features complete **CRUD operations**, **server-side pagination**, and **status filtering**. +*** -[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?logo=typescript)](https://www.typescriptlang.org/)[![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?logo=typescript)](https://www.typescriptlang.org/) +## πŸ› οΈ Tech Stack Highlights -[![React](https://img.shields.io/badge/React-19.1-61dafb?logo=react)](https://react.dev/)[![React](https://img.shields.io/badge/React-19.1-61dafb?logo=react)](https://react.dev/) +This project uses a **pnpm monorepo** architecture to share types between the frontend and backend. -[![Node.js](https://img.shields.io/badge/Node.js-22-green?logo=node.js)](https://nodejs.org/)[![Node.js](https://img.shields.io/badge/Node.js-22-green?logo=node.js)](https://nodejs.org/) +| Area | Technology | Purpose | +| :--- | :--- | :--- | +| **Backend** | **Node.js 22**, **Express** | Runtime & Web Framework | +| **Database** | **PostgreSQL 14**, **Prisma** | ORM & Data Persistence | +| **Frontend** | **React 19**, **Vite** | UI Framework & Build Tool | +| **Type Safety** | **TypeScript 5.9**, **Zod** | End-to-end Type Safety & Validation | +| **State** | **React Query** | Server State Management & Caching | -[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-14-blue?logo=postgresql)](https://www.postgresql.org/)[![PostgreSQL](https://img.shields.io/badge/PostgreSQL-14-blue?logo=postgresql)](https://www.postgresql.org/) +*** -[![Prisma](https://img.shields.io/badge/Prisma-6.3-2D3748?logo=prisma)](https://www.prisma.io/)[![Prisma](https://img.shields.io/badge/Prisma-6.3-2D3748?logo=prisma)](https://www.prisma.io/) +## ✨ Key Features -[![Vite](https://img.shields.io/badge/Vite-6.0-646CFF?logo=vite)](https://vitejs.dev/)[![Vite](https://img.shields.io/badge/Vite-6.0-646CFF?logo=vite)](https://vitejs.dev/) +### Core Functionality +* βœ… **Full CRUD Operations** for orders. +* βœ… **Server-side Pagination** and **Status Filtering** (PENDING, COMPLETED, CANCELLED). +* βœ… **Real-time Validation** using shared **Zod** schemas. +* βœ… **End-to-end Type Safety** across the stack. -[![Docker](https://img.shields.io/badge/Docker-Ready-2496ED?logo=docker)](https://www.docker.com/) +### User Experience +* βœ… Professional **Toast Notifications** and clear **Status Badges**. +* βœ… **Responsive Design** using TailwindCSS. -A modern, production-ready order management application built with **TypeScript**, **React 19**, **Express**, **Prisma**, and **PostgreSQL**. Features complete CRUD operations, pagination, filtering, end-to-end type safety, and professional UX patterns. +### Developer Experience +* βœ… **Docker Support** for quick setup. +* βœ… **Monorepo Architecture** with shared types. +* βœ… Comprehensive **Testing** (10 backend, 5 frontend tests). -A modern, production-ready order management application built with **TypeScript**, **React 19**, **Express**, **Prisma**, and **PostgreSQL**. Features complete CRUD operations, pagination, filtering, end-to-end type safety, Docker support, and professional UX patterns. +*** ---- +## 🐳 Quick Start (Recommended: Docker) ---- +The easiest way to run the entire application with one command. No need to install PostgreSQL or Node.js locally. -## πŸ“‹ Table of Contents +### Prerequisites +* **Docker Desktop** installed and running. -## πŸ“‹ Table of Contents +### Start the Application -- [Quick Start with Docker](#-quick-start-with-docker-recommended) +1. Clone the repository and navigate to the root directory. +2. Run the following command: -- [Quick Start with Docker](#-quick-start-with-docker-recommended)- [Quick Start (Manual Setup)](#-quick-start-manual-setup) + ```bash + docker compose up --build + ``` -- [Manual Setup](#-manual-setup-without-docker)- [Features](#-features) +### Access Points +* 🎨 **Frontend:** `http://localhost:5173` +* πŸš€ **Backend API:** `http://localhost:3000` -- [Features](#-features)- [Tech Stack](#-tech-stack) +> πŸ’‘ The database is **automatically migrated and seeded** with 10 sample orders on the first run. -- [Tech Stack](#-tech-stack)- [Development](#-development) +*** -- [Development](#-development)- [Testing](#-testing) +## πŸ’» Manual Setup -- [Testing](#-testing)- [API Documentation](#-api-documentation) +For manual setup, you need **Node.js >= 22.0.0**, **pnpm >= 8.0.0**, and a running local **PostgreSQL >= 14** instance. -- [API Documentation](#-api-documentation)- [Architecture](#-architecture) +1. **Clone & Install:** + ```bash + git clone + cd RedditTest + pnpm install + ``` +2. **Database Setup:** Configure your database URL in `apps/backend/.env`, then: + ```bash + pnpm --filter backend prisma:generate # Generate Prisma Client + pnpm --filter backend prisma:migrate dev # Run migrations + pnpm --filter backend prisma:seed # Seed data (optional) + ``` +3. **Start Servers:** Run these commands in two separate terminals: + ```bash + # Terminal 1: Backend API (http://localhost:3000) + pnpm dev:backend + + # Terminal 2: Frontend (http://localhost:5173) + pnpm dev:frontend + ``` -- [Project Structure](#-project-structure)- [Project Structure](#-project-structure) +*** +## πŸ“š API Documentation +### Base URL +`http://localhost:3000/api` ------- +### Endpoints +| Method | Endpoint | Description | Query Parameters | +| :--- | :--- | :--- | :--- | +| `GET` | `/api/orders` | Get paginated orders | `page`, `page_size`, `status` | +| `GET` | `/api/orders/:id` | Get order by ID | - | +| `POST` | `/api/orders` | Create new order | - | +| `PUT` | `/api/orders/:id` | Update order | - | +| `DELETE` | `/api/orders/:id` | Delete order | - | - -## 🐳 Quick Start with Docker (Recommended)## 🐳 Quick Start with Docker (Recommended) - - - -The easiest way to run this project is using Docker Compose. **No need to install PostgreSQL, Node.js, or pnpm manually!**The easiest way to run this project is using Docker Compose. **No need to install PostgreSQL, Node.js, or pnpm manually!** - - - -### Prerequisites### Prerequisites - - - -- [Docker Desktop](https://www.docker.com/products/docker-desktop/) installed and running- **Docker Desktop** installed and running - -- ~3GB free disk space- **~3GB free disk space** for images and volumes - - - -### Start the Application### Start the Application - - - -```bash```bash - -# Clone the repository# Clone the repository - -git clone https://github.com/LeSoviet/RedditTest.gitgit clone - -cd RedditTestcd RedditTest - - - -# Start all services (PostgreSQL + Backend + Frontend)# Start all services (PostgreSQL + Backend + Frontend) - -docker compose up --builddocker-compose up --build - -`````` - - - -**That's it!** πŸŽ‰ The application will be available at:**That's it!** πŸŽ‰ The application will be available at: - - - -- 🎨 **Frontend**: http://localhost:5173- 🎨 **Frontend**: http://localhost:5173 - -- πŸš€ **Backend API**: http://localhost:3000- πŸš€ **Backend API**: http://localhost:3000 - -- πŸ“š **API Health**: http://localhost:3000/health- πŸ—„οΈ **PostgreSQL**: localhost:5432 (managed by Docker) - - - -The database will be **automatically migrated and seeded** with 10 sample orders on first run.The database will be **automatically migrated and seeded** on first run with 10 sample orders. - - - -### Essential Docker Commands### Essential Commands - - - -```bash```bash - -# Start (first time or after code changes)# Start (first time or after changes) - -docker compose up --builddocker-compose up --build - - - -# Start in background# Stop (keeps data) - -docker compose up -ddocker-compose down - - - -# Stop (keeps database data)# View logs - -docker compose downdocker-compose logs -f backend - - - -# View backend logs (see database queries)# Run tests - -docker compose logs -f backenddocker-compose exec backend pnpm --filter backend test - - - -# Run tests# Reset database (⚠️ deletes all data) - -docker compose exec backend pnpm --filter backend testdocker-compose down -v && docker-compose up -d - -``` - -# Open Prisma Studio (database GUI) - -docker compose exec backend pnpm --filter backend prisma:studio### πŸ’Ύ Data Persistence - -# Opens at http://localhost:5555- βœ… `docker-compose down` β†’ **Keeps** database data - -- ❌ `docker-compose down -v` β†’ **Deletes** database data - -# Reset database (⚠️ deletes all data)- First startup auto-seeds 10 sample orders - -docker compose down -v && docker compose up -d- Data persists between restarts - -``` - -### Hot Reload in Docker - -### πŸ’Ύ Data Persistence - -All source code directories are mounted as volumes, so changes to your code will trigger automatic reloads: - -- βœ… `docker compose down` β†’ **Keeps** database data - -- ❌ `docker compose down -v` β†’ **Deletes** database data- βœ… Backend: `tsx` watch mode automatically restarts on file changes - -- First startup: Auto-migrates schema and seeds 10 orders- βœ… Frontend: Vite HMR (Hot Module Replacement) updates instantly - -- Subsequent startups: Keeps existing data (no re-seeding)- βœ… Shared Types: Changes reflect immediately in both apps - - - -### πŸ”„ Hot Reload--- - - - -All source code is mounted as volumes. Changes trigger automatic reloads:## πŸ’» Quick Start (Manual Setup) - - - -- **Backend**: `tsx` watch mode (auto-restart on save)If you prefer to run without Docker, follow these steps: - -- **Frontend**: Vite HMR (instant updates) - -- **Shared Types**: Changes reflect immediately in both apps## ✨ Features - - - ----### Core Functionality - -- βœ… **Full CRUD Operations** - Create, Read, Update, Delete orders - -## πŸ’» Manual Setup (Without Docker)- βœ… **Server-side Pagination** - Efficient data loading with configurable page size - -- βœ… **Status Filtering** - Filter orders by PENDING, COMPLETED, or CANCELLED status - -### Prerequisites- βœ… **Real-time Validation** - Zod schemas validate data on both client and server - -- βœ… **End-to-end Type Safety** - Shared types between frontend and backend - -- **Node.js** >= 22.0.0 ([download](https://nodejs.org/)) - -- **pnpm** >= 8.0.0 (`npm install -g pnpm`)### User Experience - -- **PostgreSQL** >= 14 ([download](https://www.postgresql.org/download/))- βœ… **Toast Notifications** - Professional feedback for all actions - -- βœ… **Status Badges** - Color-coded badges (🟑 Pending, 🟒 Completed, πŸ”΄ Cancelled) - -### 1. Clone & Install- βœ… **Delete Confirmation** - Modal dialog prevents accidental deletions - -- βœ… **Loading States** - Clear feedback during async operations - -```bash- βœ… **Error Handling** - User-friendly error messages - -git clone https://github.com/LeSoviet/RedditTest.git- βœ… **Responsive Design** - Mobile-friendly UI with TailwindCSS - -cd RedditTest - -pnpm install### Technical Excellence - -```- βœ… **Monorepo Architecture** - pnpm workspaces with shared types - -- βœ… **React Query** - Automatic caching, optimistic updates, cache invalidation - -### 2. Setup Environment Variables- βœ… **Type-First Development** - Zod schemas generate TypeScript types - -- βœ… **Testing** - 15 tests total (10 backend + 5 frontend) - -**Backend** (`apps/backend/.env`):- βœ… **Code Quality** - ESLint, Prettier, and strict TypeScript - - - -```env--- - -DATABASE_URL="postgresql://postgres:postgres@localhost:5432/orders_db?schema=public" - -PORT=3000## πŸ› οΈ Tech Stack - -NODE_ENV=development - -```### Backend - -- **Runtime**: Node.js 18+ with TypeScript - -**Frontend** (`apps/frontend/.env`):- **Framework**: Express.js - -- **Database**: PostgreSQL 14+ with Prisma ORM - -```env- **Validation**: Zod (runtime validation + types) - -VITE_API_URL=http://localhost:3000/api- **Testing**: Jest + Supertest (10 tests) - -``` - -### Frontend - -### 3. Setup Database- **Framework**: React 19 with TypeScript - -- **Build Tool**: Vite - -```bash- **Styling**: TailwindCSS - -# Generate Prisma Client- **State Management**: React Query (server state) - -pnpm --filter backend prisma:generate- **Forms**: React Hook Form + Zod resolver - -- **Notifications**: React Hot Toast - -# Run migrations (creates tables)- **Testing**: Vitest + React Testing Library (5 tests) - -pnpm --filter backend prisma:migrate dev - -### Shared - -# Seed database with sample data- **Monorepo**: pnpm workspaces - -pnpm --filter backend prisma:seed- **Types**: Shared Zod schemas in `@shared/types` - -```- **Code Quality**: ESLint + Prettier - - - -### 4. Start Development Servers--- - - - -```bash## οΏ½ Quick Start (Manual Setup) - -# Terminal 1: Backend (http://localhost:3000) - -pnpm dev:backend### Prerequisites - -- **Node.js** >= 18.0.0 - -# Terminal 2: Frontend (http://localhost:5173)- **pnpm** >= 8.0.0 - -pnpm dev:frontend- **PostgreSQL** >= 14 (running locally) - -``` - -### 1. Clone & Install - ---- - -```bash - -## ✨ Featuresgit clone - -cd RedditTest - -### Core Functionalitypnpm install - -- βœ… **Full CRUD Operations** - Create, Read, Update, Delete orders``` - -- βœ… **Server-side Pagination** - Efficient loading with configurable page size (default: 10, max: 100) - -- βœ… **Status Filtering** - Filter by PENDING, COMPLETED, or CANCELLED### 2. Setup Environment Variables - -- βœ… **Real-time Validation** - Zod schemas validate on client and server - -- βœ… **End-to-end Type Safety** - Shared types between frontend/backend**Backend** (`apps/backend/.env`): - - - -### User Experience```bash - -- βœ… **Toast Notifications** - Professional feedback for all actions# Copy example file - -- βœ… **Status Badges** - Color-coded (🟑 Pending, 🟒 Completed, πŸ”΄ Cancelled)cp apps/backend/.env.example apps/backend/.env - -- βœ… **Delete Confirmation** - Modal prevents accidental deletions``` - -- βœ… **Loading States** - Clear feedback during async operations - -- βœ… **Error Handling** - User-friendly error messagesEdit with your PostgreSQL credentials: - -- βœ… **Responsive Design** - Mobile-friendly with TailwindCSS - -```env - -### Developer ExperienceDATABASE_URL="postgresql://postgres:postgres@localhost:5432/orders_db?schema=public" - -- βœ… **Docker Support** - One command to start everythingPORT=3000 - -- βœ… **Monorepo Architecture** - pnpm workspaces with shared typesNODE_ENV=development - -- βœ… **React Query** - Automatic caching, optimistic updates, invalidation``` - -- βœ… **Type-First Development** - Zod schemas generate TypeScript types - -- βœ… **Comprehensive Testing** - 15 tests (10 backend + 5 frontend)**Frontend** (`apps/frontend/.env`): - -- βœ… **Hot Reload** - Instant feedback in dev mode - -- βœ… **Prisma Studio** - Visual database editor```bash - -# Copy example file - ----cp apps/frontend/.env.example apps/frontend/.env - -``` - -## πŸ› οΈ Tech Stack - -Default values should work: - -### Backend - -| Technology | Version | Purpose |```env - -|------------|---------|---------|VITE_API_URL=http://localhost:3000/api - -| **Node.js** | 22 (Alpine in Docker) | Runtime |``` - -| **TypeScript** | 5.9.3 | Type safety | - -| **Express** | 4.21.2 | Web framework |### 3. Setup Database - -| **PostgreSQL** | 14 (Alpine in Docker) | Database | - -| **Prisma** | 6.3.0 | ORM + migrations |```bash - -| **Zod** | 3.24.1 | Runtime validation |# Generate Prisma client - -| **Jest** | 29.7.0 | Testing (10 tests) |pnpm --filter backend prisma:generate - - - -### Frontend# Run migrations (creates tables) - -| Technology | Version | Purpose |pnpm --filter backend prisma:migrate dev - -|------------|---------|---------| - -| **React** | 19.1.1 | UI framework |# (Optional) Seed database - -| **TypeScript** | 5.9.3 | Type safety |pnpm --filter backend prisma:seed - -| **Vite** | 6.0.10 | Build tool + dev server |``` - -| **TailwindCSS** | 3.4.17 | Styling | - -| **React Query** | 5.63.1 | Server state management |### 4. Start Development Servers - -| **React Hook Form** | 7.54.2 | Form handling | - -| **React Hot Toast** | 2.6.0 | Notifications |**Terminal 1 - Backend:** - -| **Vitest** | 3.2.4 | Testing (5 tests) | - -```bash - -### Sharedpnpm dev:backend - -- **Monorepo**: pnpm workspaces``` - -- **Types**: Shared Zod schemas in `@shared/types` - -- **Validation**: Single source of truth for all data structuresπŸš€ Backend: http://localhost:3000 - - - ----**Terminal 2 - Frontend:** - - - -## πŸ”¨ Development```bash - -pnpm dev:frontend - -### Project Structure``` - - - -```🎨 Frontend: http://localhost:5173 - -RedditTest/ - -β”œβ”€β”€ apps/> **Note:** The backend automatically seeds the database with 10 sample orders on first run if the database is empty. - -β”‚ β”œβ”€β”€ backend/ # Express API - -β”‚ β”‚ β”œβ”€β”€ prisma/ # Schema, migrations, seed--- - -β”‚ β”‚ └── src/ - -β”‚ β”‚ β”œβ”€β”€ controllers/ # Request handlers## πŸ’» Development - -β”‚ β”‚ β”œβ”€β”€ middleware/ # Error handling, validation - -β”‚ β”‚ └── routes/ # API endpoints> **πŸ’‘ Tip:** If using Docker, replace `pnpm` commands with `docker-compose exec ` (e.g., `docker-compose exec backend pnpm --filter backend test`) - -β”‚ └── frontend/ # React SPA - -β”‚ └── src/### Quick Command Reference - -β”‚ β”œβ”€β”€ components/ # Reusable UI components - -β”‚ β”œβ”€β”€ hooks/ # React Query hooks```bash - -β”‚ β”œβ”€β”€ pages/ # Route pages# Development (Manual) - -β”‚ └── services/ # API clientpnpm dev:backend # Start backend (auto-seeds if empty) - -β”œβ”€β”€ packages/pnpm dev:frontend # Start frontend - -β”‚ └── shared-types/ # Zod schemas + TypeScript types - -└── docker-compose.yml # Docker orchestration# Development (Docker) - -```docker-compose up # Start all services - -docker-compose up -d # Start in background - -### Available Scriptsdocker-compose logs -f backend # View backend logs - - - -```bash# Testing (Manual) - -# Developmentpnpm --filter backend test # Run backend tests (10 tests) - -pnpm dev:backend # Start backend (http://localhost:3000)pnpm --filter frontend test --run # Run frontend tests (5 tests) - -pnpm dev:frontend # Start frontend (http://localhost:5173) - -# Testing (Docker) - -# Buildingdocker-compose exec backend pnpm --filter backend test - -pnpm build:backend # Compile TypeScript β†’ dist/docker-compose exec frontend pnpm --filter frontend test --run - -pnpm build:frontend # Build for production β†’ dist/ - -# Database (Manual) - -# Testingpnpm --filter backend prisma:studio # Open database GUI (port 5555) - -pnpm test:backend # Run Jest tests (10 tests)pnpm --filter backend prisma:generate # Regenerate Prisma client - -pnpm test:frontend # Run Vitest tests (5 tests)pnpm --filter backend prisma:migrate dev # Create new migration - -pnpm test # Run all testspnpm --filter backend prisma:seed # Manual seed - -pnpm --filter backend prisma:migrate reset # ⚠️ Reset database (deletes all data) - -# Database - -pnpm --filter backend prisma:generate # Regenerate Prisma Client# Database (Docker) - -pnpm --filter backend prisma:migrate # Create migrationdocker-compose exec backend pnpm --filter backend prisma:studio - -pnpm --filter backend prisma:seed # Seed databasedocker-compose exec backend pnpm --filter backend prisma:generate - -pnpm --filter backend prisma:studio # Open GUI (localhost:5555) - -# Build - -# Dockerpnpm --filter backend build # Build backend - -docker compose up --build # Start all servicespnpm --filter frontend build # Build frontend - -docker compose logs -f backend # View backend logs``` - -docker compose exec backend sh # Access backend shell - -```### Database Management - - - -### Environment Variables**Prisma Studio** - Visual database editor: - - - -#### Backend (`apps/backend/.env`)```bash - -```envpnpm --filter backend prisma:studio - -DATABASE_URL="postgresql://user:password@localhost:5432/orders_db?schema=public"``` - -PORT=3000 - -NODE_ENV=developmentOpens at http://localhost:5555 - -``` - -**Seeding Behavior:** - -#### Frontend (`apps/frontend/.env`)- Seed script checks if data exists before inserting - -```env- Only seeds if database is empty - -VITE_API_URL=http://localhost:3000/api- To reseed: `pnpm --filter backend prisma:migrate reset` - -``` - ---- - ---- - -## πŸ§ͺ Testing - -## πŸ§ͺ Testing - -### Run Tests - -### Run All Tests - -```bash - -```bash# Backend tests (Jest + Supertest) - -# Localpnpm --filter backend test - -pnpm test - -# Frontend tests (Vitest + React Testing Library) - -# Dockerpnpm --filter frontend test --run - -docker compose exec backend pnpm --filter backend test - -docker compose exec frontend pnpm --filter frontend test --run# All tests - -```pnpm --filter backend test && pnpm --filter frontend test --run - -``` - -### Test Coverage - -### Test Coverage - -**Backend (10 tests)** - Integration tests with real database: - -- βœ… Pagination with correct metadata**Backend (10 tests):** - -- βœ… Create order with valid/invalid data- βœ… Pagination with metadata - -- βœ… Get order by ID (success + 404)- βœ… Order creation with validation - -- βœ… Invalid UUID handling- βœ… Order retrieval by ID - -- βœ… Filter by status (PENDING, COMPLETED)- βœ… Status filtering - -- βœ… Combined filtering + pagination- βœ… Error handling (404, 400, validation) - - - -**Frontend (5 tests)** - Component and hook tests:**Frontend (5 tests):** - -- βœ… OrdersListPage renders without errors- βœ… Component rendering - -- βœ… Loading state displays correctly- βœ… Loading states - -- βœ… useOrders hook fetches data- βœ… React Query hook initialization - -- βœ… Pagination works correctly - -- βœ… Error handling### API Testing with Postman - - - -### Test Files1. Import `postman/Order_Management_API.postman_collection.json` - -- `apps/backend/src/__tests__/orders.test.ts`2. Import `postman/Order_Management_Dev.postman_environment.json` - -- `apps/frontend/src/pages/__tests__/OrdersListPage.test.tsx`3. Select "Order Management - Development" environment - -- `apps/frontend/src/hooks/__tests__/useOrders.test.ts`4. Run collection to test all endpoints - - - ------- - - - -## πŸ“š API Documentation## πŸ“– API Documentation - - - -### Base URL### Endpoints - -- **Development**: `http://localhost:3000/api` - -- **Docker**: `http://localhost:3000/api`| Method | Endpoint | Description | Query Parameters | - -| -------- | ----------------- | ------------------------- | ----------------------------- | - -### Endpoints| `GET` | `/health` | Health check | - | - -| `GET` | `/api/orders` | Get paginated orders | `page`, `page_size`, `status` | - -#### `GET /health`| `GET` | `/api/orders/:id` | Get order by ID | - | - -Health check endpoint.| `POST` | `/api/orders` | Create new order | - | - -| `PUT` | `/api/orders/:id` | Update order | - | - -**Response** (200):| `DELETE` | `/api/orders/:id` | Delete order | - | - -```json - -{### Query Parameters - - "status": "ok", - - "message": "Order Management API is running"- **page** - Page number (default: 1) - -}- **page_size** - Items per page (default: 10, max: 100) - -```- **status** - Filter by status: `PENDING`, `COMPLETED`, or `CANCELLED` - - - -#### `GET /api/orders`### Example Requests - -Get paginated orders with optional filtering. - -#### Get All Orders (Paginated) - -**Query Parameters**:```bash - -- `page` (number, default: 1) - Page numberGET http://localhost:3000/api/orders?page=1&page_size=10 - -- `page_size` (number, default: 10, max: 100) - Items per page``` - -- `status` (string, optional) - Filter by status: `PENDING`, `COMPLETED`, `CANCELLED` - -#### Filter by Status - -**Response** (200):```bash - -```jsonGET http://localhost:3000/api/orders?status=PENDING - -{``` - - "success": true, - - "data": {#### Create Order - - "data": [```bash - - {POST http://localhost:3000/api/orders - - "id": "uuid",Content-Type: application/json - - "customer_name": "John Doe", - - "item": "Laptop",{ - - "quantity": 2, "customer_name": "John Doe", - - "status": "PENDING", "item": "MacBook Pro", - - "created_at": "2025-10-19T20:00:00.000Z" "quantity": 2, - - } "status": "PENDING" - - ],} - - "pagination": {``` - - "page": 1, - - "page_size": 10,#### Update Order - - "total": 50,```bash - - "total_pages": 5PUT http://localhost:3000/api/orders/{id} - - }Content-Type: application/json - - } - -}{ - -``` "status": "COMPLETED" - -} - -#### `GET /api/orders/:id```` - -Get single order by ID. - -#### Delete Order - -**Response** (200):```bash - -```jsonDELETE http://localhost:3000/api/orders/{id} - -{``` - - "success": true, - - "data": {### Response Format - - "id": "uuid", - - "customer_name": "John Doe",**Success Response:** - - "item": "Laptop",```json - - "quantity": 2,{ - - "status": "PENDING", "success": true, - - "created_at": "2025-10-19T20:00:00.000Z" "data": { ... } - - }} - -}``` - -``` - -**Error Response:** - -**Error** (404):```json - -```json{ - -{ "success": false, - - "success": false, "error": { - - "error": { "message": "Error message", - - "message": "Order not found", "code": "ERROR_CODE", - - "code": "ORDER_NOT_FOUND" "details": { ... } - - } } - -}} - -`````` - - - -#### `POST /api/orders`--- - -Create a new order. - -## πŸ—οΈ Architecture - -**Request Body**: - -```json### Monorepo Structure - -{ - - "customer_name": "John Doe",``` - - "item": "Laptop",RedditTest/ - - "quantity": 2,β”œβ”€β”€ apps/ - - "status": "PENDING"β”‚ β”œβ”€β”€ backend/ # Express.js API + Prisma ORM - -}β”‚ β”‚ β”œβ”€β”€ src/ - -```β”‚ β”‚ β”‚ β”œβ”€β”€ controllers/ # HTTP request handlers - -β”‚ β”‚ β”‚ β”œβ”€β”€ middleware/ # Error handling, validation - -**Response** (201):β”‚ β”‚ β”‚ β”œβ”€β”€ routes/ # API route definitions - -```jsonβ”‚ β”‚ β”‚ └── __tests__/ # Integration tests - -{β”‚ β”‚ └── prisma/ - - "success": true,β”‚ β”‚ β”œβ”€β”€ schema.prisma # Database schema - - "data": {β”‚ β”‚ └── seed.ts # Database seeding - - "id": "uuid",β”‚ └── frontend/ # React 19 + Vite SPA - - "customer_name": "John Doe",β”‚ └── src/ - - "item": "Laptop",β”‚ β”œβ”€β”€ components/ # Reusable UI components - - "quantity": 2,β”‚ β”œβ”€β”€ pages/ # Route pages - - "status": "PENDING",β”‚ β”œβ”€β”€ hooks/ # React Query hooks - - "created_at": "2025-10-19T20:00:00.000Z"β”‚ └── services/ # API client - - }β”œβ”€β”€ packages/ - -}β”‚ └── shared-types/ # Shared Zod schemas & TypeScript types - -```└── postman/ # API testing collection - -``` - -**Error** (400): - -```json### Type-First Development Flow - -{ - - "success": false,1. **Define Zod schema** in `packages/shared-types/src/index.ts`: - - "error": { ```typescript - - "message": "Validation error", export const CreateOrderSchema = z.object({ - - "code": "VALIDATION_ERROR", customer_name: z.string().min(1).max(255), - - "details": [ quantity: z.number().int().positive(), - - { status: OrderStatusSchema - - "path": ["customer_name"], }); - - "message": "Customer name is required" ``` - - } - - ]2. **Infer TypeScript type**: - - } ```typescript - -} export type CreateOrderDTO = z.infer; - -``` ``` - - - -#### `PUT /api/orders/:id`3. **Backend validates** with same schema: - -Update an existing order. ```typescript - - const validated = CreateOrderSchema.parse(req.body); - -**Request Body** (all fields optional): ``` - -```json - -{4. **Frontend uses** without duplication: - - "customer_name": "Jane Doe", ```typescript - - "item": "Updated Item", import { CreateOrderDTO } from '@shared/types'; - - "quantity": 5, const orderData: CreateOrderDTO = { ... }; - - "status": "COMPLETED" ``` - -} - -```**Result:** Change validation once, get runtime safety + TypeScript types everywhere. No drift between frontend and backend. - - - -**Response** (200): Same structure as GET### Key Architectural Decisions - - - -#### `DELETE /api/orders/:id`#### Why Monorepo? - -Delete an order.- Shared types eliminate duplication - -- Single source of truth for validation - -**Response** (200):- Changes instantly available across apps - +### Response Format +All successful responses include a `success: true` flag and a `data` object. Errors include `success: false` and an `error` object with a `message` and `code`. +```markdown +# Example Success Response ```json - -{#### Why Zod? - - "success": true,- Runtime validation catches errors at API boundaries - - "data": {- TypeScript types auto-generated from schemas - - "id": "uuid",- Single schema for validation + types - - "customer_name": "John Doe", - - "item": "Laptop",#### Why React Query? - - "quantity": 2,- Automatic caching reduces API calls - - "status": "PENDING",- Optimistic updates for instant UI feedback - - "created_at": "2025-10-19T20:00:00.000Z"- Cache invalidation keeps data fresh - - }- Replaces Redux/Zustand for server state - -} - -```#### Why Prisma? - -- Type-safe database access prevents SQL errors - -### Postman Collection- Automatic migrations track schema changes - -- Generated client provides autocomplete - -Import the collection from `postman/Order_Management_API.postman_collection.json` for ready-to-use API tests. - -#### Why No Repository Layer? - ----- Simple domain (single entity) doesn't need abstraction - -- Prisma calls are clear and type-safe - -## πŸ—οΈ Architecture- Easy to refactor when complexity grows - - - -### Type-First Development--- - - - -All data structures originate as **Zod schemas** in `packages/shared-types/src/index.ts`:## πŸ“ Project Structure - - - -```typescript### Backend Organization - -// Define once - -export const CreateOrderSchema = z.object({``` - - customer_name: z.string().min(1).max(255),apps/backend/src/ - - item: z.string().min(1).max(255),β”œβ”€β”€ index.ts # Express app setup + middleware - - quantity: z.number().int().positive(),β”œβ”€β”€ controllers/ - - status: OrderStatusSchemaβ”‚ └── orders.controller.ts # Order CRUD logic - -});β”œβ”€β”€ middleware/ - -β”‚ β”œβ”€β”€ errorHandler.ts # Centralized error handling - -// Use everywhereβ”‚ └── validateUUID.ts # UUID validation middleware - -export type CreateOrderDTO = z.infer;β”œβ”€β”€ routes/ - -```β”‚ └── orders.routes.ts # Route definitions - -└── __tests__/ - -**Backend** validates at runtime: β”œβ”€β”€ setup.ts # Test configuration - -```typescript └── orders.test.ts # Integration tests - -const validated = CreateOrderSchema.parse(req.body); // throws ZodError if invalid``` - -``` - -### Frontend Organization - -**Frontend** gets TypeScript types: - -```typescript``` - -const orderData: CreateOrderDTO = { ... }; // Full type safetyapps/frontend/src/ - -```β”œβ”€β”€ main.tsx # App entry point - -β”œβ”€β”€ App.tsx # Router setup - -### Data Flowβ”œβ”€β”€ components/ - -β”‚ β”œβ”€β”€ ConfirmDialog.tsx # Delete confirmation modal - -```β”‚ β”œβ”€β”€ Layout.tsx # Page layout wrapper - -User Action (Frontend)β”‚ └── StatusBadge.tsx # Status display component - - β†“β”œβ”€β”€ pages/ - -React Query Hook (useOrders)β”‚ β”œβ”€β”€ OrdersListPage.tsx # List view with pagination - - ↓│ β”œβ”€β”€ OrderDetailsPage.tsx # Single order view - -API Service (ordersApi.createOrder)β”‚ β”œβ”€β”€ CreateOrderPage.tsx # Create form - - ↓│ └── EditOrderPage.tsx # Edit form - -Express Route (/api/orders)β”œβ”€β”€ hooks/ - - ↓│ └── useOrders.ts # React Query hooks - -Zod Validation (CreateOrderSchema.parse)β”œβ”€β”€ services/ - - ↓│ └── orders.service.ts # API client - -Controller (createOrder)└── lib/ - - ↓ └── api.ts # Axios configuration - -Prisma Client (prisma.order.create)``` - - ↓ - -PostgreSQL Database### Shared Types - - ↓ - -Response with ApiResponse```typescript - - ↓// packages/shared-types/src/index.ts - -React Query Cache Update - - ↓// Schemas (validation + types) - -UI Update (automatic re-render)export const OrderStatusSchema = z.enum(['PENDING', 'COMPLETED', 'CANCELLED']); - -```export const CreateOrderSchema = z.object({ ... }); - -export const UpdateOrderSchema = z.object({ ... }); - -### Error Handling - -// Types (inferred from schemas) - -Centralized error middleware converts all errors to consistent `ApiError` format:export type OrderStatus = z.infer; - -export type CreateOrderDTO = z.infer; - -```typescriptexport type Order = { ... }; - -{export type ApiResponse = { ... }; - - success: false,``` - - error: { - - message: "Error description",--- - - code: "ERROR_CODE", - - details?: any // For validation errors## 🎯 Requirements Checklist - - } - -}### βœ… Core Requirements (100%) - -``` - -**Backend:** - ----- βœ… All CRUD endpoints (POST, GET, PUT, DELETE) - -- βœ… Order structure with UUID, customer_name, item, quantity, status, created_at - -## πŸ“¦ Docker Details- βœ… Pagination support with page and page_size - -- βœ… Node.js + TypeScript + Express - -### Services- βœ… PostgreSQL database with Prisma ORM - - - -| Service | Port | Description |**Frontend:** - -|---------|------|-------------|- βœ… Order list view with pagination - -| **postgres** | 5432 | PostgreSQL 14 Alpine with persistent volume |- βœ… Order details view - -| **backend** | 3000 | Express API with auto-migration and seeding |- βœ… Create/Edit order forms - -| **frontend** | 5173 | Vite dev server with HMR |- βœ… Delete functionality - -- βœ… Loading and error states - -### Volumes- βœ… TypeScript + React 19 - - - -- `postgres_data` - Persists database data across container restarts### ⭐ Bonus Features (100%) - -- Source code mounted for hot reload (backend/src, frontend/src, shared-types/src) - -- βœ… Status filtering (backend + frontend) - -### Networks- βœ… Comprehensive testing (15 tests) - -- βœ… Shared types monorepo setup - -- `orders_network` - Bridge network for service communication- βœ… Comprehensive documentation - -- βœ… ESLint + Prettier configuration - -### Auto-Startup Process- βœ… Professional error handling - -- βœ… Toast notifications - -```- βœ… Postman collection - -1. PostgreSQL starts and runs health check- βœ… **Docker setup for easy local development** 🐳 - -2. Backend waits for healthy PostgreSQL - -3. Backend runs: prisma migrate deploy--- - -4. Backend runs: prisma generate - -5. Backend runs: seed script (only if DB empty)## 🚨 Important Notes - -6. Backend starts Express server - -7. Frontend starts Vite dev server### Docker vs Manual Setup - -```- **Docker**: Zero configuration, all dependencies included, consistent environment - -- **Manual**: More control, faster iterative development, requires PostgreSQL installation - ---- - -### Prisma Client Generation - -## 🀝 ContributingAfter modifying `prisma/schema.prisma`, always regenerate the client: - - - -1. Fork the repository```bash - -2. Create a feature branch (`git checkout -b feat/amazing-feature`)# Manual - -3. Commit changes (`git commit -m 'feat: Add amazing feature'`)pnpm --filter backend prisma:generate - -4. Push to branch (`git push origin feat/amazing-feature`) - -5. Open a Pull Request# Docker - -docker-compose exec backend pnpm --filter backend prisma:generate - ----``` - - - -## πŸ“„ License**Symptom of missing generation:** `Property 'order' does not exist on type 'PrismaClient'` - - - -This project is licensed under the MIT License.### Workspace Linking - -Shared types use `workspace:*` protocol. Changes are immediately available without reinstalling. - ---- - -If you see stale types: - -## πŸ‘€ Author```bash - -pnpm install # Rebuild workspace links - -**Daniel Khadour**``` - - - -- GitHub: [@LeSoviet](https://github.com/LeSoviet)### Auto-Seeding - -The backend checks if the database is empty and automatically seeds on first run. Manual seeding only needed after database reset. - ---- - -### Docker Hot Reload - -## πŸ™ AcknowledgmentsChanges to source files automatically trigger reloads: - -- **Backend**: `tsx` watch mode restarts on changes - -Built as a technical challenge to demonstrate:- **Frontend**: Vite HMR updates instantly - -- Full-stack TypeScript development- **Shared Types**: Changes reflect immediately in both apps - -- Modern React patterns (19+) - -- Type-safe API design### Vite Configuration - -- Docker containerizationThis project uses `rolldown-vite@7.1.14` (specified in root `package.json` overrides). If you encounter Vite type errors, ensure `apps/frontend/src/vite-env.d.ts` exists. - -- Monorepo architecture - -- Test-driven development--- - - - ----## πŸ“š Additional Resources - - - -**⭐ If you found this project helpful, please consider giving it a star!**- **Prisma Studio**: Visual database editor at http://localhost:5555 - -- **Postman Collection**: Pre-configured API tests in `/postman` directory -- **Type Definitions**: All schemas in `packages/shared-types/src/index.ts` - ---- - -## 🀝 Contributing - -This is a technical challenge project. For questions or issues, please open a GitHub issue. +{ "success": true, "data": { "id": "uuid", ... } } \ No newline at end of file