# Service Factory Professional Services Delivery & Capacity Management — a custom Frappe/ERPNext app. ## Deployment Architecture ### Production Stack ``` ┌──────────────────────┐ │ Zoraxy Proxy │ │ (SSL termination) │ │ Port 443 → 8000 │ │ /socket.io → :9000 │ │ WebSocket passthrough │ └──────┬───────────────┘ │ ┌───────────┴───────────┐ │ Nginx (8000+8080) │ │ │ │ /assets/ → filesystem │ │ /socket.io → :9000 │ │ /* → gunicorn :8001 │ └───────┬──────────┬────┘ │ │ ┌───────┴──┐ ┌────┴────────┐ │ Gunicorn │ │ Socket.IO │ │ :8001 │ │ Node.js :9000│ └──────────┘ └─────────────┘ ``` ### Key Configuration | Component | Setting | Notes | |-----------|---------|-------| | **Zoraxy** | WebSocket passthrough: **enabled** | Required for real-time updates | | **Zoraxy** | Virtual directory: `/socket.io` → `http://172.16.8.20:9000/socket.io` | Routes WebSocket directly to socket.io server | | **Nginx** | `/assets/` served directly from filesystem | Bypasses gunicorn — essential for correct CSS/JS MIME types behind proxies | | **Nginx** | `proxy_set_header Host erp.lohmar.co.uk` | Set for socket.io location to pass origin checks | | **Socket.io** | Origin check **disabled** in `authenticate.js` | Socket.io's built-in CORS handles security; middleware check breaks behind proxies | ### Services | Service | Port | Description | |---------|------|-------------| | `frappe-bench-web.service` | 8001 | Gunicorn (Frappe web app) — behind nginx | | `frappe-bench-worker.service` | — | Background async worker | | `frappe-bench-schedule.service` | — | Scheduled job runner | | `frappe-bench-socketio.service` | 9000 | Realtime WebSocket (Node.js) | | `frappe-bench-watch.service` | — | File watcher for dev/assets | ### Ports | Port | Purpose | |------|---------| | 443 | Zoraxy HTTPS → nginx :8000 | | 8080 | Nginx direct (no SSL, for testing) | | 8000 | Nginx (Zoraxy target) | | 8001 | Gunicorn (behind nginx) | | 9000 | Socket.io Node.js server | ## Installation ```bash cd $PATH_TO_YOUR_BENCH bench get-app $URL_OF_THIS_REPO --branch version-16 bench install-app service_factory ``` ### Post-Install 1. Create Zoraxy virtual directory: `/socket.io` → `http://[server-ip]:9000/socket.io` with WebSocket passthrough enabled 2. Configure nginx to serve `/assets/` directly (see nginx config in `deploy/`) 3. If behind a reverse proxy, disable the socket.io origin check in `frappe/realtime/middlewares/authenticate.js` ## DocTypes ### Setup (Master) - **Engagement Task Type** — Task categories (Demo, POC, Deployment, RFP/RFI, Other) - **Team Template** — Pre-defined teams by department - Child: **Team Template Member** — Employee assignment with role ### Transaction - **Engagement Card** — Universal work card (TEC) - Child: **Engagement Card Assignment** — Multi-person team allocation - Child: **Engagement Card Activity** — Activity log with milestones - Child: **Engagement Card Time Log** — Per-employee hours tracking - Child: **Engagement Card Subtask** — Delegatable breakdown items ### Status Flow ``` Discovery → Delivery → Complete → Archived ``` ## Development ### Prerequisites - Python ≥3.14 - Node.js/Bun - pre-commit ### Setup ```bash cd apps/service_factory pre-commit install ``` Pre-commit runs ruff, eslint, prettier, and pyupgrade on commit. ### Agent Workflow This project uses OpenAgentsControl. The agent operates in two modes: - **🗣️ Discuss** — Architecture, design, questions (no execution) - **🔧 Build** — Execute agreed plans (write, deploy, commit) ### Versioning Format: `V{major}.{minor}.{patch}` (e.g., `V0.1.0009`) - Patch auto-increments on every git push - Agent commits and pushes after every completed step ## License MIT