- EquipmentDetail: collapsible node groups (clients grouped by mesh node) - Signal strength as RSSI % (0-255 per 802.11-2020) with 10-tone color scale - Management IP clickable link to device web GUI (/superadmin/) - Fibre status compact top bar (status + Rx/Tx power when available) - targo-hub: WAN IP detection across all VLAN interfaces - targo-hub: full WiFi client count (direct + EasyMesh mesh repeaters) - targo-hub: /devices/:id/hosts endpoint with client-to-node mapping - ClientsPage: start empty, load only on search (no auto-load all) - nginx: dynamic ollama resolver (won't crash if ollama is down) - Cleanup: remove unused BillingKPIs.vue and TagInput.vue - New docs and migration scripts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
68 lines
3.5 KiB
Markdown
68 lines
3.5 KiB
Markdown
# Gigafibre FSM — Design Guidelines
|
|
|
|
This document outlines the standard design principles and conventions for adding new features and modules to the Gigafibre FSM (Field Service Management) application. Adhering to these guidelines ensures scalability, maintainability, and highly efficient AI-assisted development (by keeping context windows small and token usage low).
|
|
|
|
## 1. Modular Architecture (Feature-Sliced Design)
|
|
|
|
To avoid a monolithic `src/` folder that overwhelms both developers and AI tools, organize code by **feature** rather than strictly by technical type.
|
|
|
|
**Do Not Do This (Technical Grouping):**
|
|
```text
|
|
src/
|
|
components/ (contains dispatch, inventory, and customer components all mixed together)
|
|
store/ (one massive pinia store for everything)
|
|
api/ (one 2000-line api.js file)
|
|
```
|
|
|
|
**Do This (Feature Grouping):**
|
|
```text
|
|
src/
|
|
features/
|
|
dispatch/
|
|
components/
|
|
store.ts
|
|
api.ts
|
|
types.ts
|
|
equipment/
|
|
components/
|
|
store.ts
|
|
api.ts
|
|
types.ts
|
|
shared/
|
|
ui/ (generic buttons, dialogs)
|
|
utils/
|
|
```
|
|
*Why?* When you need AI to build a new dispatch feature, you only need to feed it the `features/dispatch/` folder, drastically reducing token usage and hallucination.
|
|
|
|
## 2. API & ERPNext Abstraction
|
|
|
|
Never make raw API calls (`axios.get`) directly inside a Vue component.
|
|
* All ERPNext interactions must go through a dedicated API service file (`features/{module}/api.ts`).
|
|
* **Rule:** Vue components should only dispatch actions (via Pinia) or call cleanly abstracted service functions. They should not care about Frappe endpoints or REST wrappers.
|
|
|
|
## 3. UI Component Standardization (Quasar)
|
|
|
|
* **Composition API:** Use Vue 3 `<script setup>` syntax universally. Avoid Options API entirely.
|
|
* **Component Size Limit:** If a `.vue` file exceeds **250 lines**, it must be split. Extract complex tables, modal dialogs, or forms into their own sub-components.
|
|
* **Dumb vs. Smart Components:**
|
|
* *Smart Components (Pages):* Handle Pinia state, fetch data from the API, and pass variables down.
|
|
* *Dumb Components (UI elements):* Only accept `props` and emit `events`. They do not fetch their own data.
|
|
|
|
## 4. State Management (Pinia)
|
|
|
|
* Use one Pinia store per domain/module (e.g., `useDispatchStore`, `useEquipmentStore`).
|
|
* **Do not store UI state in Pinia** (like "isTheSidebarOpen"). Pinia is for caching ERPNext data locally (Jobs, Technicians, Inventory). Use local `ref()` for UI toggles.
|
|
|
|
## 5. Standardizing Frappe/ERPNext Backend Additions
|
|
|
|
When creating a new custom Doctype or Python module in ERPNext for the FSM:
|
|
1. **Naming Convention:** Prefix system-specific Doctypes with logical boundaries if needed, but rely on standard Frappe naming (e.g., `Dispatch Job`, `Service Location`).
|
|
2. **Controller Logic:** Keep Python hooks small. If a `before_save` hook exceeds 50 lines, abstract the logic into a separate Python utility file.
|
|
3. **API Endpoints:** Use `@frappe.whitelist()` cleanly. Validate permissions explicitly inside the whitelisted function before returning data to the Vue app.
|
|
|
|
## 6. AI & Token Context Optimization
|
|
|
|
To ensure AI (Claude/Gemini) can easily understand and edit this project in the future:
|
|
* **Avoid "God Objects":** Keep configurations, massive constant arrays, or lookup dictionaries in separate `constants.ts` files so they don't bloat the context window of standard logical files.
|
|
* **Strict Typing:** Use TypeScript interfaces (`types.ts`) aggressively. If the AI can read your interfaces, it immediately understands your entire data model without needing to look at your database backend.
|