updated frontend
@@ -62,8 +62,15 @@ Cookie is HTTP-only and set with `sameSite=lax`.
|
||||
- `GET /api/health`
|
||||
- `GET /api/shop/categories`
|
||||
- `GET /api/shop/products`
|
||||
- `GET /api/shop/products/:productId`
|
||||
- `POST /api/shop/products` (`multipart/form-data` is supported, field name: `image`)
|
||||
- `POST /api/shop/products/:productId/image` (`multipart/form-data`, field name: `image`)
|
||||
- `POST /api/shop/orders`
|
||||
|
||||
Uploaded files are stored in `images/uploads` and are served at `/images/uploads/<filename>`.
|
||||
|
||||
Product responses include `image_url` with an absolute URL when an image exists.
|
||||
|
||||
Order payload:
|
||||
|
||||
```json
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
# Student Production Setup Guide
|
||||
|
||||
This guide explains how to set up and run the webstore backend in production mode.
|
||||
|
||||
## What You'll Receive
|
||||
|
||||
Your instructor will provide you with:
|
||||
|
||||
1. **webstore-production-images.tar** - Docker images archive (API + database)
|
||||
2. **production.compose.yml** - Docker Compose configuration
|
||||
3. **.production.env** - Environment variables template
|
||||
4. **run-student-production.bat** - Easy start script
|
||||
5. **Product images** - 17 placeholder product images
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Docker Desktop** installed ([Download here](https://www.docker.com/products/docker-desktop))
|
||||
- Windows 10 or later (for Docker)
|
||||
- Minimum 2GB free disk space
|
||||
- ~5 minutes for initial setup
|
||||
|
||||
## Step-by-Step Setup
|
||||
|
||||
### Step 1: Extract Docker Images
|
||||
|
||||
```
|
||||
Right-click on webstore-production-images.tar
|
||||
→ Select "Extract All"
|
||||
→ Choose destination folder
|
||||
```
|
||||
|
||||
Or use PowerShell/terminal:
|
||||
```powershell
|
||||
docker load -i webstore-production-images.tar
|
||||
```
|
||||
|
||||
### Step 2: Configure Environment Variables
|
||||
|
||||
1. Open `.production.env` in a text editor
|
||||
2. Update these values (if different from defaults):
|
||||
|
||||
```env
|
||||
# Database Configuration
|
||||
POSTGRES_DB=webstore_db
|
||||
POSTGRES_USER=webstore_user
|
||||
POSTGRES_PASSWORD=webstore_password
|
||||
DB_PORT=5432
|
||||
|
||||
# API Configuration
|
||||
PORT=3000
|
||||
API_PORT=3000
|
||||
|
||||
# JWT Configuration
|
||||
JWT_SECRET=your-secret-key-change-for-production
|
||||
JWT_EXPIRES_IN=7d
|
||||
|
||||
# Security
|
||||
COOKIE_NAME=webstore_token
|
||||
COOKIE_SECURE=false # Set to true if using HTTPS
|
||||
|
||||
# Database URL (usually don't change this)
|
||||
DATABASE_URL=postgresql://webstore_user:webstore_password@db:5432/webstore_db?schema=public
|
||||
```
|
||||
|
||||
### Step 3: Start the Application
|
||||
|
||||
**Option A: Using the provided script (recommended)**
|
||||
```
|
||||
Double-click: run-student-production.bat
|
||||
```
|
||||
|
||||
**Option B: Using Docker Compose directly**
|
||||
```powershell
|
||||
docker-compose -f production.compose.yml up
|
||||
```
|
||||
|
||||
### Step 4: Verify Setup
|
||||
|
||||
Wait for logs to show:
|
||||
```
|
||||
webstore_api_prod | npm notice
|
||||
webstore_api_prod | > webstore-backend@1.0.0 start
|
||||
webstore_api_prod | > node src/Api/server.js
|
||||
webstore_api_prod | Server running on port 3000
|
||||
```
|
||||
|
||||
### Step 5: Test the API
|
||||
|
||||
Open in your browser:
|
||||
```
|
||||
http://localhost:3000/api/health
|
||||
```
|
||||
|
||||
Expected response:
|
||||
```json
|
||||
{
|
||||
"status": "ok",
|
||||
"message": "CQRS backend running"
|
||||
}
|
||||
```
|
||||
|
||||
## Accessing the API
|
||||
|
||||
The API is available at: `http://localhost:3000`
|
||||
|
||||
### Key Endpoints
|
||||
|
||||
- `GET /api/health` - Health check
|
||||
- `GET /api/shop/categories` - List all product categories
|
||||
- `GET /api/shop/products` - List all products
|
||||
- `GET /api/shop/products/:id` - Get product by ID
|
||||
- `POST /api/shop/products` - Create product (with image upload)
|
||||
- `POST /api/shop/products/:id/image` - Update product image
|
||||
|
||||
### Built-in Data
|
||||
|
||||
The database automatically seeds with:
|
||||
|
||||
**Test Users:**
|
||||
```
|
||||
Email: admin@test.com
|
||||
Password: admin123
|
||||
|
||||
Email: john@test.com
|
||||
Password: password123
|
||||
|
||||
Email: jane@test.com
|
||||
Password: password123
|
||||
```
|
||||
|
||||
**Products:**
|
||||
- 16 sample products across 5 categories
|
||||
- Each product has a placeholder image
|
||||
- Sample prices range from 4,990 to 29,990 HUF
|
||||
|
||||
**Categories:**
|
||||
- Shoes (4 products)
|
||||
- Bags (4 products)
|
||||
- Accessories (4 products)
|
||||
- Clothing (3 products)
|
||||
- Electronics (2 products)
|
||||
|
||||
## Stopping the Application
|
||||
|
||||
### Using Docker Compose:
|
||||
```powershell
|
||||
docker-compose -f production.compose.yml down
|
||||
```
|
||||
|
||||
### Or simply close the terminal window
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Port Already in Use
|
||||
If you get "port 3000 already in use":
|
||||
```powershell
|
||||
# Change port in .production.env
|
||||
API_PORT=3001
|
||||
```
|
||||
|
||||
### Database Connection Failed
|
||||
- Verify database container is running: `docker ps`
|
||||
- Check DATABASE_URL in `.production.env`
|
||||
- Ensure PostgreSQL image is loaded: `docker images | grep postgres`
|
||||
|
||||
### Docker Not Running
|
||||
- Start Docker Desktop application
|
||||
- Wait for Docker daemon to be ready (check system tray)
|
||||
|
||||
### Out of Disk Space
|
||||
```powershell
|
||||
# Clean up Docker
|
||||
docker system prune -a
|
||||
```
|
||||
|
||||
## Image Upload
|
||||
|
||||
Once running, you can upload product images:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:3000/api/shop/products/1/image \
|
||||
-F "image=@path/to/image.jpg"
|
||||
```
|
||||
|
||||
Images are stored in the `images/uploads/` directory and served automatically.
|
||||
|
||||
## Database Persistence
|
||||
|
||||
Product data is stored in PostgreSQL. Data persists between application restarts unless you:
|
||||
```powershell
|
||||
docker-compose -f production.compose.yml down -v
|
||||
```
|
||||
|
||||
The `-v` flag removes data volumes (use carefully!).
|
||||
|
||||
## Connecting Frontend
|
||||
|
||||
Configure your frontend to use:
|
||||
```
|
||||
API Base URL: http://localhost:3000/api
|
||||
```
|
||||
|
||||
Example (fetch):
|
||||
```javascript
|
||||
const response = await fetch('http://localhost:3000/api/shop/products');
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
```
|
||||
|
||||
## Questions or Issues?
|
||||
|
||||
Consult your instructor or check the main README.md for more information about the backend architecture and CQRS pattern.
|
||||
|
||||
Happy coding! 🚀
|
||||
@@ -0,0 +1,104 @@
|
||||
# Product Images Directory
|
||||
|
||||
This directory contains product images for the webstore backend.
|
||||
|
||||
## Image Requirements
|
||||
|
||||
The following 17 placeholder images are required for the seed data to display properly:
|
||||
|
||||
**Shoes (4 images)**
|
||||
- `street-runner.jpg` - 18,990 HUF
|
||||
- `trail-edge.jpg` - 24,990 HUF
|
||||
- `urban-sprint.jpg` - 22,990 HUF
|
||||
- `classic-comfort.jpg` - 16,990 HUF
|
||||
|
||||
**Bags (4 images)**
|
||||
- `urban-tote.jpg` - 14,990 HUF
|
||||
- `backpack-pro.jpg` - 19,990 HUF
|
||||
- `crossbody.jpg` - 9,990 HUF
|
||||
- `duffle.jpg` - 24,990 HUF
|
||||
|
||||
**Accessories (4 images)**
|
||||
- `classic-cap.jpg` - 6,990 HUF
|
||||
- `silk-scarf.jpg` - 12,990 HUF
|
||||
- `leather-belt.jpg` - 8,990 HUF
|
||||
- `watch-straps.jpg` - 4,990 HUF
|
||||
|
||||
**Clothing (3 images)**
|
||||
- `cotton-tshirt.jpg` - 7,990 HUF
|
||||
- `denim-jacket.jpg` - 29,990 HUF
|
||||
- `yoga-leggings.jpg` - 11,990 HUF
|
||||
|
||||
**Electronics (2 images)**
|
||||
- `earbuds.jpg` - 17,990 HUF
|
||||
- `usb-hub.jpg` - 5,990 HUF
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
images/
|
||||
├── [17 product placeholder images]
|
||||
├── uploads/ (auto-created by multer)
|
||||
│ └── [user-uploaded images]
|
||||
├── production.compose.yml (production docker-compose)
|
||||
├── .production.env (production environment variables)
|
||||
└── run-student-production.bat (production start script)
|
||||
```
|
||||
|
||||
## Image Specifications
|
||||
|
||||
**Recommended specifications for product images:**
|
||||
- Format: JPEG or PNG
|
||||
- Dimensions: 400-600px width, 300-600px height
|
||||
- File size: < 500KB per image
|
||||
- Color space: RGB or RGBA
|
||||
|
||||
## Uploads Directory
|
||||
|
||||
The `uploads/` directory is automatically created by the multer middleware when the backend starts. This directory stores images uploaded by users through the frontend.
|
||||
|
||||
**Important notes:**
|
||||
- Images are stored with timestamps: `1717123456789-product-name.jpg`
|
||||
- Served via: `GET /images/uploads/{filename}`
|
||||
- Max file size: 5MB per upload
|
||||
- Only image MIME types allowed
|
||||
|
||||
## Production Build
|
||||
|
||||
When building for production with `build-production-images.bat`:
|
||||
1. ✓ Placeholder images are automatically generated (if ImageMagick or PowerShell available)
|
||||
2. ✓ Seeding runs automatically when containers start
|
||||
3. ✓ Upload directory is created on first run
|
||||
|
||||
## Database Seeding
|
||||
|
||||
The database automatically seeds with:
|
||||
- **5 categories**: Shoes, Bags, Accessories, Clothing, Electronics
|
||||
- **16 products**: 2-4 per category with placeholder images
|
||||
- **3 test users**: admin@test.com, john@test.com, jane@test.com
|
||||
|
||||
## Customization
|
||||
|
||||
To use custom product images:
|
||||
|
||||
1. **Development**: Replace placeholder images in this directory
|
||||
2. **Production**: Include custom images in the `images/` directory before building
|
||||
3. **After deployment**: Use the API to upload images via `POST /api/shop/products/{id}/image`
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Images not displaying in frontend
|
||||
- Ensure images are placed in the correct directory
|
||||
- Check file names match exactly (case-sensitive on Linux/Mac)
|
||||
- Verify `express.static` is configured in `src/Api/app.js`
|
||||
- Check console for 404 errors
|
||||
|
||||
### Upload fails
|
||||
- Check file is an image (JPEG, PNG, WebP, GIF, etc.)
|
||||
- Verify file size < 5MB
|
||||
- Ensure `uploads/` directory exists and is writable
|
||||
|
||||
### Seeding without images
|
||||
- Seed will complete successfully even without images
|
||||
- Products will have `null` imageUrl values
|
||||
- Frontend can display placeholder or error images
|
||||
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
@@ -4,7 +4,7 @@ setlocal EnableExtensions EnableDelayedExpansion
|
||||
set "ROOT_DIR=%~dp0"
|
||||
set "ENV_FILE=%ROOT_DIR%\.production.env"
|
||||
set "COMPOSE_FILE=%ROOT_DIR%\production.compose.yml"
|
||||
set "ARCHIVE_FILE=%ROOT_DIR%\images\webstore-production-images.tar"
|
||||
set "ARCHIVE_FILE=%ROOT_DIR%\webstore-production-images.tar"
|
||||
|
||||
set "API_IMAGE=webstore-api:prod"
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |
|
After Width: | Height: | Size: 332 B |