OSS-BSS-Field-Dispatch/ARCHITECTURE.md
louispaulb fd66c21c2e Add ARCHITECTURE.md — full project documentation
Covers: stack, directory structure, routes, ERPNext doctypes,
PostgreSQL extensions, features, component communication,
planned modules, and deploy instructions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 14:10:06 -04:00

6.8 KiB

OSS/BSS Field Dispatch — Architecture

Overview

Field service dispatch & scheduling PWA integrated with ERPNext (Frappe) on PostgreSQL. Manages technicians, work orders, route optimization, and team scheduling.

Stack

Layer Technology Notes
Frontend Vue 3 + Quasar (PWA) <script setup>, Composition API, custom dark UI
State Pinia Single dispatch store
Backend ERPNext / Frappe REST API, Server Scripts, Doctypes
Database PostgreSQL Native (no MariaDB), pg_trgm + unaccent for address search
Maps Mapbox GL JS Route directions, optimization API, dark style
Deploy Docker Frappe containers, PWA served as static assets
Git Gitea git.targo.ca/louis/OSS-BSS-Field-Dispatch

Directory Structure

src/
├── api/                              # ERPNext REST calls
│   ├── dispatch.js                   # Jobs, techs, tags CRUD + createTag
│   ├── auth.js                       # Login, CSRF token
│   ├── service-request.js            # Open service requests
│   ├── booking.js                    # Booking API
│   ├── contractor.js                 # Contractor API
│   └── settings.js                   # Dispatch Settings (single doctype)
│
├── components/                       # Reusable UI widgets
│   └── TagInput.vue                  # Auto-suggest tag input with inline creation
│
├── composables/                      # Shared logic (no UI)
│   ├── useHelpers.js                 # Pure utils: dates, formatting, icons, colors
│   ├── useScheduler.js               # Timeline algorithm: pinned anchors + auto-flow
│   ├── useMap.js                     # Mapbox: init, markers, routes, geo-fix, drag
│   ├── useBottomPanel.js             # Unassigned list: grouping, multi-select, criteria
│   └── useUndo.js                    # Undo stack (30 actions max)
│
├── modules/
│   └── dispatch/
│       └── components/               # Dispatch-specific components
│           ├── TimelineRow.vue       # Single tech row with job blocks
│           ├── BottomPanel.vue       # Unassigned jobs table (date-grouped)
│           ├── JobEditModal.vue      # Edit job modal (double-click)
│           └── WoCreateModal.vue     # Create work order modal
│
├── pages/                            # Route-level pages
│   ├── DispatchV2Page.vue            # Main dispatch board (active)
│   ├── DispatchPage.vue              # Legacy v1 (deprecated)
│   ├── MobilePage.vue                # Mobile tech view
│   ├── AdminPage.vue                 # Admin settings
│   ├── BookingPage.vue               # Customer booking
│   ├── TechBidPage.vue              # Tech bidding
│   └── ContractorPage.vue           # Contractor view
│
├── stores/
│   ├── dispatch.js                   # Jobs, technicians, tags state
│   └── auth.js                       # Auth state
│
├── config/
│   └── erpnext.js                    # MAPBOX_TOKEN, TECH_COLORS, BASE_URL
│
└── router/index.js                   # Vue Router (hash mode)

Routes

Path Page Description
/#/dispatch2 DispatchV2Page Main app — scheduling board
/#/ DispatchPage Legacy v1
/#/mobile MobilePage Mobile tech interface
/#/admin AdminPage Settings
/#/booking BookingPage Customer booking
/#/bid TechBidPage Tech bidding
/#/contractor ContractorPage Contractor portal

ERPNext Doctypes

Doctype Type Fields
Dispatch Job Document subject, address, lat/lng, priority, duration_h, status, assigned_tech, scheduled_date, start_time, end_date, note
Dispatch Technician Document technician_id, full_name, status, user, lat/lng
Dispatch Tag Document label, color, category (Skill/Service/Region/Equipment/Custom)
Dispatch Job Assistant Child Table (of Job) tech_id, tech_name, duration_h, note, pinned
Dispatch Tag Link Child Table tag (Link → Dispatch Tag)
Dispatch Settings Single API keys, Mapbox token

PostgreSQL Extensions

Extension Usage
pg_trgm Trigram fuzzy search on rqa_addresses.search_text
unaccent Accent-insensitive search (riviere = rivière)

Address table: rqa_addresses — 5.2M Quebec civic addresses with pre-computed search_text column, GIN trigram index.

Key Features

Scheduling

  • Day view: Timeline with pinned time anchors + auto-flow for unpinned jobs
  • Week view: Calendar grid with job chips, lasso multi-select
  • Month view: Overview with tech avatars per day
  • Travel time: Mapbox Directions API, displayed between job blocks

Dispatch

  • Auto-distribute: Ordered criteria (urgency → load balance → proximity → skills)
  • Multi-drag: Select multiple jobs in bottom panel, drag to tech or batch-assign
  • Route optimization: Nearest-neighbor + Mapbox Optimization API (TSP)

Job Management

  • Assistants: Multi-tech jobs with floating/pinned modes
  • Tags/Skills: Auto-suggest input with inline tag creation
  • Address autocomplete: Server Script → PostgreSQL with pg_trgm
  • Undo: Ctrl+Z for assign/unassign/optimize/distribute (30-deep stack)

UI

  • Sidebar: Icon strip with flyout panels on hover
  • Single click: Right panel with job details
  • Double click: Edit modal (title, address, note, duration, priority, tags)
  • Context menu: Right-click on jobs and techs
  • Lasso: Rectangle selection in day and week views
  • Map: Mapbox dark style, route visualization, geo-fix by click

Component Communication

DispatchV2Page (orchestrator)
  │
  ├── provide/inject ──→ shared state (store, colors, functions)
  │
  ├── TimelineRow ←──── events (job-click, drag, resize, ctx)
  ├── BottomPanel ←──── events (select, batch-assign, drag)
  ├── JobEditModal ←─── v-model + confirm event
  ├── WoCreateModal ←── v-model + confirm event
  └── TagInput ←──────── v-model + create event

Planned Modules

Module Directory Status
Dispatch modules/dispatch/ Active
Timesheet modules/timesheet/ Planned
HRMS modules/hrms/ Planned
ERP modules/erp/ Planned
OSS/BSS modules/oss-bss/ Planned

Deploy

# Build + deploy to ERPNext Docker
./deploy.sh

# Dev server (hot reload, proxies API to ERPNext)
npx @quasar/cli dev -m pwa
# → http://localhost:9000/#/dispatch2