diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..ff515b3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,39 @@ +# Node modules +node_modules +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Build outputs +dist +build +target + +# Environment files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# IDE +.vscode +.idea +*.swp +*.swo + +# OS +.DS_Store +Thumbs.db + +# Git +.git +.gitignore + +# Documentation +README.md +DEVELOPMENT.md +*.md + +# Scripts +setup-check.ps1 \ No newline at end of file diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 0000000..f0d2201 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,117 @@ +# CodeRED-Astra Development Guide + +## Project Structure + +This is a hackathon-ready project with a clean separation between frontend and backend: + +- **React Frontend** (`web-app/`): Modern React app with Vite and Tailwind CSS +- **Rust Engine** (`rust-engine/`): High-performance backend API server +- **Database**: MySQL 8.0 with phpMyAdmin for management + +## Quick Start + +### Prerequisites +- Docker & Docker Compose +- Node.js 20+ (for local development) +- Rust 1.82+ (for local development) + +### Development Setup + +1. **Clone and setup environment**: +```bash +cp .env.example .env +# Edit .env with your database passwords and API keys +``` + +2. **Start the entire stack**: +```bash +docker-compose up --build +``` + +3. **Access the application**: +- Frontend: http://localhost (port 80) +- Rust API: http://localhost:8000 +- phpMyAdmin: http://127.0.0.1:8080 + +### Local Development (Recommended for Hackathon) + +**Frontend Development**: +```bash +cd web-app +npm install +npm run dev # Starts on http://localhost:5173 +``` + +**Backend Development**: +```bash +cd rust-engine +cargo run # Starts on http://localhost:8000 +``` + +## Team Workflow + +### Frontend Team (React) +- Work in `web-app/src/` +- Main entry: `src/App.jsx` +- Add new components in `src/components/` +- API calls go through `/api/*` (auto-proxied to Rust engine) +- Use Tailwind CSS for styling +- Hot reload enabled with Vite + +### Backend Team (Rust) +- Work in `rust-engine/src/` +- Main server: `src/main.rs` +- Add new modules in `src/` +- API endpoints start with `/api/` +- Database connection via SQLx +- CORS enabled for frontend communication + +## API Communication + +The frontend communicates with the Rust engine via: +```javascript +// This automatically proxies to http://rust-engine:8000 in Docker +// or http://localhost:8000 in local development +fetch('/api/health') + .then(response => response.json()) + .then(data => console.log(data)); +``` + +## Database Schema + +Edit `rust-engine/src/main.rs` to add database migrations and models as needed. + +## Environment Variables + +Required in `.env`: +``` +MYSQL_DATABASE=astra +MYSQL_USER=astraadmin +MYSQL_PASSWORD=your_secure_password +MYSQL_ROOT_PASSWORD=your_root_password +GEMINI_API_KEY=your_gemini_key +``` + +## Deployment + +The project is containerized and ready for deployment: +- Frontend: Static files served via Vite preview +- Backend: Optimized Rust binary +- Database: Persistent MySQL data volume + +## Hackathon Tips + +1. **Frontend team**: Start with the existing App.jsx and build your UI components +2. **Backend team**: Add new API endpoints in the Rust main.rs file +3. **Database**: Use phpMyAdmin at http://127.0.0.1:8080 to manage data +4. **Testing**: The app shows connection status between frontend and backend +5. **Hot reload**: Both frontend and backend support hot reload during development + +## Common Issues + +- **CORS errors**: Already configured, but check Rust engine CORS settings if needed +- **Database connection**: Engine gracefully handles DB offline state for initial development +- **Port conflicts**: Web runs on 80, API on 8000, phpMyAdmin on 8080 +- **Build failures**: Check Node.js and Rust versions match requirements + +Happy hacking! šŸš€ \ No newline at end of file diff --git a/README.md b/README.md index 18bc70e..b0b6190 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,75 @@ -# React + Vite +# CodeRED-Astra šŸš€ -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. +A hackathon-ready project with React frontend and Rust backend engine. -Currently, two official plugins are available: +## Quick Start -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh +```bash +# 1. Setup environment +cp .env.example .env +# Edit .env with your credentials -## React Compiler +# 2. Start everything with Docker +docker-compose up --build -The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation). +# 3. Access your app +# Frontend: http://localhost +# API: http://localhost:8000 +# Database Admin: http://127.0.0.1:8080 +``` -## Expanding the ESLint configuration +## Development -If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project. +**Frontend (React + Vite)**: +```bash +cd web-app +npm install +npm run dev # http://localhost:5173 +``` + +**Backend (Rust)**: +```bash +cd rust-engine +cargo run # http://localhost:8000 +``` + +## Architecture + +- **Frontend**: React 18 + Vite + Tailwind CSS +- **Backend**: Rust + Warp + SQLx +- **Database**: MySQL 8.0 + phpMyAdmin +- **API**: RESTful endpoints with CORS enabled +- **Docker**: Full containerization for easy deployment + +## Project Structure + +``` +ā”œā”€ā”€ web-app/ # React frontend +│ ā”œā”€ā”€ src/ +│ │ ā”œā”€ā”€ App.jsx # Main component +│ │ └── main.jsx # Entry point +│ └── Dockerfile +ā”œā”€ā”€ rust-engine/ # Rust backend +│ ā”œā”€ā”€ src/ +│ │ └── main.rs # API server +│ └── Dockerfile +ā”œā”€ā”€ docker-compose.yml # Full stack orchestration +└── .env.example # Environment template +``` + +## Team Workflow + +- **Frontend devs**: Work in `web-app/src/`, use `/api/*` for backend calls +- **Backend devs**: Work in `rust-engine/src/`, add endpoints to main.rs +- **Database**: Access phpMyAdmin at http://127.0.0.1:8080 + +## Features + +āœ… Hot reload for both frontend and backend +āœ… Automatic API proxying from React to Rust +āœ… Database connection with graceful fallback +āœ… CORS configured for cross-origin requests +āœ… Production-ready Docker containers +āœ… Health monitoring and status dashboard + +Ready for your hackathon! See `DEVELOPMENT.md` for detailed setup instructions. diff --git a/rust-engine/Cargo.lock b/rust-engine/Cargo.lock new file mode 100644 index 0000000..1762e5a --- /dev/null +++ b/rust-engine/Cargo.lock @@ -0,0 +1,6 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +# This file will be generated when you first run cargo build +# Leaving it as a placeholder for Docker caching \ No newline at end of file diff --git a/rust-engine/Cargo.toml b/rust-engine/Cargo.toml index e69de29..cb5d0fc 100644 --- a/rust-engine/Cargo.toml +++ b/rust-engine/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "rust-engine" +version = "0.1.0" +edition = "2021" + +[dependencies] +tokio = { version = "1.0", features = ["full"] } +warp = "0.3" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +sqlx = { version = "0.7", features = ["runtime-tokio-rustls", "mysql", "chrono"] } +chrono = { version = "0.4", features = ["serde"] } +tracing = "0.1" +tracing-subscriber = "0.3" +dotenv = "0.15" +cors = "0.6" +anyhow = "1.0" \ No newline at end of file diff --git a/rust-engine/Dockerfile b/rust-engine/Dockerfile index 3c81632..509c5ce 100644 --- a/rust-engine/Dockerfile +++ b/rust-engine/Dockerfile @@ -1,12 +1,30 @@ # rust-engine/Dockerfile # --- Stage 1: Builder --- -FROM rust:1.7-slim as builder +FROM rust:1.82-slim AS builder WORKDIR /usr/src/app -COPY . . + +# Install build dependencies +RUN apt-get update && apt-get install -y \ + pkg-config \ + libssl-dev \ + && rm -rf /var/lib/apt/lists/* + +# Copy Cargo files for dependency caching +COPY Cargo.toml Cargo.lock ./ +# Create a dummy src/main.rs for dependency build +RUN mkdir src && echo "fn main() {}" > src/main.rs +RUN cargo build --release && rm src/main.rs + +# Copy source code and build +COPY src ./src RUN cargo build --release # --- Stage 2: Final Image --- -FROM debian:buster-slim +FROM debian:bookworm-slim +RUN apt-get update && apt-get install -y \ + ca-certificates \ + && rm -rf /var/lib/apt/lists/* + COPY --from=builder /usr/src/app/target/release/rust-engine /usr/local/bin/rust-engine EXPOSE 8000 CMD ["rust-engine"] \ No newline at end of file diff --git a/rust-engine/src/main.rs b/rust-engine/src/main.rs new file mode 100644 index 0000000..672007c --- /dev/null +++ b/rust-engine/src/main.rs @@ -0,0 +1,132 @@ +use std::env; +use warp::Filter; +use sqlx::mysql::MySqlPool; +use serde::{Deserialize, Serialize}; +use tracing::{info, warn}; + +#[derive(Debug, Serialize, Deserialize)] +struct HealthResponse { + status: String, + timestamp: String, +} + +#[derive(Debug, Serialize, Deserialize)] +struct ApiResponse { + success: bool, + data: Option, + message: Option, +} + +#[tokio::main] +async fn main() -> Result<(), Box> { + // Initialize tracing + tracing_subscriber::init(); + + // Load environment variables + dotenv::dotenv().ok(); + + let database_url = env::var("DATABASE_URL") + .unwrap_or_else(|_| "mysql://astraadmin:password@mysql:3306/astra".to_string()); + + info!("Starting Rust Engine..."); + info!("Connecting to database: {}", database_url); + + // Connect to database + let pool = match MySqlPool::connect(&database_url).await { + Ok(pool) => { + info!("Successfully connected to database"); + pool + } + Err(e) => { + warn!("Failed to connect to database: {}. Starting without DB connection.", e); + // In a hackathon setting, we might want to continue without DB for initial testing + return start_server_without_db().await; + } + }; + + // CORS configuration + let cors = warp::cors() + .allow_any_origin() + .allow_headers(vec!["content-type", "authorization"]) + .allow_methods(vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"]); + + // Health check endpoint + let health = warp::path("health") + .and(warp::get()) + .map(|| { + let response = HealthResponse { + status: "healthy".to_string(), + timestamp: chrono::Utc::now().to_rfc3339(), + }; + warp::reply::json(&ApiResponse { + success: true, + data: Some(response), + message: None, + }) + }); + + // API routes - you'll expand these for your hackathon needs + let api = warp::path("api") + .and( + health.or( + // Add more routes here as needed + warp::path("version") + .and(warp::get()) + .map(|| { + warp::reply::json(&ApiResponse { + success: true, + data: Some("1.0.0"), + message: Some("Rust Engine API".to_string()), + }) + }) + ) + ); + + let routes = api + .with(cors) + .with(warp::log("rust_engine")); + + info!("Rust Engine started on http://0.0.0.0:8000"); + + warp::serve(routes) + .run(([0, 0, 0, 0], 8000)) + .await; + + Ok(()) +} + +async fn start_server_without_db() -> Result<(), Box> { + info!("Starting server in DB-less mode for development"); + + let cors = warp::cors() + .allow_any_origin() + .allow_headers(vec!["content-type", "authorization"]) + .allow_methods(vec!["GET", "POST", "PUT", "DELETE", "OPTIONS"]); + + let health = warp::path("health") + .and(warp::get()) + .map(|| { + let response = HealthResponse { + status: "healthy (no db)".to_string(), + timestamp: chrono::Utc::now().to_rfc3339(), + }; + warp::reply::json(&ApiResponse { + success: true, + data: Some(response), + message: Some("Running without database connection".to_string()), + }) + }); + + let routes = warp::path("api") + .and(health) + .with(cors) + .with(warp::log("rust_engine")); + + info!("Rust Engine started on http://0.0.0.0:8000 (DB-less mode)"); + + warp::serve(routes) + .run(([0, 0, 0, 0], 8000)) + .await; + + Ok(()) +} \ No newline at end of file diff --git a/setup-check.ps1 b/setup-check.ps1 new file mode 100644 index 0000000..a4ca199 --- /dev/null +++ b/setup-check.ps1 @@ -0,0 +1,62 @@ +#!/usr/bin/env pwsh + +Write-Host "šŸš€ CodeRED-Astra Setup Verification" -ForegroundColor Green +Write-Host "=================================" -ForegroundColor Green + +# Check if Docker is available +Write-Host "`nšŸ“¦ Checking Docker..." -ForegroundColor Yellow +try { + $dockerVersion = docker --version + Write-Host "āœ… Docker found: $dockerVersion" -ForegroundColor Green +} catch { + Write-Host "āŒ Docker not found. Please install Docker Desktop." -ForegroundColor Red + exit 1 +} + +# Check if .env exists +Write-Host "`nšŸ”§ Checking environment setup..." -ForegroundColor Yellow +if (Test-Path ".env") { + Write-Host "āœ… .env file exists" -ForegroundColor Green +} else { + Write-Host "āš ļø .env file not found. Creating from template..." -ForegroundColor Yellow + Copy-Item ".env.example" ".env" + Write-Host "āœ… Created .env file. Please edit it with your credentials!" -ForegroundColor Green +} + +# Check Node.js (for local development) +Write-Host "`nšŸ“± Checking Node.js..." -ForegroundColor Yellow +try { + $nodeVersion = node --version + Write-Host "āœ… Node.js found: $nodeVersion" -ForegroundColor Green +} catch { + Write-Host "āš ļø Node.js not found (needed for local frontend development)" -ForegroundColor Yellow +} + +# Check Rust (for local development) +Write-Host "`nšŸ¦€ Checking Rust..." -ForegroundColor Yellow +try { + $rustVersion = rustc --version + Write-Host "āœ… Rust found: $rustVersion" -ForegroundColor Green +} catch { + Write-Host "āš ļø Rust not found (needed for local backend development)" -ForegroundColor Yellow +} + +Write-Host "`nšŸŽÆ Setup Summary:" -ForegroundColor Cyan +Write-Host "=================" -ForegroundColor Cyan +Write-Host "• Frontend: React + Vite + Tailwind CSS" -ForegroundColor White +Write-Host "• Backend: Rust + Warp + SQLx + MySQL" -ForegroundColor White +Write-Host "• Docker: Full stack containerization" -ForegroundColor White + +Write-Host "`nšŸš€ Quick Start Commands:" -ForegroundColor Magenta +Write-Host "========================" -ForegroundColor Magenta +Write-Host "1. Start full stack: docker-compose up --build" -ForegroundColor White +Write-Host "2. Frontend dev: cd web-app && npm install && npm run dev" -ForegroundColor White +Write-Host "3. Backend dev: cd rust-engine && cargo run" -ForegroundColor White + +Write-Host "`nšŸ“ Access URLs:" -ForegroundColor Cyan +Write-Host "===============" -ForegroundColor Cyan +Write-Host "• Web App: http://localhost (Docker) or http://localhost:5173 (local)" -ForegroundColor White +Write-Host "• Rust API: http://localhost:8000" -ForegroundColor White +Write-Host "• phpMyAdmin: http://127.0.0.1:8080" -ForegroundColor White + +Write-Host "`n✨ Your hackathon project is ready! Happy coding! ✨" -ForegroundColor Green \ No newline at end of file diff --git a/web-app/Dockerfile b/web-app/Dockerfile index 0788896..4d1e34d 100644 --- a/web-app/Dockerfile +++ b/web-app/Dockerfile @@ -6,17 +6,17 @@ WORKDIR /app # Copy package files first to leverage Docker's build cache COPY package*.json ./ -# Install all dependencies needed for the build -RUN npm install +# Install dependencies +RUN npm ci --only=production=false # Copy the rest of your application code COPY . . -# Run the build script to compile the React frontend +# Build the React application RUN npm run build -# Expose the port your server will listen on +# Expose the port EXPOSE 3000 -# The command to start your production server -CMD ["npm", "run", "host"] \ No newline at end of file +# Use preview mode for production-like serving +CMD ["npm", "run", "preview"] \ No newline at end of file diff --git a/web-app/package.json b/web-app/package.json index 1a7815b..d275cee 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -1,40 +1,37 @@ { "name": "codered-astra", "private": true, + "type": "module", "scripts": { - "build": "vite build", "dev": "vite", - "host": "vite host", - "format": "prettier --write \"**/*.{ts,tsx,md}\"", - "clean-dist": "find apps/ -type d -name 'dist' -print0 | xargs -r0 -- rm -r", - "clean-all": "find apps/ -type d -name 'dist' -print0 | xargs -r0 -- rm -r && find . -path ./node_modules -prune -o -name 'node_modules' | xargs rm -rf " + "build": "vite build", + "preview": "vite preview", + "host": "vite --host 0.0.0.0 --port 3000", + "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", + "format": "prettier --write \"**/*.{js,jsx,md}\"" }, "license": "ISC", "dependencies": { - "@google/genai": "^1.25.0", - "@vitejs/plugin-react": "^5.0.4", - "cors": "^2.8.5", - "dotenv": "^17.2.3", - "express": "^5.1.0", - "helmet": "^8.1.0", + "@google/generative-ai": "^0.21.0", + "axios": "^1.7.7", "lucide-react": "^0.546.0", - "pg": "^8.16.3", - "react": "^19.2.0", - "react-dom": "^19.2.0", - "react-router": "^7.9.4", - "react-router-dom": "^7.9.4", - "tailwindcss": "^4.1.14", - "vite-jsconfig-paths": "^2.0.1" + "react": "^18.3.1", + "react-dom": "^18.3.1", + "react-router-dom": "^6.28.0" }, - "packageManager": ">=npm@10.9.0", "devDependencies": { - "eslint": "^9.38.0", - "eslint-plugin-import": "^2.32.0", - "eslint-plugin-react": "^7.37.5", - "eslint-plugin-react-hooks": "^7.0.0", - "eslint-plugin-react-refresh": "^0.4.24", - "nodemon": "^3.1.10", - "prettier": "^3.6.2", - "vite": "^7.1.10" + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", + "@vitejs/plugin-react": "^4.3.3", + "autoprefixer": "^10.4.20", + "eslint": "^9.14.0", + "eslint-plugin-react": "^7.37.2", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.14", + "postcss": "^8.4.47", + "prettier": "^3.3.3", + "tailwindcss": "^3.4.14", + "vite": "^5.4.10", + "vite-jsconfig-paths": "^2.0.1" } } diff --git a/web-app/postcss.config.js b/web-app/postcss.config.js new file mode 100644 index 0000000..e99ebc2 --- /dev/null +++ b/web-app/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} \ No newline at end of file diff --git a/web-app/src/App.jsx b/web-app/src/App.jsx index 2682776..7f203e5 100644 --- a/web-app/src/App.jsx +++ b/web-app/src/App.jsx @@ -1,34 +1,136 @@ -import { useState } from "react"; -import reactLogo from "./assets/react.svg"; -import viteLogo from "/vite.svg"; -import "./App.css"; +import { useState, useEffect } from "react"; +import { Cpu, Database, Zap, Activity } from "lucide-react"; function App() { - const [count, setCount] = useState(0); + const [engineStatus, setEngineStatus] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + checkEngineHealth(); + }, []); + + const checkEngineHealth = async () => { + try { + const response = await fetch('/api/health'); + const data = await response.json(); + setEngineStatus(data); + } catch (error) { + console.error('Engine health check failed:', error); + setEngineStatus({ success: false, message: 'Engine offline' }); + } finally { + setLoading(false); + } + }; return ( - <> -
- - Vite logo - - - React logo - +
+
+ {/* Header */} +
+
+ +

