DELETE /campaigns/:id removes the JSON from /opt/targo-hub/data/campaigns/. The Giftbit shortlinks already issued for that campaign live on Giftbit's side and are unaffected — this is purely about clearing internal tracking records (typically test runs cluttering the list). Refuses (409) while the send worker is active for that id so we never yank the file out from under saveCampaign(). Defensive id regex (in campaignPath) blocks path-traversal attempts before unlink runs. UI: red trash icon on each row, disabled while status=sending. Confirmation dialog spells out what survives the deletion (Giftbit links) vs what's lost (tracking, opens/clicks, CSV report) so the operator isn't surprised. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|---|---|---|
| apps | ||
| docs | ||
| erpnext | ||
| patches | ||
| scripts | ||
| services | ||
| .gitignore | ||
| README.md | ||
Gigafibre FSM
Gigafibre FSM is the operations platform for Gigafibre (consumer brand of TARGO Internet), a fiber ISP in Quebec. It replaces a legacy PHP/MariaDB billing system with ERPNext v16 + Vue 3/Quasar apps for ops, dispatch, field service, and customer self-service.
Repository Structure
gigafibre-fsm/
apps/
ops/ Targo Ops -- main operations PWA (Vue 3 / Quasar v2)
field/ Targo Field -- mobile app for technicians
client/ Gigafibre Portal -- customer self-service
website/ www.gigafibre.ca -- marketing site (React / Vite / Tailwind)
portal/ Customer portal deploy configs
services/
targo-hub/ Node.js API gateway (ERPNext, GenieACS, Twilio, Traccar)
modem-bridge/ SNMP/TR-069 bridge for CPE diagnostics
legacy-db/ Legacy MariaDB read-only access
docuseal/ Document signing service
erpnext/ Custom doctype setup scripts (setup_fsm_doctypes.py)
scripts/
migration/ 51 Python scripts for legacy-to-ERPNext data migration
bulk_submit.py, fix_ple_*.py/sh -- PostgreSQL patches, bulk ops
docs/ Architecture, infrastructure, migration, strategy docs
docker/ Docker compose fragments
patches/ ERPNext patches
Architecture
Internet
|
96.125.196.67 (Proxmox VM, Ubuntu 24.04, Docker)
|
Traefik v2.11 (TLS via Let's Encrypt)
|
+----------+----------+----------+----------+----------+
| | | | | |
ERPNext Ops PWA Authentik n8n Website DocuSeal
erp. erp. auth. n8n. www. docs.
gigafibre gigafibre targo.ca giga giga gigafibre
.ca .ca/ops/ id.giga fibre fibre .ca
fibre.ca .ca .ca
|
targo-hub (API gateway, msg.gigafibre.ca)
|
+----------+----------+----------+----------+
| | | | |
GenieACS Twilio Mailjet Stripe Traccar
(TR-069) (SMS) (email) ($) (GPS)
|
modem-bridge (SNMP / TR-069 deep-dive for TP-Link)
Services & Dependencies
| Service | URL | Stack | Purpose |
|---|---|---|---|
| ERPNext | erp.gigafibre.ca | Frappe v16, PostgreSQL | ERP / billing / ticketing — Source of Truth |
| Ops SPA | erp.gigafibre.ca/ops/ | Vue 3, Quasar v2, Pinia | Internal operations app (dispatch, clients, settings) |
| targo-hub | msg.gigafibre.ca | Node.js 20, Express | API gateway: SMS, SSE, AI, OAuth admin, Stripe webhooks, Traccar proxy |
| modem-bridge | internal | Node.js, Playwright | TR-181 deep-dive for TP-Link XX230v / Deco mesh |
| Authentik (staff) | auth.targo.ca | Python, PostgreSQL | SSO for ops + n8n + Gitea + ERPNext OAuth provider |
| Authentik (clients) | id.gigafibre.ca | Python, PostgreSQL | SSO for customer-facing portals |
| n8n | n8n.gigafibre.ca | Node.js | Workflow automation (campaigns, SMS, email) |
| Traefik | — | Go | Reverse proxy, TLS, forwardAuth middleware |
| Website | www.gigafibre.ca | React, Vite, Tailwind | Marketing site + address API |
| DocuSeal | sign.gigafibre.ca | Ruby on Rails | Contract e-signature |
| GenieACS | (external) | Node.js, MongoDB | TR-069 ACS for ONT/router fleet |
| Traccar | (external) | Java | GPS tracking for techs |
ERPNext Custom Doctypes
| 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, RADIUS) |
| Dispatch Job | DJ-##### | Work orders with equipment, materials, checklist, photos, signature |
| Dispatch Technician | DT-##### | Tech profiles with GPS (Traccar), skills, color coding |
| Dispatch Tag | -- | Skill/service/region tags with levels (Fibre, TV, Telephonie, etc.) |
Key Custom Fields
| Doctype | Custom Fields |
|---|---|
| Customer | legacy_account_id, legacy_customer_id, ppa_enabled, stripe_id |
| Item | legacy_product_id, download_speed, upload_speed, olt_profile |
| Subscription | radius_user, radius_pwd, legacy_service_id |
| Issue | legacy_ticket_id, assigned_staff, issue_type, is_important, service_location |
Tech Stack
Frontend: Vue 3, Quasar v2, Pinia, Vite, Mapbox GL JS Backend: ERPNext v16 / Frappe (Python), PostgreSQL, Node.js (targo-hub) Infra: Docker, Traefik v2.11, Authentik SSO, Proxmox Integrations: Twilio (SMS), Mailjet (email), Stripe (payments), Traccar (GPS), GenieACS (TR-069), Gemini 2.5 Flash via targo-hub (vision/OCR — see docs/features/vision-ocr.md)
Data Volumes (migrated from legacy)
| Entity | Volume |
|---|---|
| Customers | 6,667 (active + terminated) |
| Subscriptions | 21,876 (with RADIUS credentials) |
| Sales Invoices | 115,000+ |
| Payments | 99,000+ (with invoice references) |
| Tickets (Issues) | 242,000+ (parent/child hierarchy) |
| Ticket Messages | 784,000+ |
| Devices | 7,600+ (ONT, router, TV box) |
| Service Locations | ~17,000 |
Development
# Ops app
cd apps/ops && npm install && npx quasar dev
# Website
cd apps/website && npm install && npm run dev
# targo-hub
cd services/targo-hub && npm install && npm run dev
# Deploy ops to production
cd apps/ops && bash deploy.sh
Auth Pattern
Two parallel Authentik instances — not a migration in progress:
auth.targo.ca— staff-facing. Protects/ops/, n8n, Gitea, the hub admin endpoints. Also acts as the OAuth provider for ERPNext sign-in. Lives on the prod box at/opt/authentik(managed by Targo's IT team).id.gigafibre.ca— customer-facing. Protects the client portal. Lives at/opt/authentik-clienton the prod box.
Staff apps go through Traefik forwardAuth → Authentik outpost → cookie. The ops SPA reads X-Authentik-Email from the proxied header to identify the user, then maps Authentik groups to the in-app capability set (useUserGroups.js). All ERPNext API calls from targo-hub use Authorization: token <ERP_SERVICE_TOKEN> (Bearer from .env).
New users are added via ops Settings → Utilisateurs → "Inviter" which hits POST /auth/users on the hub. The hub creates the Authentik user, sets a temporary password, emails it via Mailjet, and creates the matching ERPNext System User in one round-trip. See docs/SETUP.md §6.
Documentation
Start at docs/README.md — it indexes every doc with a "I want to…" intent table. Quick map:
| Area | Entry point |
|---|---|
| Plan & live module URLs | docs/roadmap.md |
| System architecture (services, Docker, SSO) | docs/architecture/overview.md |
| ERPNext data model + customer flows | docs/architecture/data-model.md |
| Frontend patterns (Vue/Quasar/Pinia) | docs/architecture/app-design.md |
| Billing, Stripe, invoices | docs/features/billing-payments.md |
| CPE / modems / ONTs / TR-069 | docs/features/cpe-management.md |
| Scanner / OCR / Gemini pipeline | docs/features/vision-ocr.md |
| Agent flows (Flow Template) | docs/features/flow-editor.md |
| Wizard SKU vs legacy audit | docs/reference/erpnext-item-diff.md |
| Historical snapshots & migration logs | docs/archive/ |