No description
| deploy | ||
| service_factory | ||
| .editorconfig | ||
| .eslintrc | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| AGENTS.md | ||
| license.txt | ||
| pyproject.toml | ||
| README.md | ||
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
cd $PATH_TO_YOUR_BENCH
bench get-app $URL_OF_THIS_REPO --branch version-16
bench install-app service_factory
Post-Install
- Create Zoraxy virtual directory:
/socket.io→http://[server-ip]:9000/socket.iowith WebSocket passthrough enabled - Configure nginx to serve
/assets/directly (see nginx config indeploy/) - If behind a reverse proxy, disable the socket.io origin check in
frappe/realtime/middlewares/authenticate.js
DocTypes
Engagement Card (the core)
The primary work tracking DocType with:
- Assignments — Multi-person team allocation
- Activity Log — Timestamped comments, milestones, notes
- Time Log — Per-employee hours tracking
- Subtasks — Delegatable breakdown items
Card types: SE (Sales Engineering), PS (Professional Services), MS (Managed Services), Support
Status Flow
Discovery → Delivery → Complete → Archived
Development
Prerequisites
- Python ≥3.14
- Node.js/Bun
- pre-commit
Setup
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