diff --git a/.env b/.env deleted file mode 100644 index 8c71b0e2..00000000 --- a/.env +++ /dev/null @@ -1,7 +0,0 @@ -VITE_SUPABASE_PROJECT_ID="vatgianzotsurljznsry" -VITE_SUPABASE_PUBLISHABLE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZhdGdpYW56b3RzdXJsanpuc3J5Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjI2OTA2MDksImV4cCI6MjA3ODI2NjYwOX0.7AjzaZjAMcygsMiPbI8w43F00JDU6hlpOWlbejOAZS0" -VITE_SUPABASE_URL="https://vatgianzotsurljznsry.supabase.co" - -# CAD PROCESSING SERVICE (Local Dev) -VITE_CAD_SERVICE_URL="http://localhost:8888" -VITE_CAD_SERVICE_API_KEY="eryxon_dev_key_12345" diff --git a/.env.example b/.env.example index 6102d551..51f68e1d 100644 --- a/.env.example +++ b/.env.example @@ -28,30 +28,9 @@ VITE_SUPABASE_PROJECT_ID="your-project-id" # ============================================================================= # CAD PROCESSING SERVICE (Optional) # ============================================================================= -# Server-side CAD processing for geometry and PMI extraction -# See services/pmi-extractor/README.md for deployment instructions # CAD service URL (leave empty to use browser-based processing) # VITE_CAD_SERVICE_URL="https://your-cad-service.example.com" -# API key for CAD service authentication (optional if service allows anonymous) +# API key for CAD service authentication # VITE_CAD_SERVICE_API_KEY="your-api-key-here" - -# Legacy PMI service URL (falls back to VITE_CAD_SERVICE_URL if not set) -# VITE_PMI_SERVICE_URL="https://your-pmi-service.example.com" - -# ============================================================================= -# SELF-HOSTED NOTES -# ============================================================================= -# -# For self-hosted deployments: -# 1. Create a Supabase project (cloud or self-hosted) -# 2. Apply the database schema from supabase/migrations/ -# 3. Deploy edge functions: supabase functions deploy -# 4. Configure storage buckets: parts-images, issues -# 5. Set these environment variables -# -# See docs/SELF_HOSTING_GUIDE.md for complete instructions. -# -# License: BSL 1.1 - Self-hosting is free and unlimited. -# You cannot offer commercial hosted versions that compete with eryxon.eu diff --git a/.github/workflows/deploy-cloudflare.yml b/.github/workflows/deploy-cloudflare.yml new file mode 100644 index 00000000..1c11f78a --- /dev/null +++ b/.github/workflows/deploy-cloudflare.yml @@ -0,0 +1,44 @@ +name: Deploy to Cloudflare Pages + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + contents: read + deployments: write + name: Deploy to Cloudflare Pages + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: Install dependencies + run: npm ci + + - name: Build + run: npm run build + env: + VITE_SUPABASE_URL: ${{ secrets.VITE_SUPABASE_URL }} + VITE_SUPABASE_PUBLISHABLE_KEY: ${{ secrets.VITE_SUPABASE_PUBLISHABLE_KEY }} + + - name: Deploy to Cloudflare Pages + uses: cloudflare/pages-action@v1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + projectName: eryxon-flow + directory: dist + gitHubToken: ${{ secrets.GITHUB_TOKEN }} + wranglerVersion: '3' diff --git a/.gitignore b/.gitignore index b451f134..c9dcc7dd 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,32 @@ __pycache__/ .Python *.egg-info/ .eggs/ + +# === Security: Sensitive Files === + +# Supabase configuration (contains project ID) +supabase/config.toml +supabase/.temp/ + +# Environment files (contains credentials) +.env +.env.local +.env.*.local +# Keep example files +!.env.example + +# Secrets and credentials +*.pem +*.key +*.p12 +secrets/ +credentials/ + +# IDE settings (may contain sensitive paths) +.vscode/settings.json +.idea/workspace.xml + +# Backup files +*.bak +*.backup +*~ diff --git a/DEPLOY.md b/DEPLOY.md new file mode 100644 index 00000000..74162ee6 --- /dev/null +++ b/DEPLOY.md @@ -0,0 +1,53 @@ +# Deploy Eryxon Flow + +## Prerequisites + +- Supabase account +- Cloudflare account (free tier) + +## Step 1: Create Supabase Project + +```bash +# 1. Go to supabase.com → Create project +# 2. Get credentials from Settings → API: +# - Project URL +# - anon key +# - Project Ref + +# 3. Apply schema +supabase link --project-ref YOUR_REF +supabase db push + +# 4. Create storage +supabase storage create parts-images +supabase storage create issues + +# 5. Deploy functions +supabase functions deploy +``` + +## Step 2: Deploy to Cloudflare Pages + +```bash +# 1. Go to dash.cloudflare.com +# 2. Pages → Create → Connect Git +# 3. Select repo +# 4. Build: npm run build +# 5. Output: dist +``` + +**Environment Variables** (set in Cloudflare): +``` +VITE_SUPABASE_URL = https://YOUR_REF.supabase.co +VITE_SUPABASE_PUBLISHABLE_KEY = your-anon-key +VITE_SUPABASE_PROJECT_ID = YOUR_REF +``` + +## Step 3: Custom Domain + +In Cloudflare Pages: +- Custom domains → Add domain +- Enter: app.eryxon.eu +- DNS: CNAME app → eryxon-flow.pages.dev + +Done. diff --git a/README.md b/README.md index ea661d46..53557ef5 100644 --- a/README.md +++ b/README.md @@ -1,209 +1,82 @@ -# Eryxon MES +# Eryxon Flow -**The simple, elegant and powerful manufacturing execution system that your people will love to use. Made for SMB metal fabrication.** +Open source Manufacturing Execution System (MES) for job shops and make-to-order manufacturers. -
+## Features -[![License: BSL 1.1](https://img.shields.io/badge/License-BSL_1.1-blue?style=for-the-badge)](LICENSE) -[![React](https://img.shields.io/badge/React-18.3.1-61DAFB?style=for-the-badge&logo=react&logoColor=black)](https://reactjs.org/) -[![TypeScript](https://img.shields.io/badge/TypeScript-5.8.3-3178C6?style=for-the-badge&logo=typescript&logoColor=white)](https://www.typescriptlang.org/) -[![Vite](https://img.shields.io/badge/Vite-7.2.6-646CFF?style=for-the-badge&logo=vite&logoColor=white)](https://vite.dev/) -[![Supabase](https://img.shields.io/badge/Supabase-2.86.2-3ECF8E?style=for-the-badge&logo=supabase&logoColor=white)](https://supabase.com/) +- Job and part tracking with real-time status updates +- Production planning and scheduling +- Multi-tenant SaaS architecture with row-level security +- Analytics and reporting (OEE, QRM, quality metrics) +- REST API with webhooks for ERP integration +- Shipping and logistics management +- Multi-language support (English, Dutch, German) -
+## Quick Deploy ---- +See **[DEPLOY.md](DEPLOY.md)** for complete deployment instructions. -## About This Project +## Prerequisites -Eryxon MES is built by [Sheet Metal Connect e.U.](https://www.sheetmetalconnect.com/), founded by Luke van Enkhuizen, for digital transformation of SMB metals companies. +- [Supabase](https://supabase.com) account +- [Cloudflare](https://cloudflare.com) account +- Node.js 20+ -This is a starting point. Each shop is unique - fork it, customize it, make it yours. Sheet Metal Connect e.U. can help you self-host and adapt it to your specific needs. - -**Recommended:** Self-host with your own Supabase instance or Docker. - ---- - -## What Makes This Different - -- **MCP Server** - AI/automation ready out of the box -- **API-first** - Send data from any system -- **Webhooks** - Link to any other system -- **Event-driven, real-time** - Industry 4.0 ready -- **Modern UI** - Operators actually want to use it - -It's opinionated. Built for sheet metal manufacturing. Not for everyone. - -## ✨ Key Features - -- **Production Management** - Job tracking, parts routing, operation assignments, and issue tracking -- **QRM Capacity Management** - WIP limits, capacity warnings, and bottleneck prevention -- **Operator Terminal** - Real-time production interface with time tracking and 3D CAD viewer -- **Admin Dashboard** - Live production metrics, job wizard, and activity monitoring -- **Multi-tenant SaaS** - Complete tenant isolation with row-level security -- **REST API & Webhooks** - Full integration capabilities with external systems -- **MCP Server** - AI-powered automation via Model Context Protocol -- **Multi-language** - English, Dutch, German with dark mode support - -## 🚀 Quick Start +## Local Development ```bash -# Install dependencies -npm install +git clone https://github.com/SheetMetalConnect/eryxon-flow.git +cd eryxon-flow -# Set up environment variables cp .env.example .env # Edit .env with your Supabase credentials -# Start development server +npm install npm run dev ``` -Visit `http://localhost:8080` to access the application. - -## 📚 Documentation - -Comprehensive documentation is available in the [`/docs`](./docs) folder: - -- **[HOW-THE-APP-WORKS.md](docs/HOW-THE-APP-WORKS.md)** - Complete functional guide -- **[API_DOCUMENTATION.md](docs/API_DOCUMENTATION.md)** - REST API reference -- **[DESIGN_SYSTEM.md](docs/DESIGN_SYSTEM.md)** - Design tokens and styling -- **[EDGE_FUNCTIONS_SETUP.md](docs/EDGE_FUNCTIONS_SETUP.md)** - Edge Functions guide -- **[CICD_DEPLOYMENT_PLAN.md](docs/CICD_DEPLOYMENT_PLAN.md)** - CI/CD pipeline and Docker deployment -- **[CLAUDE.md](CLAUDE.md)** - AI assistant guide for contributors - -Additional documentation: -- [3D Viewer](docs/3d-viewer.md) -- [Notifications System](docs/NOTIFICATIONS_SYSTEM.md) -- [Data Export](docs/DATA_EXPORT_FEATURE.md) -- [Integrations Marketplace](docs/INTEGRATIONS_MARKETPLACE.md) -- [MCP Server Setup](mcp-server/README.md) - -## 🏗️ Tech Stack - -- **Frontend**: React 18, TypeScript 5.8, Vite 7, TailwindCSS 3 -- **UI**: shadcn/ui (54+ components), Material-UI, Lucide icons -- **State**: React Query, React Context -- **Backend**: Supabase (PostgreSQL, Realtime, Edge Functions, Storage) -- **Forms**: react-hook-form, Zod validation -- **3D**: Three.js for STEP file viewing -- **Charts**: Recharts -- **i18n**: i18next with en/nl/de support - -## 📁 Project Structure +## Environment Variables ``` -├── src/ -│ ├── components/ # UI components (admin, operator, terminal, qrm, etc.) -│ ├── pages/ # Route pages (admin, operator, common) -│ ├── hooks/ # Custom React hooks -│ ├── lib/ # Utility libraries -│ └── integrations/ # Supabase client -├── supabase/ -│ ├── functions/ # 23 Edge Functions -│ └── migrations/ # Database schema -├── mcp-server/ # Model Context Protocol server -└── docs/ # Documentation +VITE_SUPABASE_URL +VITE_SUPABASE_PUBLISHABLE_KEY +VITE_SUPABASE_PROJECT_ID ``` -## 🔒 Security - -- **Multi-Tenancy**: PostgreSQL Row-Level Security for complete data isolation -- **Authentication**: Supabase Auth with JWT tokens -- **API Security**: Bearer token auth with bcrypt-hashed keys -- **Webhooks**: HMAC-SHA256 signatures for verification - -## Getting Started +See `.env.example` for complete list. -| | Hosted Demo | Self-Hosted (Recommended) | -|---|---|---| -| **Where** | Our infrastructure | Your infrastructure | -| **Usage** | Limited | Unlimited | -| **API** | Limited | Full | -| **Webhooks** | Limited | Full | -| **MCP Server** | Limited | Full | -| **Support** | Docs only | Community + Consulting | +## Architecture -- **Hosted Demo** — Try it online, limited usage for evaluation and educational purposes -- **Self-Hosted** — Full features, unlimited usage, bring your own Supabase or Docker +**Frontend**: React + TypeScript + Vite +**UI**: shadcn/ui + Tailwind CSS +**Backend**: Supabase (PostgreSQL + Edge Functions) +**Deployment**: Cloudflare Pages +**Database**: 85 migrations, multi-tenant schema +**API**: 28 Edge Functions -**Recommended:** Self-host with your own Supabase instance. See the [Self-Hosting Guide](docs/SELF_HOSTING_GUIDE.md) for database setup, migrations, and deployment. +## Documentation -Need help setting up or customizing? [Contact Sheet Metal Connect e.U.](mailto:office@sheetmetalconnect.com) - -## Deployment - -### Self-Hosted - -```bash -# Clone and configure -git clone https://github.com/SheetMetalConnect/eryxon-flow.git -cd eryxon-flow -cp .env.example .env -# Edit .env with your Supabase credentials - -# Run with Docker -docker-compose up -d -``` - -See **[docs/SELF_HOSTING_GUIDE.md](docs/SELF_HOSTING_GUIDE.md)** for complete setup instructions. - -### Docker Quick Start - -```bash -docker pull ghcr.io/sheetmetalconnect/eryxon-flow:latest -docker run -p 8080:80 \ - -e VITE_SUPABASE_URL=your-url \ - -e VITE_SUPABASE_PUBLISHABLE_KEY=your-key \ - ghcr.io/sheetmetalconnect/eryxon-flow:latest -``` +- [DEPLOY.md](DEPLOY.md) - Deployment guide +- [docs/API_DOCUMENTATION.md](docs/API_DOCUMENTATION.md) - API reference +- [docs/SELF_HOSTING_GUIDE.md](docs/SELF_HOSTING_GUIDE.md) - Self-hosting +- [docs/DATABASE.md](docs/DATABASE.md) - Database schema +- [docs/](docs/) - Complete documentation ## License -**Business Source License 1.1 (BSL 1.1)** - Source Available +**Business Source License 1.1** -This is an **open source repository** under the BSL 1.1 license, which allows source code access while preventing competitive SaaS offerings. - -**TL;DR:** Use it, modify it, self-host it - all free. Just don't host it and charge others for access. - -- ✅ Self-host for your own manufacturing operations - free, unlimited -- ✅ Fork it, modify it, make it yours - each shop is unique -- ✅ Use for internal business, development, testing, education -- ❌ Cannot host it and sell access as a SaaS to others -- 🔄 Converts to Apache 2.0 after 4 years +- Free to use for your own manufacturing business +- Source available for modification and improvement +- Self-host unlimited instances +- Cannot offer as competing hosted service See [LICENSE](LICENSE) for full terms. -### External Components (Feature Flags) - -Some features require external services that must be deployed separately: - -| Feature | Service | Description | Feature Flag | -|---------|---------|-------------|--------------| -| Advanced CAD (PMI/MBD) | `services/eryxon3d` | Server-side CAD processing with PMI extraction | `advancedCAD` | - -These external components are: -- **Disabled by default** - must be explicitly enabled via feature flags in Organization Settings -- **Self-hosted** - you deploy and control the service -- **Optional** - core MES functionality works without them - -To enable an external feature: -1. Deploy the required service (see `services/` directory) -2. Configure environment variables (see `.env.example`) -3. Enable the feature flag in Admin → Settings → Organization Settings - ---- - -## Contributing & Support - -- **Website**: [sheetmetalconnect.com](https://www.sheetmetalconnect.com/) -- **Issues & PRs**: [GitHub](https://github.com/SheetMetalConnect/eryxon-flow) -- **Consulting & Custom Setup**: [office@sheetmetalconnect.com](mailto:office@sheetmetalconnect.com) - -No guarantees of continued development, but likely will be updated with latest features. - ---- +**Change Date**: 2029-01-01 (converts to Apache 2.0) -Copyright © 2025 Sheet Metal Connect e.U. +## Support -**Built with** React + TypeScript + Supabase | **Region**: EU (Netherlands) +- Documentation: [docs/](docs/) +- Issues: [GitHub Issues](https://github.com/SheetMetalConnect/eryxon-flow/issues) +- Commercial support: office@sheetmetalconnect.com diff --git a/public/_headers b/public/_headers new file mode 100644 index 00000000..77b1104d --- /dev/null +++ b/public/_headers @@ -0,0 +1,15 @@ +# Security headers +/* + X-Frame-Options: DENY + X-Content-Type-Options: nosniff + X-XSS-Protection: 1; mode=block + Referrer-Policy: strict-origin-when-cross-origin + Permissions-Policy: camera=(), microphone=(), geolocation=() + +# Cache static assets +/assets/* + Cache-Control: public, max-age=31536000, immutable + +# Don't cache index.html +/index.html + Cache-Control: no-cache, no-store, must-revalidate diff --git a/public/_redirects b/public/_redirects new file mode 100644 index 00000000..1c8b7267 --- /dev/null +++ b/public/_redirects @@ -0,0 +1,2 @@ +# Cloudflare Pages - SPA routing +/* /index.html 200 diff --git a/scripts/security/clean-git-history.sh b/scripts/security/clean-git-history.sh new file mode 100755 index 00000000..0a967fdf --- /dev/null +++ b/scripts/security/clean-git-history.sh @@ -0,0 +1,87 @@ +#!/bin/bash +# Clean .env and config.toml from git history +# WARNING: This rewrites git history! + +set -e + +echo "🧹 Git History Cleanup" +echo "=====================" +echo "" +echo "⚠️ WARNING: This will rewrite git history!" +echo "" +echo "This removes from ALL commits:" +echo " - .env" +echo " - supabase/config.toml" +echo "" +echo "After running:" +echo " - All contributors must re-clone" +echo " - Force push required" +echo " - Cannot be undone easily" +echo "" +read -p "Are you SURE? (type 'yes' to continue): " CONFIRM + +if [ "$CONFIRM" != "yes" ]; then + echo "Aborted." + exit 1 +fi + +echo "" +echo "Checking for git-filter-repo..." + +if ! command -v git-filter-repo &> /dev/null; then + echo "❌ git-filter-repo not found" + echo "" + echo "Install it:" + echo " pip install git-filter-repo" + echo "" + echo "Or on macOS:" + echo " brew install git-filter-repo" + echo "" + exit 1 +fi + +echo "✓ git-filter-repo found" +echo "" + +# Backup current branch +CURRENT_BRANCH=$(git branch --show-current) +echo "Current branch: $CURRENT_BRANCH" +echo "" + +# Create backup tag +BACKUP_TAG="backup-before-history-clean-$(date +%Y%m%d-%H%M%S)" +echo "Creating backup tag: $BACKUP_TAG" +git tag "$BACKUP_TAG" +echo "✓ Backup tag created" +echo "" + +# Remove .env from history +echo "Removing .env from git history..." +git filter-repo --invert-paths --path .env --force +echo "✓ .env removed from history" +echo "" + +# Remove config.toml from history +echo "Removing supabase/config.toml from git history..." +git filter-repo --invert-paths --path supabase/config.toml --force +echo "✓ supabase/config.toml removed from history" +echo "" + +echo "✅ Git history cleaned!" +echo "" +echo "Next steps:" +echo "" +echo "1. Verify the cleanup:" +echo " git log --all --full-history -- .env" +echo " (should show nothing)" +echo "" +echo "2. Force push to remote:" +echo " git push --force --all" +echo " git push --force --tags" +echo "" +echo "3. Notify all contributors to re-clone:" +echo " git clone " +echo "" +echo "4. If something went wrong, restore from backup:" +echo " git reset --hard $BACKUP_TAG" +echo "" diff --git a/src/integrations/supabase/client.ts b/src/integrations/supabase/client.ts index 534b6a18..b017ed7e 100644 --- a/src/integrations/supabase/client.ts +++ b/src/integrations/supabase/client.ts @@ -2,8 +2,12 @@ import { createClient } from '@supabase/supabase-js'; import type { Database } from './types'; -const SUPABASE_URL = import.meta.env.VITE_SUPABASE_URL || "https://vatgianzotsurljznsry.supabase.co"; -const SUPABASE_PUBLISHABLE_KEY = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY || "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZhdGdpYW56b3RzdXJsanpuc3J5Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjI2OTA2MDksImV4cCI6MjA3ODI2NjYwOX0.7AjzaZjAMcygsMiPbI8w43F00JDU6hlpOWlbejOAZS0"; +const SUPABASE_URL = import.meta.env.VITE_SUPABASE_URL; +const SUPABASE_PUBLISHABLE_KEY = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY; + +if (!SUPABASE_URL || !SUPABASE_PUBLISHABLE_KEY) { + throw new Error('Missing VITE_SUPABASE_URL or VITE_SUPABASE_PUBLISHABLE_KEY environment variables. Please check your .env file.'); +} // Import the supabase client like this: // import { supabase } from "@/integrations/supabase/client"; diff --git a/src/lib/upload-with-progress.ts b/src/lib/upload-with-progress.ts index fb848900..4aa36429 100644 --- a/src/lib/upload-with-progress.ts +++ b/src/lib/upload-with-progress.ts @@ -34,9 +34,13 @@ export async function uploadFileWithProgress( const { onProgress, signal } = options; try { - // Use the actual Supabase project URL and anon key - const supabaseUrl = 'https://vatgianzotsurljznsry.supabase.co'; - const supabaseKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZhdGdpYW56b3RzdXJsanpuc3J5Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NjI2OTA2MDksImV4cCI6MjA3ODI2NjYwOX0.7AjzaZjAMcygsMiPbI8w43F00JDU6hlpOWlbejOAZS0'; + // Get Supabase configuration from environment variables + const supabaseUrl = import.meta.env.VITE_SUPABASE_URL; + const supabaseKey = import.meta.env.VITE_SUPABASE_PUBLISHABLE_KEY; + + if (!supabaseUrl || !supabaseKey) { + throw new Error('Missing VITE_SUPABASE_URL or VITE_SUPABASE_PUBLISHABLE_KEY environment variables'); + } // Get the current session for auth const { data: { session } } = await supabase.auth.getSession(); diff --git a/supabase/config.toml b/supabase/config.toml deleted file mode 100644 index f8f53aa7..00000000 --- a/supabase/config.toml +++ /dev/null @@ -1 +0,0 @@ -project_id = "vatgianzotsurljznsry" \ No newline at end of file diff --git a/wrangler.toml b/wrangler.toml new file mode 100644 index 00000000..a492f839 --- /dev/null +++ b/wrangler.toml @@ -0,0 +1,20 @@ +name = "eryxon-flow" +compatibility_date = "2024-01-01" + +[build] +command = "npm run build" + +[build.upload] +format = "service-worker" +main = "./dist" + +[site] +bucket = "./dist" + +[env.production] +name = "eryxon-flow" +route = "" +vars = { NODE_VERSION = "20" } + +[env.preview] +name = "eryxon-flow-preview"