From beb6ddc5e5f6e07fa4be3ed89bd535f3c4e4eb7c Mon Sep 17 00:00:00 2001 From: louispaulb Date: Wed, 22 Apr 2026 11:51:33 -0400 Subject: [PATCH] docs: reorganize into architecture/features/reference/archive folders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All docs moved with git mv so --follow preserves history. Flattens the single-folder layout into goal-oriented folders and adds a README.md index at every level. - docs/README.md — new landing page with "I want to…" intent table - docs/architecture/ — overview, data-model, app-design - docs/features/ — billing-payments, cpe-management, vision-ocr, flow-editor - docs/reference/ — erpnext-item-diff, legacy-wizard/ - docs/archive/ — HANDOFF-2026-04-18, MIGRATION, status-snapshots/ - docs/assets/ — pptx sources, build scripts (fixed hardcoded path) - roadmap.md gains a "Modules in production" section with clickable URLs for every ops/tech/portal route and admin surface - Phase 4 (Customer Portal) flipped to "Largely Shipped" based on audit of services/targo-hub/lib/payments.js (16 endpoints, webhook, PPA cron, Klarna BNPL all live) - Archive files get an "ARCHIVED" banner so stale links inside them don't mislead readers Code comments + nginx configs rewritten to use new doc paths. Root README.md documentation table replaced with intent-oriented index. Co-Authored-By: Claude Opus 4.7 --- README.md | 25 ++- apps/field/infra/nginx.conf | 2 +- apps/field/src/api/ocr.js | 2 +- apps/ops/infra/nginx.conf | 2 +- apps/ops/src/components/flow-editor/index.js | 4 +- apps/ops/src/composables/useScanner.js | 2 +- apps/ops/src/data/wizard-constants.js | 4 +- .../src/modules/tech/pages/TechDevicePage.vue | 2 +- .../src/modules/tech/pages/TechScanPage.vue | 4 +- apps/ops/src/stores/offline.js | 2 +- docs/README.md | 76 ++++++++ docs/ROADMAP.md | 111 ----------- docs/architecture/README.md | 12 ++ .../app-design.md} | 0 .../data-model.md} | 0 .../overview.md} | 2 +- .../HANDOFF-2026-04-18.md} | 6 +- docs/archive/README.md | 26 +++ .../status-snapshots/2026-04-18.md} | 9 +- .../status-snapshots/2026-04-18b.md} | 6 +- .../status-snapshots/2026-04-19.md} | 6 +- docs/archive/status-snapshots/README.md | 19 ++ .../Gigafibre-Billing-Handoff.pptx | Bin docs/{ => assets}/Gigafibre-FSM-Features.pptx | Bin docs/{ => assets}/build-billing-pptx.js | 0 docs/{ => assets}/build-pptx.js | 3 +- docs/{ => assets}/package-lock.json | 0 docs/{ => assets}/package.json | 0 docs/features/README.md | 14 ++ .../billing-payments.md} | 5 +- .../cpe-management.md} | 0 .../flow-editor.md} | 8 +- .../vision-ocr.md} | 8 +- docs/reference/README.md | 11 ++ .../erpnext-item-diff.md} | 0 .../legacy-wizard/account_wizard.php | 0 .../legacy-wizard/account_wizard_ajax.php | 0 .../legacy-wizard/tele_wizard_package.php | 0 .../legacy-wizard/tele_wizard_subs.php | 0 docs/roadmap.md | 182 ++++++++++++++++++ services/targo-hub/lib/flow-runtime.js | 2 +- 41 files changed, 402 insertions(+), 153 deletions(-) create mode 100644 docs/README.md delete mode 100644 docs/ROADMAP.md create mode 100644 docs/architecture/README.md rename docs/{APP_DESIGN_GUIDELINES.md => architecture/app-design.md} (100%) rename docs/{DATA_AND_FLOWS.md => architecture/data-model.md} (100%) rename docs/{ARCHITECTURE.md => architecture/overview.md} (98%) rename docs/{HANDOFF.md => archive/HANDOFF-2026-04-18.md} (92%) create mode 100644 docs/archive/README.md rename docs/{STATUS_2026-04-18.md => archive/status-snapshots/2026-04-18.md} (96%) rename docs/{STATUS_2026-04-18b.md => archive/status-snapshots/2026-04-18b.md} (96%) rename docs/{STATUS_2026-04-19.md => archive/status-snapshots/2026-04-19.md} (94%) create mode 100644 docs/archive/status-snapshots/README.md rename docs/{ => assets}/Gigafibre-Billing-Handoff.pptx (100%) rename docs/{ => assets}/Gigafibre-FSM-Features.pptx (100%) rename docs/{ => assets}/build-billing-pptx.js (100%) rename docs/{ => assets}/build-pptx.js (99%) rename docs/{ => assets}/package-lock.json (100%) rename docs/{ => assets}/package.json (100%) create mode 100644 docs/features/README.md rename docs/{BILLING_AND_PAYMENTS.md => features/billing-payments.md} (99%) rename docs/{CPE_MANAGEMENT.md => features/cpe-management.md} (100%) rename docs/{FLOW_EDITOR_ARCHITECTURE.md => features/flow-editor.md} (99%) rename docs/{VISION_AND_OCR.md => features/vision-ocr.md} (98%) create mode 100644 docs/reference/README.md rename docs/{ERPNEXT_ITEM_DIFF_VS_LEGACY.md => reference/erpnext-item-diff.md} (100%) rename docs/{ => reference}/legacy-wizard/account_wizard.php (100%) rename docs/{ => reference}/legacy-wizard/account_wizard_ajax.php (100%) rename docs/{ => reference}/legacy-wizard/tele_wizard_package.php (100%) rename docs/{ => reference}/legacy-wizard/tele_wizard_subs.php (100%) create mode 100644 docs/roadmap.md diff --git a/README.md b/README.md index 201e37a..204accb 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ GenieACS Twilio Traccar modem-bridge **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/VISION_AND_OCR.md](docs/VISION_AND_OCR.md)) +**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](docs/features/vision-ocr.md)) ## Data Volumes (migrated from legacy) @@ -128,11 +128,18 @@ Authentik SSO protects staff apps via Traefik `forwardAuth`. The ops app reads ` ## Documentation -| Document | Content | -|----------|---------| -| [ARCHITECTURE.md](docs/ARCHITECTURE.md) | Ecosystem overview, remote Docker infrastructure, platform strategy | -| [DATA_AND_FLOWS.md](docs/DATA_AND_FLOWS.md) | ERPNext data models, atomic order creation, customer flows | -| [CPE_MANAGEMENT.md](docs/CPE_MANAGEMENT.md) | Hardware management, XX230v diagnostics, TR-069/TR-369 | -| [APP_DESIGN_GUIDELINES.md](docs/APP_DESIGN_GUIDELINES.md) | Frontend framework architecture rules, UI/UX Wizard guidelines | -| [ROADMAP.md](docs/ROADMAP.md) | Implementation phases and current remote transition tasks | -| [archive/](docs/archive/) | Completed legacy migration analyses and accounting audits | +Start at **[docs/README.md](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](docs/roadmap.md) | +| System architecture (services, Docker, SSO) | [docs/architecture/overview.md](docs/architecture/overview.md) | +| ERPNext data model + customer flows | [docs/architecture/data-model.md](docs/architecture/data-model.md) | +| Frontend patterns (Vue/Quasar/Pinia) | [docs/architecture/app-design.md](docs/architecture/app-design.md) | +| Billing, Stripe, invoices | [docs/features/billing-payments.md](docs/features/billing-payments.md) | +| CPE / modems / ONTs / TR-069 | [docs/features/cpe-management.md](docs/features/cpe-management.md) | +| Scanner / OCR / Gemini pipeline | [docs/features/vision-ocr.md](docs/features/vision-ocr.md) | +| Agent flows (Flow Template) | [docs/features/flow-editor.md](docs/features/flow-editor.md) | +| Wizard SKU vs legacy audit | [docs/reference/erpnext-item-diff.md](docs/reference/erpnext-item-diff.md) | +| Historical snapshots & migration logs | [docs/archive/](docs/archive/) | diff --git a/apps/field/infra/nginx.conf b/apps/field/infra/nginx.conf index e7d17d7..37b4d40 100644 --- a/apps/field/infra/nginx.conf +++ b/apps/field/infra/nginx.conf @@ -18,7 +18,7 @@ server { # NOTE: Ollama Vision proxy removed 2026-04-22 — all invoice OCR and # barcode/equipment scans now go directly to targo-hub (Gemini 2.5 Flash). - # See docs/VISION_AND_OCR.md. + # See docs/features/vision-ocr.md. # Targo Hub API proxy — vision, devices, etc. location /hub/ { diff --git a/apps/field/src/api/ocr.js b/apps/field/src/api/ocr.js index 5f90e7a..0e9734a 100644 --- a/apps/field/src/api/ocr.js +++ b/apps/field/src/api/ocr.js @@ -7,7 +7,7 @@ * vision model behind the hub. * * NOTE: apps/field is being folded into apps/ops under /j (see - * docs/ARCHITECTURE.md §"Legacy Retirement Plan"). During the transition + * docs/architecture/overview.md §"Legacy Retirement Plan"). During the transition * we keep this file in sync with apps/ops/src/api/ocr.js so no surprises * when code moves over. */ diff --git a/apps/ops/infra/nginx.conf b/apps/ops/infra/nginx.conf index 52b04e3..75258fd 100644 --- a/apps/ops/infra/nginx.conf +++ b/apps/ops/infra/nginx.conf @@ -21,7 +21,7 @@ server { # NOTE: Ollama Vision proxy removed 2026-04-22 — invoice OCR and all # barcode/equipment scans now go directly to targo-hub (Gemini 2.5 Flash). - # See docs/VISION_AND_OCR.md. The hub handles CORS + rate-limit, so no + # See docs/features/vision-ocr.md. The hub handles CORS + rate-limit, so no # nginx pass-through is needed here. # SPA fallback — all routes serve index.html diff --git a/apps/ops/src/components/flow-editor/index.js b/apps/ops/src/components/flow-editor/index.js index 1732aa6..ad3d308 100644 --- a/apps/ops/src/components/flow-editor/index.js +++ b/apps/ops/src/components/flow-editor/index.js @@ -6,8 +6,8 @@ * * * - * See FLOW_EDITOR_ARCHITECTURE.md in /docs/ for the full data model and - * runtime contract. + * See docs/features/flow-editor.md for the full data model and runtime + * contract. */ export { default as FlowEditor } from './FlowEditor.vue' diff --git a/apps/ops/src/composables/useScanner.js b/apps/ops/src/composables/useScanner.js index e1beb6b..aa34408 100644 --- a/apps/ops/src/composables/useScanner.js +++ b/apps/ops/src/composables/useScanner.js @@ -25,7 +25,7 @@ * Merged from apps/ops/src/composables/useScanner.js (which had the * equipment-label branch) and apps/field/src/composables/useScanner.js * (which had the resilient timeout + offline queue). See - * docs/ARCHITECTURE.md §"Legacy Retirement Plan" — field is being folded + * docs/architecture/overview.md §"Legacy Retirement Plan" — field is being folded * into ops at /j and must not lose offline capability in the process. * * @param {object} options diff --git a/apps/ops/src/data/wizard-constants.js b/apps/ops/src/data/wizard-constants.js index 1a640aa..be0888b 100644 --- a/apps/ops/src/data/wizard-constants.js +++ b/apps/ops/src/data/wizard-constants.js @@ -183,7 +183,7 @@ export const RESIDENTIAL_PRESETS = [ // Legacy reuse: gestionclient.product.sku = TELEPMENS // "Téléphonie IP, options toutes incluses, Canada et É-U illimité". // Bundle discount (to reach ~10$/mo) is applied manually by the sales - // rep, not auto-generated. See docs/ERPNEXT_ITEM_DIFF_VS_LEGACY.md. + // rep, not auto-generated. See docs/reference/erpnext-item-diff.md. { item_code: 'TELEPMENS', item_name: 'Téléphonie IP illimitée CA/US', rate: 28.95, billing: 'recurring', billing_interval: 'Month', contract_months: 24 }, ], }, @@ -320,7 +320,7 @@ export const REFERRAL_CREDIT_AMOUNT = 50.00 // Combo rebates are applied MANUALLY by the sales rep from the catalog // (legacy RAB2X / RAB3X / RAB4X SKUs, -5 / -10 / -15 $). We intentionally // do NOT auto-insert a combo rebate line — the rep picks the right SKU -// based on the actual bundle. See docs/ERPNEXT_ITEM_DIFF_VS_LEGACY.md. +// based on the actual bundle. See docs/reference/erpnext-item-diff.md. const CAT_ICON_MAP = { Internet: 'wifi', Téléphonie: 'phone', Bundle: 'inventory_2', Équipement: 'router', Frais: 'receipt', Autre: 'category' } export function catIcon (cat) { diff --git a/apps/ops/src/modules/tech/pages/TechDevicePage.vue b/apps/ops/src/modules/tech/pages/TechDevicePage.vue index 0287bc1..eb62047 100644 --- a/apps/ops/src/modules/tech/pages/TechDevicePage.vue +++ b/apps/ops/src/modules/tech/pages/TechDevicePage.vue @@ -15,7 +15,7 @@ ├ Interventions ─────┤ upcoming Dispatch Jobs at this Service Location └ Info OLT ──────────┘ frame/slot/port/ontid if this is an ONT - See docs/VISION_AND_OCR.md §10 for the full relationship map. The data + See docs/features/vision-ocr.md §10 for the full relationship map. The data loads lazily (equipment first, then location + related entities in parallel) — if the network drops halfway, the first card still renders. diff --git a/apps/ops/src/modules/tech/pages/TechScanPage.vue b/apps/ops/src/modules/tech/pages/TechScanPage.vue index a81ac92..7d50e4a 100644 --- a/apps/ops/src/modules/tech/pages/TechScanPage.vue +++ b/apps/ops/src/modules/tech/pages/TechScanPage.vue @@ -5,7 +5,7 @@ label, Gemini reads the serial, and we look it up in ERPNext, optionally auto-linking the equipment to the tech's current Dispatch Job. - ERPNext relationships touched (see docs/VISION_AND_OCR.md §10 for the full + ERPNext relationships touched (see docs/features/vision-ocr.md §10 for the full data-model diagram): Dispatch Job ─► Customer ─► Service Location ◄── Service Equipment @@ -22,7 +22,7 @@ naturally for any downstream ticket view. Ported from apps/field/src/pages/ScanPage.vue during the field→ops - unification (see docs/ARCHITECTURE.md §"Legacy Retirement Plan"). Adapted + unification (see docs/architecture/overview.md §"Legacy Retirement Plan"). Adapted for the ops router: - device-detail route name: 'tech-device' (was 'device' in field) - same query-param contract from TechJobDetailPage.goScan() diff --git a/apps/ops/src/stores/offline.js b/apps/ops/src/stores/offline.js index ba874a9..0462449 100644 --- a/apps/ops/src/stores/offline.js +++ b/apps/ops/src/stores/offline.js @@ -33,7 +33,7 @@ * - `cache-{key}` → generic read cache (used for read-through patterns) * * Ported from apps/field/src/stores/offline.js as part of the field→ops - * unification (see docs/ARCHITECTURE.md §"Legacy Retirement Plan"). + * unification (see docs/architecture/overview.md §"Legacy Retirement Plan"). */ import { defineStore } from 'pinia' diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..c730c5f --- /dev/null +++ b/docs/README.md @@ -0,0 +1,76 @@ +# Gigafibre FSM — Documentation + +> **Start here.** Everything you need to understand the system is one or two +> clicks away. Pick the row that matches why you're here. + +--- + +## Quick nav by intent + +| I want to… | Open | +|---|---| +| **See the plan** — what's shipped, what's queued, with clickable links to every live module | [roadmap.md](roadmap.md) | +| **Understand the system end-to-end** — services, containers, networks, SSO, Traefik routes | [architecture/overview.md](architecture/overview.md) | +| **Build a new feature** — UI patterns, folder layout, router conventions, Pinia, feature-sliced design | [architecture/app-design.md](architecture/app-design.md) | +| **Touch ERPNext data** — doctypes, customer → subscription → equipment → invoice, "Lead to Live" flow | [architecture/data-model.md](architecture/data-model.md) | +| **Work on billing, Stripe, payments** — subscription lifecycle, invoice OCR, payment reconciliation, PPA | [features/billing-payments.md](features/billing-payments.md) | +| **Touch CPE / modems / ONTs** — GenieACS, Oktopus, TR-069 → TR-369 migration, TP-Link XX230v diagnostics | [features/cpe-management.md](features/cpe-management.md) | +| **Build or debug the scanner / OCR** — Gemini vision pipeline, barcode/equipment/invoice endpoints, offline queue, AI_API_KEY rotation | [features/vision-ocr.md](features/vision-ocr.md) | +| **Work on agent flows / automation** — Flow Template model, trigger wiring, step editor, runtime contract | [features/flow-editor.md](features/flow-editor.md) | +| **Audit the wizard's SKU mapping vs legacy** | [reference/erpnext-item-diff.md](reference/erpnext-item-diff.md) | +| **Inspect the legacy PHP wizard** | [reference/legacy-wizard/](reference/legacy-wizard/) | +| **Read a historical status snapshot** | [archive/status-snapshots/](archive/status-snapshots/) | + +--- + +## Folder map + +```text +docs/ +├── README.md ← you are here +├── roadmap.md ← phase tracker + live module URLs +├── architecture/ ← the system itself +│ ├── overview.md (services, Docker, Traefik, SSO, retirement plan) +│ ├── data-model.md (ERPNext doctypes + "Lead to Live") +│ └── app-design.md (Vue/Quasar patterns, feature-sliced layout) +├── features/ ← one doc per business capability +│ ├── billing-payments.md (Stripe, invoices, subscriptions, PPA) +│ ├── cpe-management.md (GenieACS, Oktopus, XX230v) +│ ├── vision-ocr.md (Gemini, scan pipeline, offline queue, keys) +│ └── flow-editor.md (Flow Template, triggers, runtime) +├── reference/ ← lookup material +│ ├── erpnext-item-diff.md (new SKUs vs legacy gestionclient) +│ └── legacy-wizard/ (read-only snapshot of the PHP wizard) +├── assets/ ← PPTX decks, screenshots, generated diagrams +└── archive/ ← frozen docs, do not edit + ├── HANDOFF-2026-04-18.md + ├── MIGRATION.md + ├── LEGACY-ACCOUNTING-ANALYSIS.md + └── status-snapshots/ (dated session reports) +``` + +--- + +## Conventions + +- **Edit in place.** Don't copy-paste a section into a new file — link to it instead. +- **Dated snapshots go to `archive/status-snapshots/`.** Don't create `STATUS_YYYY-MM-DD.md` at the root anymore. +- **Code comments that reference a doc** use the full repo-relative path, e.g. + `// See docs/features/vision-ocr.md §10` — so `grep docs/` still surfaces them if we reorganize again. +- **The root `README.md`** (one level up) is the repo introduction for + non-technical readers; `docs/README.md` (this file) is the engineering index. + +--- + +## What changed on 2026-04-22 + +The docs were flattened out of a single folder into `architecture/`, +`features/`, `reference/`, `archive/`. Every file move used `git mv` so +`git log --follow` still works. The old paths +(`docs/ARCHITECTURE.md`, `docs/VISION_AND_OCR.md`, etc.) no longer exist — if +you land on one of those links from an external bookmark, use the table above +to find the new location. + +The only place old names still appear is inside +`archive/HANDOFF-2026-04-18.md` and `archive/status-snapshots/*.md`, where the +links are intentionally preserved as a frozen historical record. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md deleted file mode 100644 index d2b1ec2..0000000 --- a/docs/ROADMAP.md +++ /dev/null @@ -1,111 +0,0 @@ -# Gigafibre FSM — Roadmap - -> See [STATUS_2026-04-18.md](STATUS_2026-04-18.md) for a full state snapshot and [HANDOFF.md](HANDOFF.md) for the reader's guide. - - -## Phase 1 — Foundation (Done, March 2026) -- [x] ERPNext v16 + PostgreSQL -- [x] Custom FSM doctypes (Service Location, Equipment, Subscription) -- [x] Dispatch doctypes (Job, Technician, Tag with skill levels) -- [x] Dispatch PWA with timeline, drag-drop, Mapbox map -- [x] GPS tracking (Traccar hybrid REST + WebSocket) -- [x] Authentik SSO (forwardAuth) -- [x] ERPNext API proxy (nginx same-origin) -- [x] Legacy migration (6,667 customers, 21K subs, 115K invoices, 242K tickets) - -## Phase 2 — Ops App (Done, March 2026) -- [x] Unified ops PWA (erp.gigafibre.ca/ops/) -- [x] Client list/detail with inline editing (Odoo-style) -- [x] Dispatch module + ticket management -- [x] Equipment tracking with OLT/SNMP diagnostics -- [x] SMS/Email notifications (Twilio + Mailjet) -- [x] Invoice OCR — originally Ollama Vision, migrated to Gemini 2.5 Flash via targo-hub (2026-04-22, no GPU on ops VM). See [VISION_AND_OCR.md](VISION_AND_OCR.md). -- [x] Field tech mobile (/j/, unified into ops app — see Phase 2.7) -- [x] Authentik federation (staff → client SSO) -- [x] Modem-bridge (Playwright headless for TP-Link ONU diagnostics) -- [x] WiFi diagnostic panel (mesh topology, client signal, packet loss) - -## Phase 2.5 — Remote Architecture Transition (Current Focus) -- [x] Deprecate local `frappe_docker` development dependencies -- [x] Consolidate architecture and ecosystem documentation -- [ ] Decouple API/Auth (Token-based auth instead of session for frontend apps) -- [ ] Set up dev proxy (Vite) to bridge local env to remote ERPNext API (bypassing CORS) -- [ ] Establish secure PostgreSQL tunnel for `infra-map-vue` development -- [ ] **Sandboxed outbound comms** (required before any scheduler/webhook/Twilio/Mailjet E2E test) — prevents test runs from reaching real customers while legacy still bills -- [ ] Subscription → Sales Invoice scheduler: keep `pause_scheduler=1` until cutover event. Legacy PHP is authoritative until then. - -## Phase 2.6 — Quotation + DocuSeal (Shipped 2026-04-18) -- [x] DocuSeal container at sign.gigafibre.ca (Docker + Mailjet SMTP) -- [x] Hub routes: `/accept/generate`, `/accept/docuseal-webhook`, `/accept/confirm` -- [x] Quotation custom fields: `custom_docuseal_signing_url`, `custom_docuseal_envelope_id`, `custom_quote_type` -- [x] Billing Frequency Custom Field on Item + Quotation/Sales Invoice/Sales Order Item (fetch_from item_code) -- [x] Print Format "Soumission TARGO" with split Recurring / One-time sections and QR → signing URL -- [x] Wizard flow: ProjectWizard → `/accept/generate` → DocuSeal submission → signed webhook → `acceptQuotation()` -- [ ] Register DocuSeal webhook in UI (Settings → Webhooks, `form.completed` → hub endpoint) — **manual** -- [ ] First end-to-end signed acceptance on a real customer quote - -## Phase 2.7 — Field ↔ Ops unification at /j (In Progress, started 2026-04-22) - -Collapse `apps/field` into `apps/ops/src/modules/tech` so there is one -PWA, one deploy, one auth surface. See [VISION_AND_OCR.md](VISION_AND_OCR.md) -for the scan pipeline this depends on. - -**Phase 1 — scan + device (Shipped 2026-04-22, commit `e50ea88`)** -- [x] Invoice OCR on Gemini 2.5 Flash via hub `/vision/invoice` — ops VM no longer needs a GPU -- [x] Ollama proxy blocks removed from ops + field nginx configs -- [x] Offline store (`apps/ops/src/stores/offline.js`) — mutation queue + vision queue, time-driven retries, idb-keyval persistence -- [x] Unified scanner composable (`useScanner.js`) with Mode A (barcodes, 8s timeout + queue) and Mode B (equipment label, sync) -- [x] TechScanPage at `/j/scan` — camera, 3-tier lookup (serial → barcode → MAC), auto-link to Dispatch Job context, create/link dialogs -- [x] TechDevicePage at `/j/device/:serial` — 7 cards surfacing full ERPNext relationship graph (Equipment, Customer, Location, Subscription, Issues, Dispatch Jobs, OLT) -- [x] Documentation: `docs/VISION_AND_OCR.md` (pipeline, §10 relationship graph, §8.1 secrets/rotation) - -**Phase 2 — PWA hardening** -- [ ] Quasar service worker runtime caching scoped to `/j/*` (stale-while-revalidate for reads, network-first for mutations) -- [ ] Precache the tech route manifest so a cold install with no signal still boots `/j/` - -**Phase 4 — Auth unification** -- [ ] Collapse logout URL to `id.gigafibre.ca` (currently ops points to `auth.targo.ca`) -- [ ] Decide whether `/j/*` stays behind Authentik forwardAuth or moves to magic-link only - -**Phase 5 — Magic-link tech access** -- [ ] Traefik skip Authentik on `/j/{jwt-token}` route -- [ ] targo-hub `/otp/tech-link` — mint short-lived JWT bound to technician + job -- [ ] JWT validation in TechTasksPage → populate tech context without an SSO session -- [ ] SMS delivery of the link (reuse existing Twilio path) - -**Phase 6 — Flow runtime integration** -- [ ] Wire `flow-runtime` to persist pending steps through `offline.queue` so a tech mid-flow survives a dead zone -- [ ] Surface queued flow state in TechTasksPage ("3 actions en attente de sync") - -**Phase 7 — Remove apps/field** -- [ ] `git rm -r apps/field` once `/j/*` has parity and has run in production for ≥2 weeks -- [ ] Remove field build + deploy from CI -- [ ] Redirect `*.field.gigafibre.ca` (if any) → `erp.gigafibre.ca/ops/#/j/` -- [ ] Update `docs/ARCHITECTURE.md` service table (drop field row) - -## Phase 3 — Workflows & Automation (In Progress) -- [ ] Tag technicians with skills (46 techs to tag) -- [ ] Wire auto-dispatch (cost-optimization matching) -- [ ] Issue → Dispatch Job creation -- [ ] Job completion → equipment status + close ticket -- [ ] Equipment swap → inventory log -- [ ] n8n escalation workflows -- [ ] Twilio 10DLC production upgrade -- [ ] SLA tracking - -## Phase 4 — Customer Portal -- [ ] Self-service app (invoices, tickets, equipment) -- [ ] Stripe payments -- [ ] Online appointment booking -- [ ] Real-time tech tracking SMS -- [ ] Legacy password migration (MD5 → PBKDF2) -- [ ] QR code modem → subscriber dashboard - -## Phase 5 — Advanced Features -- [ ] Van stock inventory per tech -- [ ] Revenue analytics (MRR, churn, ARPU) -- [ ] Proactive monitoring (auto-ticketing) -- [ ] Online checkout (e-commerce signup) -- [ ] Marketing segmentation + campaigns -- [ ] Tech performance dashboards -- [ ] Preventive maintenance scheduling diff --git a/docs/architecture/README.md b/docs/architecture/README.md new file mode 100644 index 0000000..5ed4507 --- /dev/null +++ b/docs/architecture/README.md @@ -0,0 +1,12 @@ +# Architecture + +How the pieces fit together. Read [overview.md](overview.md) first unless you +have a specific reason not to. + +| Doc | Read when… | +|---|---| +| [overview.md](overview.md) | You need the full service map — ERPNext, Ops PWA, targo-hub, DocuSeal, Authentik, Traefik, Docker networks, the legacy retirement plan | +| [data-model.md](data-model.md) | You're about to touch ERPNext: Customer, Service Location, Service Subscription, Service Equipment, Sales Invoice, Payment Entry. Also covers the "Lead to Live" customer flow | +| [app-design.md](app-design.md) | You're building frontend. Feature-sliced layout, Vue/Quasar patterns, Pinia, router, theming, Storybook conventions | + +Back to [docs/README.md](../README.md) · [roadmap.md](../roadmap.md) diff --git a/docs/APP_DESIGN_GUIDELINES.md b/docs/architecture/app-design.md similarity index 100% rename from docs/APP_DESIGN_GUIDELINES.md rename to docs/architecture/app-design.md diff --git a/docs/DATA_AND_FLOWS.md b/docs/architecture/data-model.md similarity index 100% rename from docs/DATA_AND_FLOWS.md rename to docs/architecture/data-model.md diff --git a/docs/ARCHITECTURE.md b/docs/architecture/overview.md similarity index 98% rename from docs/ARCHITECTURE.md rename to docs/architecture/overview.md index 9e43a52..2364694 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/architecture/overview.md @@ -77,7 +77,7 @@ Internet - **Model:** Gemini 2.5 Flash (Google) — no local GPU, all inference remote. - **Endpoints (hub):** `/vision/barcodes`, `/vision/equipment`, `/vision/invoice`. - **Why centralized:** ops VM has no GPU, so the legacy Ollama `llama3.2-vision` install was retired. All three frontends (ops, field-as-ops `/j`, future client portal) hit the hub, which enforces JSON `responseSchema` per endpoint. -- **Client-side resilience:** barcode scans use an 8s timeout + IndexedDB retry queue so techs in weak-LTE zones don't lose data. See [VISION_AND_OCR.md](VISION_AND_OCR.md) for the full pipeline. +- **Client-side resilience:** barcode scans use an 8s timeout + IndexedDB retry queue so techs in weak-LTE zones don't lose data. See [../features/vision-ocr.md](../features/vision-ocr.md) for the full pipeline. --- diff --git a/docs/HANDOFF.md b/docs/archive/HANDOFF-2026-04-18.md similarity index 92% rename from docs/HANDOFF.md rename to docs/archive/HANDOFF-2026-04-18.md index 4b5838c..5ed5a0d 100644 --- a/docs/HANDOFF.md +++ b/docs/archive/HANDOFF-2026-04-18.md @@ -1,6 +1,8 @@ -# Gigafibre FSM — Handoff Index +# Gigafibre FSM — Handoff Index (ARCHIVED 2026-04-18) -> **Purpose:** one-page map of every doc in this repo. Pick the path for your role, read in order, stop when you have enough. +> **⚠️ ARCHIVED.** This was the single-page index before the docs were reorganized into folders. Doc paths below are **stale** — use [../README.md](../README.md) for the current index. Kept for historical reference only. + +> **Purpose (at time of writing):** one-page map of every doc in this repo. Pick the path for your role, read in order, stop when you have enough. **Last refreshed:** 2026-04-18 diff --git a/docs/archive/README.md b/docs/archive/README.md new file mode 100644 index 0000000..3d8b6c0 --- /dev/null +++ b/docs/archive/README.md @@ -0,0 +1,26 @@ +# Archive + +> **Do not edit these files.** They're frozen snapshots kept for historical +> context. Internal links inside archived docs still point at the +> pre-reorganization paths (e.g. `ARCHITECTURE.md`) — that's intentional so +> they read as they did at the time. + +For the current state of the system, go back to [docs/README.md](../README.md) +or [roadmap.md](../roadmap.md). + +## Contents + +| File | What it is | +|---|---| +| [HANDOFF-2026-04-18.md](HANDOFF-2026-04-18.md) | The single-page doc index as it stood before the 2026-04-22 reorganization | +| [MIGRATION.md](MIGRATION.md) | Legacy `gestionclient` (MariaDB) → ERPNext migration: table-by-table mapping, completion log | +| [LEGACY-ACCOUNTING-ANALYSIS.md](LEGACY-ACCOUNTING-ANALYSIS.md) | April 2026 audit of the legacy PHP/MariaDB accounting system, informed the migration plan | +| [status-snapshots/](status-snapshots/) | Dated "state of the system" write-ups from individual work sessions | + +## Why these still exist + +Old snapshots capture context that doesn't belong in the evergreen docs: +what someone was worried about on a specific date, what tradeoffs we +considered and rejected, what shipped in a given sprint. When reading, assume +code examples and doc paths have drifted — verify in the current code before +acting on them. diff --git a/docs/STATUS_2026-04-18.md b/docs/archive/status-snapshots/2026-04-18.md similarity index 96% rename from docs/STATUS_2026-04-18.md rename to docs/archive/status-snapshots/2026-04-18.md index 6c1177e..e702cdc 100644 --- a/docs/STATUS_2026-04-18.md +++ b/docs/archive/status-snapshots/2026-04-18.md @@ -1,8 +1,9 @@ -# Gigafibre FSM — Status Snapshot (2026-04-18) +# Gigafibre FSM — Status Snapshot (2026-04-18) — ARCHIVED -> **Audience:** new contributor, stakeholder, or future-me opening this cold. -> **Goal:** be able to hold a coherent conversation about the system in 10 minutes. -> **Companion docs:** [README](../README.md) · [ARCHITECTURE](ARCHITECTURE.md) · [ROADMAP](ROADMAP.md) · [DATA_AND_FLOWS](DATA_AND_FLOWS.md) · [BILLING_AND_PAYMENTS](BILLING_AND_PAYMENTS.md) · [CPE_MANAGEMENT](CPE_MANAGEMENT.md) · [APP_DESIGN_GUIDELINES](APP_DESIGN_GUIDELINES.md) +> **⚠️ ARCHIVED snapshot.** Links below point to the pre-reorganization layout and are stale. For the current state, see [../../roadmap.md](../../roadmap.md). For the live index, see [../../README.md](../../README.md). + +> **Audience (original):** new contributor, stakeholder, or future-me opening this cold. +> **Goal (original):** be able to hold a coherent conversation about the system in 10 minutes. --- diff --git a/docs/STATUS_2026-04-18b.md b/docs/archive/status-snapshots/2026-04-18b.md similarity index 96% rename from docs/STATUS_2026-04-18b.md rename to docs/archive/status-snapshots/2026-04-18b.md index 4d653a6..7ce4573 100644 --- a/docs/STATUS_2026-04-18b.md +++ b/docs/archive/status-snapshots/2026-04-18b.md @@ -1,6 +1,8 @@ -# Status — 2026-04-18 (session 2) +# Status — 2026-04-18 (session 2) — ARCHIVED -> Follow-up to STATUS_2026-04-18.md. This session was the sales-flow sprint. +> **⚠️ ARCHIVED snapshot.** For current state, see [../../roadmap.md](../../roadmap.md). + +> Follow-up to [2026-04-18.md](2026-04-18.md). This session was the sales-flow sprint. ## What changed this session diff --git a/docs/STATUS_2026-04-19.md b/docs/archive/status-snapshots/2026-04-19.md similarity index 94% rename from docs/STATUS_2026-04-19.md rename to docs/archive/status-snapshots/2026-04-19.md index a9e5265..f5fe25f 100644 --- a/docs/STATUS_2026-04-19.md +++ b/docs/archive/status-snapshots/2026-04-19.md @@ -1,6 +1,8 @@ -# Status — 2026-04-19 (wizard legacy-alignment refinement) +# Status — 2026-04-19 (wizard legacy-alignment refinement) — ARCHIVED -> Follow-up to STATUS_2026-04-18b.md. Small session: reviewed the legacy +> **⚠️ ARCHIVED snapshot.** For current state, see [../../roadmap.md](../../roadmap.md). + +> Follow-up to [2026-04-18b.md](2026-04-18b.md). Small session: reviewed the legacy > wizard (`facturation.targo.ca/.../client_wizard`), realized the initial > preset model fought the real workflow, refactored. diff --git a/docs/archive/status-snapshots/README.md b/docs/archive/status-snapshots/README.md new file mode 100644 index 0000000..d1d17bb --- /dev/null +++ b/docs/archive/status-snapshots/README.md @@ -0,0 +1,19 @@ +# Status snapshots + +Dated "state of the system" write-ups. Each captures what shipped, what +changed, and what was queued on that specific date. **Frozen** — do not edit +past snapshots. + +| Date | File | Theme | +|---|---|---| +| 2026-04-18 | [2026-04-18.md](2026-04-18.md) | Foundational 10-min snapshot, TL;DR + architecture refresher | +| 2026-04-18 (session 2) | [2026-04-18b.md](2026-04-18b.md) | Sales-flow sprint | +| 2026-04-19 | [2026-04-19.md](2026-04-19.md) | Wizard legacy-alignment refinement | + +For the live state see [../../roadmap.md](../../roadmap.md). + +## Creating a new snapshot + +- File name: `YYYY-MM-DD.md` (append `b`, `c`, … for multiple sessions per day). +- Link it from the table above when you commit. +- Don't cross-link from evergreen docs — those should point at `roadmap.md` instead. diff --git a/docs/Gigafibre-Billing-Handoff.pptx b/docs/assets/Gigafibre-Billing-Handoff.pptx similarity index 100% rename from docs/Gigafibre-Billing-Handoff.pptx rename to docs/assets/Gigafibre-Billing-Handoff.pptx diff --git a/docs/Gigafibre-FSM-Features.pptx b/docs/assets/Gigafibre-FSM-Features.pptx similarity index 100% rename from docs/Gigafibre-FSM-Features.pptx rename to docs/assets/Gigafibre-FSM-Features.pptx diff --git a/docs/build-billing-pptx.js b/docs/assets/build-billing-pptx.js similarity index 100% rename from docs/build-billing-pptx.js rename to docs/assets/build-billing-pptx.js diff --git a/docs/build-pptx.js b/docs/assets/build-pptx.js similarity index 99% rename from docs/build-pptx.js rename to docs/assets/build-pptx.js index a6b6c05..cb0bce5 100644 --- a/docs/build-pptx.js +++ b/docs/assets/build-pptx.js @@ -482,7 +482,8 @@ async function build() { s.addText("Targo — Avril 2026", { x: 0.8, y: 5.1, w: 9, h: 0.3, fontSize: 10, fontFace: "Calibri", color: C.muted, margin: 0 }); // Write file - await pres.writeFile({ fileName: "/Users/louispaul/Documents/testap/gigafibre-fsm/docs/Gigafibre-FSM-Features.pptx" }); + const path = require("path"); + await pres.writeFile({ fileName: path.join(__dirname, "Gigafibre-FSM-Features.pptx") }); console.log("Presentation created!"); } diff --git a/docs/package-lock.json b/docs/assets/package-lock.json similarity index 100% rename from docs/package-lock.json rename to docs/assets/package-lock.json diff --git a/docs/package.json b/docs/assets/package.json similarity index 100% rename from docs/package.json rename to docs/assets/package.json diff --git a/docs/features/README.md b/docs/features/README.md new file mode 100644 index 0000000..6804a07 --- /dev/null +++ b/docs/features/README.md @@ -0,0 +1,14 @@ +# Features + +One doc per business capability. Each describes the user-facing behaviour, +the ERPNext doctypes touched, the API endpoints involved, and the failure +modes. Open the one that matches the feature you're changing. + +| Doc | Owns | +|---|---| +| [billing-payments.md](billing-payments.md) | Stripe integration (Checkout, Billing Portal, webhook), subscription lifecycle, invoice generation, payment reconciliation, PPA (Plan de paiement automatique), Klarna BNPL | +| [cpe-management.md](cpe-management.md) | CPE fleet: GenieACS (TR-069), Oktopus (TR-369), provisioning, diagnostics, TP-Link XX230v / Deco deep probe, migration plan | +| [vision-ocr.md](vision-ocr.md) | Camera-based scanning via Gemini 2.5 Flash — barcode, equipment label, invoice OCR. Hub endpoints `/vision/*`, `useScanner` composable, offline queue, AI_API_KEY rotation policy, ERPNext relationships triggered by a scan | +| [flow-editor.md](flow-editor.md) | Agent-flows module: Flow Template + Flow Run doctypes, trigger catalogue, step types, runtime contract, UI editor at `/ops/#/agent-flows` | + +Back to [docs/README.md](../README.md) · [roadmap.md](../roadmap.md) diff --git a/docs/BILLING_AND_PAYMENTS.md b/docs/features/billing-payments.md similarity index 99% rename from docs/BILLING_AND_PAYMENTS.md rename to docs/features/billing-payments.md index 049537a..e6f2c78 100644 --- a/docs/BILLING_AND_PAYMENTS.md +++ b/docs/features/billing-payments.md @@ -1,8 +1,9 @@ # Facturation & Paiements — Handoff dev > Référence unique pour toutes les fonctionnalités facture / paiement construites sur -> la stack `erp.gigafibre.ca` + `client.gigafibre.ca` + `ops`. Lisez `ARCHITECTURE.md` -> d'abord pour le contexte réseau/services. +> la stack `erp.gigafibre.ca` + `client.gigafibre.ca` + `ops`. Lisez +> [../architecture/overview.md](../architecture/overview.md) d'abord pour le contexte +> réseau/services. Dernière MàJ : 2026-04-17 diff --git a/docs/CPE_MANAGEMENT.md b/docs/features/cpe-management.md similarity index 100% rename from docs/CPE_MANAGEMENT.md rename to docs/features/cpe-management.md diff --git a/docs/FLOW_EDITOR_ARCHITECTURE.md b/docs/features/flow-editor.md similarity index 99% rename from docs/FLOW_EDITOR_ARCHITECTURE.md rename to docs/features/flow-editor.md index 46a7870..7c7f4e8 100644 --- a/docs/FLOW_EDITOR_ARCHITECTURE.md +++ b/docs/features/flow-editor.md @@ -3,7 +3,8 @@ > Authoritative reference for the Flow Editor subsystem: visual builder in the > Ops PWA, JSON flow-definition language, runtime engine in `targo-hub`, and > the Frappe scheduler that wakes delayed steps. Companion document to -> `ARCHITECTURE.md` and `DATA_AND_FLOWS.md`. +> [../architecture/overview.md](../architecture/overview.md) and +> [../architecture/data-model.md](../architecture/data-model.md). --- @@ -674,5 +675,6 @@ Deploy order (important): --- *Last updated: 2026-04-21. Owners: Targo Platform team -(). See `ROADMAP.md` for upcoming Flow Editor v2 items -(JSONLogic conditions, sub-flows, parallel branches, retry policies).* +(). See [../roadmap.md](../roadmap.md) for upcoming Flow +Editor v2 items (JSONLogic conditions, sub-flows, parallel branches, +retry policies).* diff --git a/docs/VISION_AND_OCR.md b/docs/features/vision-ocr.md similarity index 98% rename from docs/VISION_AND_OCR.md rename to docs/features/vision-ocr.md index d5f7057..23f9feb 100644 --- a/docs/VISION_AND_OCR.md +++ b/docs/features/vision-ocr.md @@ -323,11 +323,13 @@ DevTools, no key in the browser's `Network` tab. ## 9. Related -- [ARCHITECTURE.md](ARCHITECTURE.md) — the full service map this lives in. -- [CPE_MANAGEMENT.md](CPE_MANAGEMENT.md) — how scanned serials flow into +- [../architecture/overview.md](../architecture/overview.md) — the full service map this lives in. +- [cpe-management.md](cpe-management.md) — how scanned serials flow into the TR-069/TR-369 device management plane. -- [APP_DESIGN_GUIDELINES.md](APP_DESIGN_GUIDELINES.md) — frontend +- [../architecture/app-design.md](../architecture/app-design.md) — frontend conventions (Vue 3 Composition API, feature folders). +- [../roadmap.md](../roadmap.md) — Phase 2.7 tracks the ongoing /j tech + unification this pipeline depends on. --- diff --git a/docs/reference/README.md b/docs/reference/README.md new file mode 100644 index 0000000..07cc5ae --- /dev/null +++ b/docs/reference/README.md @@ -0,0 +1,11 @@ +# Reference + +Lookup material. These aren't narratives — open them when you need a specific +fact. + +| Doc | Use when… | +|---|---| +| [erpnext-item-diff.md](erpnext-item-diff.md) | Auditing why a wizard SKU doesn't match a legacy `gestionclient.product` row. Lists every new / reused / semantic-reuse item with rationale | +| [legacy-wizard/](legacy-wizard/) | You need to check what the old PHP wizard at `facturation.targo.ca/.../client_wizard` actually did for a given step. These are read-only snapshots — never edit | + +Back to [docs/README.md](../README.md) · [roadmap.md](../roadmap.md) diff --git a/docs/ERPNEXT_ITEM_DIFF_VS_LEGACY.md b/docs/reference/erpnext-item-diff.md similarity index 100% rename from docs/ERPNEXT_ITEM_DIFF_VS_LEGACY.md rename to docs/reference/erpnext-item-diff.md diff --git a/docs/legacy-wizard/account_wizard.php b/docs/reference/legacy-wizard/account_wizard.php similarity index 100% rename from docs/legacy-wizard/account_wizard.php rename to docs/reference/legacy-wizard/account_wizard.php diff --git a/docs/legacy-wizard/account_wizard_ajax.php b/docs/reference/legacy-wizard/account_wizard_ajax.php similarity index 100% rename from docs/legacy-wizard/account_wizard_ajax.php rename to docs/reference/legacy-wizard/account_wizard_ajax.php diff --git a/docs/legacy-wizard/tele_wizard_package.php b/docs/reference/legacy-wizard/tele_wizard_package.php similarity index 100% rename from docs/legacy-wizard/tele_wizard_package.php rename to docs/reference/legacy-wizard/tele_wizard_package.php diff --git a/docs/legacy-wizard/tele_wizard_subs.php b/docs/reference/legacy-wizard/tele_wizard_subs.php similarity index 100% rename from docs/legacy-wizard/tele_wizard_subs.php rename to docs/reference/legacy-wizard/tele_wizard_subs.php diff --git a/docs/roadmap.md b/docs/roadmap.md new file mode 100644 index 0000000..cdb355b --- /dev/null +++ b/docs/roadmap.md @@ -0,0 +1,182 @@ +# Gigafibre FSM — Roadmap + +> Live phase tracker. For onboarding or architecture context see +> [README.md](README.md). Historical status snapshots live under +> [archive/status-snapshots/](archive/status-snapshots/). + +**Last refreshed:** 2026-04-22 + +--- + +## Modules in production — quick links + +Everything in this table is reachable from a browser today (Authentik +SSO for staff surfaces, Stripe Checkout for customer ones). + +### Ops app — `https://erp.gigafibre.ca/ops/` + +| Module | URL | Purpose | +|---|---|---| +| Dashboard | [/ops/#/](https://erp.gigafibre.ca/ops/#/) | Home | +| Clients | [/ops/#/clients](https://erp.gigafibre.ca/ops/#/clients) | Customer list + detail | +| Dispatch | [/ops/#/dispatch](https://erp.gigafibre.ca/ops/#/dispatch) | Timeline, drag-drop, map | +| Tickets | [/ops/#/tickets](https://erp.gigafibre.ca/ops/#/tickets) | Issue management | +| Équipe | [/ops/#/equipe](https://erp.gigafibre.ca/ops/#/equipe) | Technician directory | +| Rapports | [/ops/#/rapports](https://erp.gigafibre.ca/ops/#/rapports) | Revenu / Ventes / Taxes / AR | +| OCR | [/ops/#/ocr](https://erp.gigafibre.ca/ops/#/ocr) | Invoice OCR (Gemini) | +| Téléphonie | [/ops/#/telephony](https://erp.gigafibre.ca/ops/#/telephony) | PBX + SIP | +| Agent flows | [/ops/#/agent-flows](https://erp.gigafibre.ca/ops/#/agent-flows) | Flow editor | +| Réseau | [/ops/#/network](https://erp.gigafibre.ca/ops/#/network) | GenieACS / OLT / TR-069 | +| Settings | [/ops/#/settings](https://erp.gigafibre.ca/ops/#/settings) | Config | + +### Tech mobile (same app, mobile layout) — `/j/*` + +| Page | URL | Purpose | +|---|---|---| +| Tasks | [/ops/#/j](https://erp.gigafibre.ca/ops/#/j) | Tech's assigned jobs | +| Scan | [/ops/#/j/scan](https://erp.gigafibre.ca/ops/#/j/scan) | Camera scanner, auto-link | +| Device | `/ops/#/j/device/:serial` | Equipment detail + relationships | +| Diagnostic | [/ops/#/j/diagnostic](https://erp.gigafibre.ca/ops/#/j/diagnostic) | ONT/OLT/SNMP probe | + +### Customer portal — `https://portal.gigafibre.ca` + +| Page | URL | Purpose | +|---|---|---| +| Dashboard | [/](https://portal.gigafibre.ca) | Balance + quick actions | +| Account | [/#/me](https://portal.gigafibre.ca/#/me) | Profile + cards (Stripe Billing Portal) | +| Invoices | [/#/invoices](https://portal.gigafibre.ca/#/invoices) | History + pay (Stripe Checkout + Klarna) | +| Tickets | [/#/tickets](https://portal.gigafibre.ca/#/tickets) | Open tickets | +| Messages | [/#/messages](https://portal.gigafibre.ca/#/messages) | SMS / email thread with support | +| Catalog | [/#/catalog](https://portal.gigafibre.ca/#/catalog) | Add-on purchases | + +### Admin surfaces (non-ops) + +| Service | URL | Stack | +|---|---|---| +| ERPNext | [erp.gigafibre.ca](https://erp.gigafibre.ca) | Frappe v16 / PostgreSQL | +| Authentik SSO (staff) | [auth.targo.ca](https://auth.targo.ca) | migrating → id.gigafibre.ca | +| Authentik SSO (clients) | [id.gigafibre.ca](https://id.gigafibre.ca) | Federated from auth.targo.ca | +| DocuSeal | [sign.gigafibre.ca](https://sign.gigafibre.ca) | Contract signing | +| n8n | [n8n.gigafibre.ca](https://n8n.gigafibre.ca) | Workflow automation | +| Oktopus | [oss.gigafibre.ca](https://oss.gigafibre.ca) | TR-369 CPE controller | +| GenieACS | internal `10.5.2.115:7557` | TR-069 NBI | +| Traccar | [tracker.targointernet.com](https://tracker.targointernet.com) | GPS tracking | +| Website | [www.gigafibre.ca](https://www.gigafibre.ca) | Marketing + address lookup | + +--- + +## Phase 1 — Foundation (Done, March 2026) +- [x] ERPNext v16 + PostgreSQL +- [x] Custom FSM doctypes (Service Location, Equipment, Subscription) → see [architecture/data-model.md](architecture/data-model.md) +- [x] Dispatch doctypes (Job, Technician, Tag with skill levels) +- [x] Dispatch PWA with timeline, drag-drop, Mapbox map → [/ops/#/dispatch](https://erp.gigafibre.ca/ops/#/dispatch) +- [x] GPS tracking (Traccar hybrid REST + WebSocket) +- [x] Authentik SSO (forwardAuth) +- [x] ERPNext API proxy (nginx same-origin) +- [x] Legacy migration (6,667 customers, 21K subs, 115K invoices, 242K tickets) + +## Phase 2 — Ops App (Done, March 2026) +- [x] Unified ops PWA → [erp.gigafibre.ca/ops/](https://erp.gigafibre.ca/ops/) +- [x] Client list/detail with inline editing → [/ops/#/clients](https://erp.gigafibre.ca/ops/#/clients) +- [x] Dispatch module + ticket management → [/ops/#/dispatch](https://erp.gigafibre.ca/ops/#/dispatch), [/ops/#/tickets](https://erp.gigafibre.ca/ops/#/tickets) +- [x] Equipment tracking with OLT/SNMP diagnostics → [/ops/#/network](https://erp.gigafibre.ca/ops/#/network) +- [x] SMS/Email notifications (Twilio + Mailjet) +- [x] Invoice OCR — migrated from Ollama Vision to Gemini 2.5 Flash via targo-hub (2026-04-22, no GPU on ops VM). See [features/vision-ocr.md](features/vision-ocr.md) → [/ops/#/ocr](https://erp.gigafibre.ca/ops/#/ocr) +- [x] Field tech mobile → [/ops/#/j](https://erp.gigafibre.ca/ops/#/j) (unified into ops app, see Phase 2.7) +- [x] Authentik federation (staff → client SSO) +- [x] Modem-bridge (Playwright headless for TP-Link ONU diagnostics) +- [x] WiFi diagnostic panel (mesh topology, client signal, packet loss) + +## Phase 2.5 — Remote Architecture Transition (In Progress) +- [x] Deprecate local `frappe_docker` development dependencies +- [x] Consolidate architecture and ecosystem documentation (this reorg, 2026-04-22) +- [ ] Decouple API/Auth (Token-based auth instead of session for frontend apps) +- [ ] Set up dev proxy (Vite) to bridge local env to remote ERPNext API (bypassing CORS) +- [ ] Establish secure PostgreSQL tunnel for `infra-map-vue` development +- [ ] **Sandboxed outbound comms** (required before any scheduler/webhook/Twilio/Mailjet E2E test) — prevents test runs from reaching real customers while legacy still bills +- [ ] Subscription → Sales Invoice scheduler: keep `pause_scheduler=1` until cutover event. Legacy PHP is authoritative until then. + +## Phase 2.6 — Quotation + DocuSeal (Shipped 2026-04-18) +- [x] DocuSeal container → [sign.gigafibre.ca](https://sign.gigafibre.ca) +- [x] Hub routes: `/accept/generate`, `/accept/docuseal-webhook`, `/accept/confirm` +- [x] Quotation custom fields: `custom_docuseal_signing_url`, `custom_docuseal_envelope_id`, `custom_quote_type` +- [x] Billing Frequency Custom Field on Item + Quotation/Sales Invoice/Sales Order Item (fetch_from item_code) +- [x] Print Format "Soumission TARGO" with split Recurring / One-time sections and QR → signing URL +- [x] Wizard flow: ProjectWizard → `/accept/generate` → DocuSeal submission → signed webhook → `acceptQuotation()` +- [ ] Register DocuSeal webhook in UI (Settings → Webhooks, `form.completed` → hub endpoint) — **manual** +- [ ] First end-to-end signed acceptance on a real customer quote + +## Phase 2.7 — Field ↔ Ops unification at /j (In Progress, started 2026-04-22) + +Collapse `apps/field` into `apps/ops/src/modules/tech` so there is one +PWA, one deploy, one auth surface. See [features/vision-ocr.md](features/vision-ocr.md) +for the scan pipeline this depends on. + +**Step 1 — scan + device (Shipped 2026-04-22, commit `e50ea88`)** +- [x] Invoice OCR on Gemini 2.5 Flash via hub `/vision/invoice` — ops VM no longer needs a GPU +- [x] Ollama proxy blocks removed from ops + field nginx configs +- [x] Offline store (`apps/ops/src/stores/offline.js`) — mutation queue + vision queue, time-driven retries, idb-keyval persistence +- [x] Unified scanner composable (`useScanner.js`) with Mode A (barcodes, 8s timeout + queue) and Mode B (equipment label, sync) +- [x] TechScanPage → [/ops/#/j/scan](https://erp.gigafibre.ca/ops/#/j/scan) — camera, 3-tier lookup (serial → barcode → MAC), auto-link to Dispatch Job context, create/link dialogs +- [x] TechDevicePage at `/j/device/:serial` — 7 cards surfacing full ERPNext relationship graph (Equipment, Customer, Location, Subscription, Issues, Dispatch Jobs, OLT) +- [x] Documentation: [features/vision-ocr.md](features/vision-ocr.md) (pipeline, §10 relationship graph, §8.1 secrets/rotation) + +**Step 2 — PWA hardening** +- [ ] Quasar service worker runtime caching scoped to `/j/*` (stale-while-revalidate for reads, network-first for mutations) +- [ ] Precache the tech route manifest so a cold install with no signal still boots `/j/` + +**Step 3 — Auth unification** +- [ ] Collapse logout URL to `id.gigafibre.ca` (currently ops points to `auth.targo.ca`) +- [ ] Decide whether `/j/*` stays behind Authentik forwardAuth or moves to magic-link only + +**Step 4 — Magic-link tech access** +- [ ] Traefik skip Authentik on `/j/{jwt-token}` route +- [ ] targo-hub `/otp/tech-link` — mint short-lived JWT bound to technician + job +- [ ] JWT validation in TechTasksPage → populate tech context without an SSO session +- [ ] SMS delivery of the link (reuse existing Twilio path) + +**Step 5 — Flow runtime integration** +- [ ] Wire `flow-runtime` to persist pending steps through `offline.queue` so a tech mid-flow survives a dead zone +- [ ] Surface queued flow state in TechTasksPage ("3 actions en attente de sync") + +**Step 6 — Remove apps/field** +- [ ] `git rm -r apps/field` once `/j/*` has parity and has run in production for ≥2 weeks +- [ ] Remove field build + deploy from CI +- [ ] Redirect `*.field.gigafibre.ca` (if any) → `erp.gigafibre.ca/ops/#/j/` +- [ ] Update [architecture/overview.md](architecture/overview.md) service table (drop field row) + +## Phase 3 — Workflows & Automation (In Progress) +- [ ] Tag technicians with skills (46 techs to tag) → [/ops/#/equipe](https://erp.gigafibre.ca/ops/#/equipe) +- [ ] Wire auto-dispatch (cost-optimization matching) +- [ ] Issue → Dispatch Job creation (triggered from [/ops/#/tickets](https://erp.gigafibre.ca/ops/#/tickets)) +- [ ] Job completion → equipment status + close ticket +- [ ] Equipment swap → inventory log +- [x] Flow editor (v1 shipped) → [/ops/#/agent-flows](https://erp.gigafibre.ca/ops/#/agent-flows) — see [features/flow-editor.md](features/flow-editor.md) +- [ ] n8n escalation workflows → [n8n.gigafibre.ca](https://n8n.gigafibre.ca) +- [ ] Twilio 10DLC production upgrade +- [ ] SLA tracking + +## Phase 4 — Customer Portal (Largely Shipped) + +Portal Vue SPA lives at [portal.gigafibre.ca](https://portal.gigafibre.ca). +All 16 `/payments/*` hub endpoints ship; see +[features/billing-payments.md](features/billing-payments.md) for the full flow. + +- [x] Self-service app → [portal.gigafibre.ca](https://portal.gigafibre.ca) (13 pages: Dashboard, Invoices, Account, Tickets, Messages, Catalog, Cart, …) +- [x] Stripe payments → pay-balance, pay-invoice, save-card, Billing Portal, refund, PPA auto-pay cron (daily 06:00 EST). Klarna BNPL supported on invoice payments. +- [x] Webhook handler with signature verification (5-min tolerance) → `/webhook/stripe` +- [x] Payment links via SMS + email (`/payments/send-link`) +- [x] Magic-link redirect after Stripe return (`/payments/return` → portal) +- [ ] Online appointment booking +- [ ] Real-time tech tracking SMS +- [ ] Legacy password migration (MD5 → PBKDF2) — MD5-hashed passwords in legacy need forced reset via OTP email/SMS +- [ ] QR code on modem → subscriber dashboard (`msg.gigafibre.ca/q/{mac}`) + +## Phase 5 — Advanced Features +- [ ] Van stock inventory per tech +- [ ] Revenue analytics (MRR, churn, ARPU) → extend [/ops/#/rapports](https://erp.gigafibre.ca/ops/#/rapports) +- [ ] Proactive monitoring (auto-ticketing) +- [ ] Online checkout (e-commerce signup via [www.gigafibre.ca](https://www.gigafibre.ca)) +- [ ] Marketing segmentation + campaigns +- [ ] Tech performance dashboards +- [ ] Preventive maintenance scheduling diff --git a/services/targo-hub/lib/flow-runtime.js b/services/targo-hub/lib/flow-runtime.js index 658e7c9..f336af8 100644 --- a/services/targo-hub/lib/flow-runtime.js +++ b/services/targo-hub/lib/flow-runtime.js @@ -26,7 +26,7 @@ * { [stepId]: { status: 'pending|running|done|failed|scheduled|skipped', * started_at, completed_at, result, error, retry_count } } * - * See docs/FLOW_EDITOR_ARCHITECTURE.md for full data model + trigger wiring. + * See docs/features/flow-editor.md for full data model + trigger wiring. */ const { log, erpFetch } = require('./helpers')