- InlineField component + useInlineEdit composable for Odoo-style dblclick editing - Client search by name, account ID, and legacy_customer_id (or_filters) - SMS/Email notification panel on ContactCard via n8n webhooks - Ticket reply thread via Communication docs - All migration scripts (51 files) now tracked - Client portal and field tech app added to monorepo - README rewritten with full feature list, migration summary, architecture - CHANGELOG updated with all recent work - ROADMAP updated with current completion status - Removed hardcoded tokens from docs (use $ERP_SERVICE_TOKEN) - .gitignore updated (docker/, .claude/, exports/, .quasar/) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
199 lines
9.1 KiB
Markdown
199 lines
9.1 KiB
Markdown
# Gigafibre FSM
|
|
|
|
Complete operations platform for **Gigafibre** (consumer brand of TARGO Internet), a fiber ISP in Quebec. Replaces a legacy PHP/MariaDB billing system with ERPNext v16 + custom Vue.js (Quasar) apps.
|
|
|
|
## What This Repo Contains
|
|
|
|
| Directory | Description |
|
|
|-----------|-------------|
|
|
| `apps/ops/` | **Targo Ops** — main operations PWA (Vue 3 / Quasar v2) |
|
|
| `apps/field/` | **Targo Field** — mobile app for technicians (barcode, diagnostics, offline) |
|
|
| `apps/client/` | **Gigafibre Portal** — customer self-service portal |
|
|
| `apps/website/` | **www.gigafibre.ca** — marketing site (React / Vite / Tailwind) |
|
|
| `apps/dispatch/` | Legacy dispatch app (replaced by `apps/ops/` dispatch module) |
|
|
| `apps/portal/` | Customer portal deploy configs |
|
|
| `erpnext/` | ERPNext custom doctype setup scripts |
|
|
| `scripts/migration/` | 51 Python scripts for legacy-to-ERPNext data migration |
|
|
| `scripts/` | Utility scripts (bulk submit, PostgreSQL fixes) |
|
|
| `docs/` | Architecture, infrastructure, migration plan, changelog |
|
|
|
|
## Architecture
|
|
|
|
```
|
|
96.125.196.67 (Proxmox VM, Ubuntu 24.04)
|
|
|
|
|
Traefik v2.11 (TLS via Let's Encrypt)
|
|
|
|
|
+-- erp.gigafibre.ca ERPNext v16.10.1 (PostgreSQL, 9 containers)
|
|
+-- erp.gigafibre.ca/ops/ Ops PWA (Quasar/Vue3, Authentik SSO)
|
|
+-- id.gigafibre.ca Authentik SSO (customer-facing)
|
|
+-- auth.targo.ca Authentik SSO (staff, federated to id.gigafibre.ca)
|
|
+-- n8n.gigafibre.ca n8n workflow automation
|
|
+-- git.targo.ca Gitea
|
|
+-- www.gigafibre.ca Marketing site + address API
|
|
+-- oss.gigafibre.ca Oktopus CE (TR-069 CPE management)
|
|
+-- tracker.targointernet.com Traccar GPS tracking
|
|
```
|
|
|
|
## Features
|
|
|
|
### Ops App (`apps/ops/`)
|
|
|
|
- **Client Management** — customer list with search by name, account ID, legacy ID. Inline editing (double-click any field to edit, saves to ERPNext in background)
|
|
- **Client Detail** — full customer view with contact, billing KPIs, service locations, subscriptions, equipment, tickets, invoices, payments, notes
|
|
- **Inline Editing** — Odoo-style double-click-to-edit on all fields (locations, equipment, tickets, invoices). Uses `InlineField` component + `useInlineEdit` composable
|
|
- **Dispatch Timeline** — drag-drop job scheduling with Mapbox map, GPS tracking (Traccar), technician management, tag/skill system
|
|
- **Ticket Management** — list with inline status/priority editing, detail modal with reply thread
|
|
- **Equipment Tracking** — serial/MAC, status lifecycle, OLT info, per-location grouping
|
|
- **SMS/Email Notifications** — send from contact card via n8n webhooks (Twilio SMS, Mailjet email)
|
|
- **Invoice OCR** — scan paper bills using Ollama Vision (llama3.2-vision)
|
|
- **PWA** — installable, offline-capable with Workbox
|
|
|
|
### Legacy Migration (completed)
|
|
|
|
Migrated from a 15-year-old PHP/MariaDB billing system:
|
|
|
|
| Data | Volume | Status |
|
|
|------|--------|--------|
|
|
| Customers | 6,667 (active + terminated) | Migrated |
|
|
| Contacts + Addresses | ~6,600 each | Migrated |
|
|
| Service Locations | ~17,000 | Migrated |
|
|
| Subscriptions | 21,876 (with RADIUS credentials) | Migrated |
|
|
| Items (products/plans) | 833 | Migrated |
|
|
| Sales Invoices | 115,000+ | Migrated |
|
|
| Payments | 99,000+ | Migrated with invoice references |
|
|
| Tickets (Issues) | 242,000+ (parent/child hierarchy) | Migrated |
|
|
| Ticket Messages (Communications) | 784,000+ | Migrated |
|
|
| Customer Memos (Comments) | 29,000+ | Migrated with real dates |
|
|
| Employees | 45 ERPNext Users from legacy staff | Migrated |
|
|
|
|
### Bugs Fixed From Legacy System
|
|
|
|
- **Date corruption** — Unix timestamps stored as strings; fixed during import with timezone-aware conversion
|
|
- **Invoice outstanding amounts** — payment_item references broken in legacy; reconciled during migration
|
|
- **Customer links** — orphan records (invoices/payments without valid customer); rebuilt relationships
|
|
- **Subscription details** — missing service_location links, incorrect billing frequencies; corrected via analysis scripts
|
|
- **Reversal transactions** — credit notes improperly recorded; mapped to ERPNext return invoices
|
|
- **Annual billing dates** — yearly subscriptions had wrong period boundaries; recalculated
|
|
- **Duplicate customer IDs** — legacy allowed duplicate customer_id; resolved with rename script
|
|
- **Staff/ticket ownership** — legacy used numeric IDs for assignment; mapped to ERPNext User emails
|
|
|
|
### ERPNext Adjustments for Import
|
|
|
|
- **Direct PostgreSQL inserts** — Frappe ORM too slow for 100K+ records; used psycopg2 with proper `tabXxx` schema
|
|
- **Scheduler paused** — disabled auto-invoicing during import to prevent 21K subscriptions from generating invoices
|
|
- **Custom fields on Customer** — `legacy_account_id`, `legacy_customer_id`, `ppa_enabled`, `stripe_id`, date fields
|
|
- **Custom fields on Item** — `legacy_product_id`, download/upload speeds, quotas, OLT profiles
|
|
- **Custom fields on Subscription** — `radius_user`, `radius_pwd`, `legacy_service_id`
|
|
- **Custom fields on Issue** — `legacy_ticket_id`, `assigned_staff`, `opened_by_staff`, `issue_type`, `is_important`, `service_location`
|
|
- **PostgreSQL GROUP BY patch** — ERPNext v16 generates MySQL-style queries; patched `number_card.py` and PLE reports
|
|
- **Subscription API unlock** — removed `read_only` and `set_only_once` restrictions on Subscription fields for REST API updates
|
|
- **Portal auth bridge** — server script for legacy MD5 password migration to PBKDF2
|
|
|
|
## ERPNext Custom Doctypes
|
|
|
|
### Field Service Management
|
|
|
|
| Doctype | ID Pattern | Purpose |
|
|
|---------|-----------|---------|
|
|
| Service Location | LOC-##### | Customer premises (address, GPS, OLT port, network config) |
|
|
| Service Equipment | EQP-##### | Deployed hardware (ONT, router, TV box — serial, MAC, IP) |
|
|
| Service Subscription | SUB-##### | Active service plans (speed, price, billing cycle, RADIUS) |
|
|
|
|
### Dispatch
|
|
|
|
| Doctype | Purpose |
|
|
|---------|---------|
|
|
| Dispatch Job | Work orders with equipment, materials, checklist, photos, signature |
|
|
| Dispatch Technician | Tech profiles with GPS link (Traccar), skills, color coding |
|
|
| Dispatch Tag | Categorization with skill levels (Fibre, TV, Telephonie, etc.) |
|
|
| Dispatch Tag Link | Child table linking tags to jobs/techs with level + required flag |
|
|
|
|
### Child Tables
|
|
|
|
Equipment Move Log, Job Equipment Item, Job Material Used, Job Checklist Item, Job Photo, Dispatch Job Assistant, Checklist Template + Items
|
|
|
|
## Quick Start
|
|
|
|
### Development
|
|
|
|
```bash
|
|
# Ops app
|
|
cd apps/ops
|
|
npm install
|
|
npx quasar dev
|
|
|
|
# Website
|
|
cd apps/website
|
|
npm install
|
|
npm run dev
|
|
```
|
|
|
|
### Deploy Ops to Production
|
|
|
|
```bash
|
|
cd apps/ops
|
|
bash deploy.sh # builds PWA + deploys to server via SSH
|
|
```
|
|
|
|
### Run Migration Scripts
|
|
|
|
```bash
|
|
# Scripts run inside the ERPNext backend container
|
|
docker cp scripts/migration/migrate_all.py frappe_docker-backend-1:/tmp/
|
|
docker exec frappe_docker-backend-1 bench --site erp.gigafibre.ca execute /tmp/migrate_all.main
|
|
```
|
|
|
|
### Setup FSM Doctypes
|
|
|
|
```bash
|
|
docker cp erpnext/setup_fsm_doctypes.py frappe_docker-backend-1:/home/frappe/frappe-bench/apps/frappe/frappe/
|
|
docker exec frappe_docker-backend-1 bench --site erp.gigafibre.ca execute frappe.setup_fsm_doctypes.create_all
|
|
```
|
|
|
|
## Documentation
|
|
|
|
| Document | Content |
|
|
|----------|---------|
|
|
| [ARCHITECTURE.md](docs/ARCHITECTURE.md) | Data model, tech stack, authentication flow, doctype reference |
|
|
| [INFRASTRUCTURE.md](docs/INFRASTRUCTURE.md) | Server, DNS, Traefik, Authentik, Docker, n8n, gotchas |
|
|
| [MIGRATION-PLAN.md](docs/MIGRATION-PLAN.md) | Legacy system portrait, mapping, phases, risks |
|
|
| [CHANGELOG.md](docs/CHANGELOG.md) | Detailed migration log with volumes and methods |
|
|
| [ROADMAP.md](docs/ROADMAP.md) | 5-phase implementation plan |
|
|
| [MIGRATION_MAP.md](scripts/migration/MIGRATION_MAP.md) | Field-level mapping legacy tables to ERPNext |
|
|
| [COMPETITIVE-ANALYSIS.md](docs/COMPETITIVE-ANALYSIS.md) | Comparison with Gaiia, Odoo, Zuper, Salesforce, ServiceTitan |
|
|
|
|
## Infrastructure
|
|
|
|
| Service | URL | Technology |
|
|
|---------|-----|------------|
|
|
| ERP | erp.gigafibre.ca | ERPNext v16.10.1 (Frappe, PostgreSQL) |
|
|
| Ops | erp.gigafibre.ca/ops/ | Quasar v2 PWA |
|
|
| SSO (staff) | auth.targo.ca | Authentik |
|
|
| SSO (customers) | id.gigafibre.ca | Authentik (federated from auth.targo.ca) |
|
|
| Workflows | n8n.gigafibre.ca | n8n |
|
|
| Git | git.targo.ca | Gitea |
|
|
| GPS | tracker.targointernet.com | Traccar |
|
|
| Website | www.gigafibre.ca | React / Vite / Tailwind |
|
|
| CPE Mgmt | oss.gigafibre.ca | Oktopus CE (TR-069) |
|
|
| DNS | Cloudflare | gigafibre.ca (DNS-only, Traefik handles TLS) |
|
|
| Email | Mailjet | noreply@targo.ca |
|
|
| SMS | Twilio | +1 438 231-3838 |
|
|
|
|
## Tech Stack
|
|
|
|
| Layer | Technology |
|
|
|-------|-----------|
|
|
| Backend | ERPNext v16 / Frappe (Python) on PostgreSQL |
|
|
| Frontend (ops) | Vue 3, Quasar v2, Pinia, Vite |
|
|
| Frontend (website) | React, Vite, Tailwind, shadcn/ui |
|
|
| Maps | Mapbox GL JS + Directions API |
|
|
| GPS | Traccar (REST + WebSocket) |
|
|
| Auth | Authentik SSO (forwardAuth via Traefik) |
|
|
| Proxy | Traefik v2.11 (Let's Encrypt) |
|
|
| Automation | n8n webhooks |
|
|
| SMS | Twilio (via n8n) |
|
|
| Email | Mailjet (via n8n) |
|
|
| OCR | Ollama (llama3.2-vision) |
|
|
| Hosting | Proxmox VM, Ubuntu 24.04, Docker |
|