209 lines
7.9 KiB
Markdown
209 lines
7.9 KiB
Markdown
# Service Factory — ERPNext Custom App Project
|
|
|
|
> **Current Version: V0.1.0020** — Each completed prompt/step increments the patch number by 1 (V0.1.0000 → V0.1.0001 → V0.1.0002…). The agent automatically commits and pushes after every step.
|
|
|
|
## Project Overview
|
|
|
|
**Service Factory** is a custom Frappe/ERPNext application that productizes professional services by treating human teams as structured "Resource Centers" and engagements as "Production Orders." Built for Frappe v16/ERPNext.
|
|
|
|
---
|
|
|
|
## Architecture
|
|
|
|
### ERPNext Deployment (Production)
|
|
|
|
| Attribute | Value |
|
|
|-----------|-------|
|
|
| **Location** | `/opt/erpnext/frappe-bench/` |
|
|
| **System user** | `erpnext` |
|
|
| **Frappe version** | v16 (via `bench`) |
|
|
| **Database** | MariaDB |
|
|
| **Domain** | `erp.lohmar.co.uk` |
|
|
| **Port** | 8080 (web via nginx proxy, proxies web + SocketIO) |
|
|
| **Direct port** | 8000 (gunicorn direct — SocketIO won't work) |
|
|
| **Reverse proxy** | Nginx on ports 8000+8080 → gunicorn:8001 (web) + node:9000 (SocketIO) |
|
|
| **Zoraxy config** | WebSocket passthrough: **enabled** — Virtual directory: `/socket.io` → `http://172.16.8.20:9000/socket.io` |
|
|
| **Static assets** | `/assets/` served directly by nginx (bypasses gunicorn) — essential for correct MIME handling behind Zoraxy |
|
|
| **Process manager** | systemd (5 services managed via `frappe-bench.target`) |
|
|
| **Reverse proxy** | Zoraxy (unifies web + SocketIO on port 8080) |
|
|
|
|
### Sites
|
|
|
|
| Site | URL | Purpose |
|
|
|------|-----|---------|
|
|
| `erp.lohmar.co.uk` | http://erp.lohmar.co.uk:8000 | **Production** — ERPNext with all default apps + service_factory |
|
|
| `test_sf.lohmar.co.uk` | (site created) | **Testing** — isolated site for Service Factory development |
|
|
|
|
### Installed Apps (on production site)
|
|
|
|
```
|
|
frappe, erpnext, service_factory
|
|
```
|
|
|
|
Default ERPNext apps active: Framework, Organization, Accounting, Assets, Buying, Manufacturing, Projects, Quality, Selling, Stock, Subcontracting, ERPNext Settings.
|
|
|
|
### Bench Services (systemd)
|
|
|
|
| Service | Description |
|
|
|---------|-------------|
|
|
| `frappe-bench-web.service` | Gunicorn web server (port 8001, behind nginx on ports 8000+8080) |
|
|
| `frappe-bench-worker.service` | Background async worker |
|
|
| `frappe-bench-schedule.service` | Scheduled job runner |
|
|
| `frappe-bench-socketio.service` | Realtime WebSocket (port 9000) |
|
|
| `frappe-bench-watch.service` | File watcher for dev/assets |
|
|
|
|
All services managed via `frappe-bench.target` (start/stop/status as a unit).
|
|
|
|
### Credentials
|
|
|
|
```
|
|
Location: /root/erpnext-admin-credentials.txt
|
|
Site: http://erp.lohmar.co.uk:8080
|
|
Username: Administrator
|
|
```
|
|
|
|
---
|
|
|
|
## Development Repository Structure
|
|
|
|
```
|
|
~/development/
|
|
├── erp-next/ # Git repository (Forgejo: cclohmar/erp-next.git)
|
|
│ ├── service_factory/ # Frappe app source (DEV COPY — may be behind bench)
|
|
│ ├── pyproject.toml
|
|
│ ├── README.md
|
|
│ └── .pre-commit-config.yaml
|
|
└── sow.md # Statement of Work — the authoritative blueprint
|
|
```
|
|
|
|
The **actual live app** lives at:
|
|
```
|
|
/opt/erpnext/frappe-bench/apps/service_factory/
|
|
```
|
|
|
|
**IMPORTANT**: The bench app and the dev repo are two separate git clones. The bench app contains the latest development work (all milestones complete). The dev repo at `~/development/erp-next/` may be behind and needs syncing after changes are made in the bench.
|
|
|
|
---
|
|
|
|
## Milestone Status (ALL COMPLETE in bench)
|
|
|
|
| # | Milestone | Status |
|
|
|---|-----------|--------|
|
|
| **M1** | Custom App Scaffold & DB Schema (5 DocTypes) | ✅ Done |
|
|
| **M2** | Backend Python Controllers (cost rollup, card generation, capacity warnings) | ✅ Done |
|
|
| **M3+4** | Frontend JS Components + Role-Based Workspaces | ✅ Done |
|
|
| **M5** | Test Suite (4 integration tests) | ✅ Done |
|
|
| — | Deployment config with systemd, nginx, Zoraxy proxy | ✅ Done |
|
|
| — | App icon + fixtures (seed data) | ✅ Done |
|
|
|
|
### DocTypes Created
|
|
|
|
**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
|
|
|
|
### Business Logic (server-side)
|
|
|
|
- `EngagementOrder.validate()` — Recipe step auto-population, capacity warnings, cost totals
|
|
- `EngagementOrder.on_submit()` — Auto-generates Execution Cards for assigned steps
|
|
- `ExecutionCard.on_update()` — Rollup of actual hours → parent order costs/billing
|
|
|
|
### Dashboards (3 role-based workspaces)
|
|
|
|
- **Engineer Workspace** — My Execution Cards, Timer, Hours chart, Quick actions
|
|
- **Manager Workspace** — Schedule Gantt, Capacity Alerts, Active/Stalled KPIs
|
|
- **Director Workspace** — Margin Ledger, Delivery Efficiency, Resource Burn-Down
|
|
|
|
### Tests (bench app)
|
|
|
|
```
|
|
test_engagement_order.py — 4 integration tests:
|
|
1. Execution Cards generated on Order submit
|
|
2. Cost/billing rollup from Card hours
|
|
3. Recipe steps auto-populate from template
|
|
4. Capacity warning fires on overallocation
|
|
```
|
|
|
|
---
|
|
|
|
## Git Operations
|
|
|
|
Git server: `git.lohmar.co.uk` (self-hosted Forgejo)
|
|
|
|
Two `.gitenv` files exist:
|
|
- `/root/.gitenv` — template (placeholder, ignore)
|
|
- `/root/bin/.gitenv` — **actual credentials**
|
|
|
|
```bash
|
|
source /root/bin/.gitenv
|
|
```
|
|
|
|
| Setting | Value |
|
|
|---------|-------|
|
|
| Remote | `https://cclohmar:${TOKEN}@git.lohmar.co.uk/cclohmar/erp-next.git` |
|
|
| Default branch | `main` |
|
|
| Commit prefix | `chore:` |
|
|
| Auto-stash | enabled |
|
|
|
|
### Two Git Repos — Keep in Sync
|
|
|
|
```
|
|
DEV REPO: ~/development/erp-next/ (1 commit — scaffold only)
|
|
BENCH APP: /opt/erpnext/frappe-bench/apps/service_factory/ (10 commits — all milestones)
|
|
```
|
|
|
|
The bench app has all the development work. When making changes:
|
|
1. Develop in the bench's app directory (or sync bench → dev repo first)
|
|
2. Commit from the bench app OR the dev repo
|
|
3. Push to Forgejo
|
|
|
|
### Auto-Push Workflow
|
|
|
|
After **every completed prompt/step**, the agent MUST:
|
|
1. Stage all changes (`git add -A`)
|
|
2. Commit with prefix `chore:` and a concise description
|
|
3. Increment the version in this file's header (V0.1.xxxx → V0.1.xxxx+1)
|
|
4. Push to `origin/main`
|
|
5. If the dev repo is behind the bench app, sync first before committing
|
|
|
|
This ensures every interaction is checkpointed and version-tracked.
|
|
|
|
---
|
|
|
|
## Development Environment
|
|
|
|
| Tool | Location |
|
|
|------|----------|
|
|
| OpenAgentsControl | `/root/.opencode/` |
|
|
| Context files | `/root/.opencode/context/` |
|
|
| Tmux manager | `/root/bin/workspace` (`tmux-project new\|return\|list\|kill`) |
|
|
| Linting | ruff (Python), eslint (JS), prettier |
|
|
| Python | ≥3.14 |
|
|
| Runtime | Node.js/Bun, `@opencode-ai/plugin` |
|
|
|
|
### Agent Modes (Toggle)
|
|
|
|
OpenAgent operates in two explicit modes during conversation:
|
|
|
|
| Mode | Trigger | Behaviour |
|
|
|------|---------|-----------|
|
|
| 🗣️ **Discuss** | **Default** — every interaction starts here | Ideas, trade-offs, architecture sketches (text-only), questions, exploration. **Not a single file is touched, no bash executed.** |
|
|
| 🔧 **Build** | Only when you say `"build it"` or equivalent | Execute the agreed plan — write files, edit code, run benchmarks, deploy, commit & push. All standard approval gates still apply. |
|
|
|
|
The toggle is conversational: I stay in 🗣️ Discuss until you explicitly switch to 🔧 Build. This ensures we align on direction before any work begins.
|
|
|
|
### Agent Rules
|
|
|
|
- **OpenAgent** — General purpose, workflow orchestration (toggle mode: discuss / build)
|
|
- **OpenCoder** — Production development
|
|
- Load context via ContextScout before any code/doc/test work
|
|
- Approval gates required before file writes and bash execution
|
|
- STOP on test failure — never auto-fix
|