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>
This commit is contained in:
parent
e2b775c077
commit
ec385c99d0
161
ARCHITECTURE.md
Normal file
161
ARCHITECTURE.md
Normal file
|
|
@ -0,0 +1,161 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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
|
||||||
|
```
|
||||||
Loading…
Reference in New Issue
Block a user