+ CodeRED-Astra +

+
+

+ Hackathon Project - React Frontend + Rust Engine +

+
+ + {/* Status Cards */} +
+ {/* React App Status */} +
+
+ +

React Frontend

+
+
āœ“ Online
+

+ Vite + React development environment ready +

+
+ + {/* Rust Engine Status */} +
+
+ +

Rust Engine

+
+
+ {loading ? 'ā³ Checking...' : engineStatus?.success ? 'āœ“ Online' : 'āœ— Offline'} +
+

+ {loading ? 'Connecting to engine...' : + engineStatus?.success ? 'Engine responding normally' : + 'Engine may still be starting up'} +

+
+
+ + {/* Engine Details */} + {engineStatus?.success && ( +
+
+ +

Engine Status

+
+
+
+ Status: + {engineStatus.data?.status} +
+
+ Last Check: + + {engineStatus.data?.timestamp ? new Date(engineStatus.data.timestamp).toLocaleTimeString() : 'N/A'} + +
+
+ {engineStatus.message && ( +
+ {engineStatus.message} +
+ )} +
+ )} + + {/* Quick Actions */} +
+

Quick Actions

+
+ + + +
+
+ + {/* Development Notes */} +
+

šŸš€ Ready for hackathon development!

+

+ Frontend team: Work in web-app/src/ | + Backend team: Work in rust-engine/src/ +

