- 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>
188 lines
8.5 KiB
Markdown
188 lines
8.5 KiB
Markdown
# Changelog
|
|
|
|
## 2026-03-31 — Ops App: Inline Editing, Notifications, Search
|
|
|
|
### Inline Editing (Odoo-style)
|
|
- **InlineField component** (`apps/ops/src/components/shared/InlineField.vue`) — universal dblclick-to-edit supporting text, number, textarea, select, date types
|
|
- **useInlineEdit composable** (`apps/ops/src/composables/useInlineEdit.js`) — save logic wrapping `updateDoc()` with error handling + Quasar Notify
|
|
- **ClientDetailPage** — all Service Location fields now inline-editable (address, city, postal code, contact, OLT port, network ID, connection type)
|
|
- **CustomerHeader** — customer_name editable via InlineField
|
|
- **DetailModal** — Issue (status, priority, type, subject), Equipment (all fields), Invoice (remarks) — all inline-editable
|
|
- **TicketsPage** — status and priority columns editable from table with badge display slot
|
|
- **ClientsPage** — customer name, type, group editable directly from the list table
|
|
|
|
### Search Enhancement
|
|
- Client search now matches `customer_name`, `name` (account ID like CUST-4), and `legacy_customer_id` (like LPB4) using `or_filters`
|
|
- Legacy ID column added to clients table
|
|
- `listDocs` and `countDocs` API helpers updated to support `or_filters` parameter
|
|
|
|
### SMS/Email Notifications
|
|
- **ContactCard** — expanding notification panel with SMS/Email toggle, recipient selector, subject (email), message body, character count
|
|
- **Server Scripts** — `send_sms_notification` and `send_email_notification` API endpoints (normalize phone, route via n8n, log Comment on Customer)
|
|
- **sms.js** — new API wrapper for SMS endpoint
|
|
- Routes through n8n webhooks: `/webhook/sms-send` (Twilio) and `/webhook/email-send` (Mailjet)
|
|
|
|
### Ticket Replies
|
|
- Reply textarea + send button in DetailModal Issue view
|
|
- Creates `Communication` doc in ERPNext with proper linking
|
|
|
|
### Bug Fixes
|
|
- Fixed blur race condition in InlineField (80ms debounce + `committing` flag prevents double API calls)
|
|
- Fixed CustomerHeader double-save (InlineField saves directly, removed redundant parent emit)
|
|
- Fixed deploy script — was rsync'ing locally instead of SSH to production server
|
|
|
|
### Authentik Federation
|
|
- OAuth2 Source created on id.gigafibre.ca linking to auth.targo.ca as OIDC provider
|
|
- `email_link` user matching mode — staff from auth.targo.ca can log in to id.gigafibre.ca
|
|
- Customers register directly on id.gigafibre.ca (not added to auth.targo.ca)
|
|
|
|
---
|
|
|
|
## 2026-03-30 — Ops App V2, Field Tech App, OCR
|
|
|
|
### Ops App
|
|
- **ClientDetailPage** — full customer view with locations, subscriptions, equipment, tickets, invoices, payments, notes
|
|
- **Dispatch module** — integrated into ops app at `/dispatch` route (replaces standalone dispatch app)
|
|
- **Equipment page** — searchable list of all Service Equipment
|
|
- **OCR page** — Ollama Vision integration for invoice scanning
|
|
|
|
### Field Tech App (`apps/field/`)
|
|
- Barcode scanner (camera API), task list, diagnostics, offline support
|
|
- PWA with Workbox for field use
|
|
|
|
### Infrastructure
|
|
- Ops app served at `erp.gigafibre.ca/ops/` via nginx proxy with API token injection
|
|
- Ollama Vision routed through ops-frontend nginx proxy
|
|
|
|
---
|
|
|
|
## 2026-03-29 — Migration Phases 5-7
|
|
|
|
### Phase 5: Opening Balance + AR Analysis
|
|
- Outstanding invoice analysis and reconciliation
|
|
|
|
### Phase 6: Tickets
|
|
- **242,618 tickets** migrated as ERPNext Issues with parent/child hierarchy
|
|
- Issue types mapped: Reparation Fibre, Installation Fibre, Telephonie, Television, etc.
|
|
- Assigned staff and opened_by_staff mapped from legacy numeric IDs to ERPNext User emails
|
|
- **784,290 ticket messages** imported as Communications
|
|
|
|
### Phase 7: Staff + Memos
|
|
- **45 ERPNext Users** created from legacy staff table
|
|
- **29,000 customer memos** imported as Comments with real creation dates
|
|
- **99,000 payments** imported with invoice references and mode mapping (PPA, cheque, credit card)
|
|
|
|
---
|
|
|
|
## 2026-03-28 — Migration Phases 1-4
|
|
|
|
### Phase 1 : Données maîtres
|
|
|
|
### Infrastructure
|
|
- **Frappe Assistant Core v2.3.3** installé sur ERPNext — MCP connecté à Claude Code
|
|
- **Connexion MariaDB legacy** (10.100.80.100) → ERPNext (10.100.5.61) établie
|
|
- GRANT SELECT pour `facturation@10.100.5.61` sur `gestionclient`
|
|
- **2 Workspaces** créés sur ERPNext Desk : Dispatch (icône tool) + Gigafibre FSM (icône map)
|
|
|
|
### Item Groups (34)
|
|
Hiérarchie créée sous 3 parents :
|
|
- **Services** (16) : Mensualités fibre/sans fil/télévision, Téléphonie, IP Fixe, Hébergement, Nom de domaine, Location P2P, Internet camping, Cloud, Site internet, Services info, Location espace, Garantie, Téléchargement supp, Honoraires
|
|
- **Products** (8) : Installation fibre/sans fil/télé, Équipement fibre/sans fil, Quincaillerie, Pièces info, Technicien
|
|
- **Frais et ajustements** (10) : Intérêts, Activation, Frais divers taxables, Créances, Recouvrement, Transport, Impression, Infographie, SPECIAL
|
|
|
|
### Items (833)
|
|
- **833/833** produits importés via script Python (`/tmp/import_items.py`)
|
|
- Source : `gestionclient.product` → ERPNext `Item`
|
|
- Mapping : SKU → item_code, price → standard_rate, category → item_group
|
|
- Items sans services actifs ET inactive dans legacy → `disabled=1`
|
|
- Script exécuté depuis le container `erpnext-backend-1`
|
|
|
|
### Custom Fields créés
|
|
|
|
**Sur Item (section "ISP Settings")** :
|
|
| Fieldname | Type | Description |
|
|
|-----------|------|-------------|
|
|
| legacy_product_id | Int | ID dans gestionclient.product |
|
|
| download_speed | Int | Vitesse download en Kbps |
|
|
| upload_speed | Int | Vitesse upload en Kbps |
|
|
| quota_day_gb | Float | Quota jour en GB |
|
|
| quota_night_gb | Float | Quota nuit en GB |
|
|
| fibre_lineprofile | Data | Profil OLT ligne |
|
|
| fibre_serviceprofile | Data | Profil OLT service |
|
|
|
|
**Sur Customer (section "Legacy Settings")** :
|
|
| Fieldname | Type | Description |
|
|
|-----------|------|-------------|
|
|
| legacy_account_id | Int | ID dans gestionclient.account |
|
|
| legacy_customer_id | Data | customer_id legacy (ex: DR2, LOUIS4502470070) |
|
|
| ppa_enabled | Check | Paiement pré-autorisé AccesD actif |
|
|
| stripe_id | Data | Stripe customer ID |
|
|
|
|
**Sur Subscription (section "ISP Settings")** :
|
|
| Fieldname | Type | Description |
|
|
|-----------|------|-------------|
|
|
| radius_user | Data | Utilisateur RADIUS (ex: tci44166) |
|
|
| radius_pwd | Data | Mot de passe RADIUS |
|
|
| legacy_service_id | Int | ID dans gestionclient.service |
|
|
|
|
### Données mises à jour
|
|
- **833** Items : legacy_product_id peuplé
|
|
- **98** Items : vitesses download/upload + quotas en GB + profils fibre
|
|
|
|
---
|
|
|
|
## 2026-03-28 — Phase 2 : Customers, Contacts, Addresses
|
|
|
|
### Méthode
|
|
- **Direct PostgreSQL** (`migrate_direct.py`) au lieu de l'API REST
|
|
- Temps d'exécution : ~30 secondes vs plusieurs heures via API REST
|
|
- PostgreSQL `max_connections` augmenté à **200** pour supporter la charge
|
|
|
|
### Résultats
|
|
- **6,667 Customers** importés (comptes actifs + suspendus)
|
|
- **~6,600 Contacts** créés avec email, téléphone, cellulaire
|
|
- **~6,700 Addresses** créées avec géolocalisation (latitude/longitude)
|
|
- Liens Customer ↔ Contact ↔ Address établis
|
|
|
|
---
|
|
|
|
## 2026-03-28 — Phase 3 : Tax Templates + Subscription Plans
|
|
|
|
### Tax Templates
|
|
- **QC TPS 5%** — Sales Taxes and Charges Template
|
|
- **QC TVQ 9.975%** — Sales Taxes and Charges Template
|
|
|
|
### Subscription Plans
|
|
- **92 Subscription Plans** créés à partir des produits actifs avec services
|
|
- Mapping : Item → Subscription Plan (billing_interval=Month, currency=CAD)
|
|
|
|
---
|
|
|
|
## 2026-03-28 — Phase 4 : Subscriptions
|
|
|
|
### Résultats
|
|
- **21,876 Subscriptions** importées avec données RADIUS (radius_user, radius_pwd)
|
|
- legacy_service_id peuplé pour chaque Subscription
|
|
- Lien Customer ↔ Subscription Plan établi
|
|
|
|
### ATTENTION CRITIQUE
|
|
- **Le scheduler ERPNext est PAUSED** — les Subscriptions ne génèrent PAS de factures automatiquement
|
|
- **NE PAS réactiver le scheduler sans instruction explicite** — la réactivation déclencherait la facturation automatique pour les 21,876 abonnements
|
|
|
|
---
|
|
|
|
## Connexions et accès
|
|
|
|
| Système | Accès | Méthode |
|
|
|---------|-------|---------|
|
|
| ERPNext API | `token $ERP_SERVICE_TOKEN` (see server .env) | REST API |
|
|
| ERPNext MCP | Frappe Assistant Core | StreamableHTTP |
|
|
| Legacy MariaDB | `facturation@10.100.80.100` | pymysql depuis container ERPNext |
|
|
| Legacy SSH | `root@96.125.192.252` (clé SSH copiée) | SSH |
|
|
| DB server SSH | `root@10.100.80.100` via sshpass depuis legacy | SSH |
|
|
|
|
## Scripts de migration
|
|
- `/tmp/import_items.py` — Import 833 produits → Items
|
|
- `/tmp/update_items_speeds.py` — MAJ vitesses/quotas sur Items
|
|
- Tous exécutés depuis `erpnext-backend-1` container
|