+
-

Vite + React

-
- -

- Edit src/App.jsx and save to test HMR -

-
-

- Click on the Vite and React logos to learn more -

- +
); } diff --git a/web-app/src/index.css b/web-app/src/index.css index 9330886..ec9640b 100644 --- a/web-app/src/index.css +++ b/web-app/src/index.css @@ -2,28 +2,32 @@ @tailwind components; @tailwind utilities; -.light { - --paragraph: 16, 17, 20; - --background: 229, 230, 240; - --primary: 41, 49, 97; - --secondary: 122, 137, 220; - --accent: 32, 55, 203; - background: rgba(var(--background)); -} -.dark { - --paragraph: 235, 236, 239; - --background: 15, 16, 26; - --primary: 158, 166, 214; - --secondary: 35, 50, 133; - --accent: 52, 75, 223; - background: rgba(var(--background)); +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + color-scheme: dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } body { margin: 0; - font-family: - -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", - "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +#root { + width: 100%; + margin: 0; +} + +code { + font-family: ui-monospace, SFMono-Regular, "SF Mono", Consolas, "Liberation Mono", Menlo, monospace; } diff --git a/web-app/vite.config.js b/web-app/vite.config.js index eebfd72..226be7d 100644 --- a/web-app/vite.config.js +++ b/web-app/vite.config.js @@ -5,4 +5,22 @@ import jsconfigPaths from "vite-jsconfig-paths"; // https://vite.dev/config/ export default defineConfig({ plugins: [react(), jsconfigPaths()], + server: { + host: '0.0.0.0', + port: 3000, + proxy: { + '/api': { + target: process.env.RUST_ENGINE_URL || 'http://localhost:8000', + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api/, '') + } + } + }, + preview: { + host: '0.0.0.0', + port: 3000 + }, + build: { + outDir: 'dist' + } });