The Jetters Edge
The Jetters Edge
Dashboard
—
In stock
—
In service
—
Orders
—
TBD
Machine
Engine
Pump
Test data
Belt tension — pre
Pre-start checklist
Oils & covers
Remote & safety
Post checklist
Oils & shutdown
Leaks & bolts
Belt tension — post
Vehicle / Trailer unit
Sign off
✅
Birth certificate saved
Jetter # registered in Google Sheets
📄
Saved to Google Drive → Machines →
Select a machine to sell
Loading…
Customer
Start typing to search existing clients — or add a new one
New client
Auto-calculated
✅
Sale complete
—
Generating documents…
✉️ Email customer
New build order
✅
Order saved
Saved to Orders tab in Google Sheets
— Pending — Total
Loading orders…
TJE1
Service · Full design record

Services & Installs — complete record

The full design session, numbered: brief as given, resolved design, data model, workflow, every flagged gap, integration findings, my notes, and the decisions still open. Captured before any code is written.

Claude's note Logic gap (with fix) Open / unresolved

1 Session context & method

1.1Carried context. Persistent memory loads each session: pending tasks, coding rules, master reference pointer, sales-doc notes.
1.2Working method. Read → Think → Ask → Write. Memory first, code read, plan explained, confirmation, then code/back-test/export.
1.3Status. Design / "Ask" stage. Nothing here is built yet.
Claude's note

Treated as a brainstorm that touches the app, so known architecture (Google Sheets/Drive/Docs, Cloudflare Worker, vanilla-JS PWA) was assumed rather than asked. Integration claims verified against MYOB & Microsoft developer docs (June 2026).

2 The brief, as given

Install, brand and service jetters on clients' vehicles. Captured close to verbatim so original intent is never lost.

2.1 Service — technician record

2.1.1Jetter has a TJE number. Simple history record saved in the same folder as the birth certificate — traceable, every service readable in history.
2.1.2Jetter has no TJE number. New database; a TJE service tag attached (sticker, plate, QR, NFC). Data points: tag, engine make+model+serial, drivetrain (RTI 131 / RTI 123; clutch or belt + notes), pump serial (opt), vehicle rego, customer.

2.2 Install temp plate

2.2.1Ute body tray. Drag-drop items for install reference — jetter, double-stacker, single & mini reel, toolboxes — "are they already foxy" and clearance dimensions, as a reference of the outlay.
2.2.2Van installs. Same items, but shows 2 side doors + rear barn door or 2 wing doors — to convey what the customer wants.

2.3 Installer logic (as described)

Installer grabs the machine allocated to this customer (recently sold), carries out the work, fills a document including the vehicle reg + details — saved in the same jetter-ID folder, with photos and notes. Once created, installer clicks "install completed" and the jetter moves Recently Sold → Archive.

2.4 Integration questions

2.4.1Microsoft Calendar — book in services; is it possible?
2.4.2MYOB — create invoices from the data sheets; scan barcodes for service items and MYOB pulls the data?

3 The two service paths (resolved)

3.1Path A — built by TJE (has TJE ID). Service record → same Drive folder as the birth cert, keyed by zero-padded Jetter ID. One folder = full lifecycle. Lookup reuses openSalesDoc().
3.2Path B — external / service-only (no TJE ID). New row in an External Machines tab. A physical TJE service tag = master key SVC-#####; machine gets its own Drive folder. (Backlog #23 realised.)

4 Key data points

4.1 Path B — external machine identity (one-time)

FieldNotes
TJE service tag REQMaster key SVC-#####, encoded into the tag. Own range — never collide with Jetter ID.
Engine make+model REQe.g. Honda GX390.
Engine serial REQScannable if barcoded.
Drive train REQGearbox RTI 131/RTI 123 + clutch or belt.
Drive notes optBelt size, clutch model, oddities.
Pump serial optIf visible.
Customer REQLink to Clients tab — don't re-type.
Vehicle rego REQOn the record, not the machine — gap 7.1.

4.2 Service / install record (both paths, every visit)

FieldNotes
Machine key REQJetter ID or SVC-##### — decides the folder.
Record type REQInstall · service · repair · warranty.
Date REQdd/mm/yyyy — mind date-format bug #35.
Technician REQAuto-capture from signed-in account.
Vehicle rego REQPoint-in-time; current = latest record.
Work performed REQChecklist + notes.
Parts used optBarcode line items → MYOB (§10).
Layout config installSaved tray/van plan (JSON + image).
Photos optIn machine folder. Quota — gap 7.8.
Next service due optDrives calendar booking (§9).

5 Install layout planner

5.1Concept. Pre-install reference of the outlay + saved spec of what the customer signed off. Working proof-of-concept built (drag/drop, ute↔van, barn↔wing).
5.2Ute tray — open tray canvas with cab marker.
5.3Van — adds 2 side doors + rear: barn door or 2 wing doors.
5.4Items — jetter, double-stacker, single reel, mini reel, toolbox.
5.5Touch note. Pointer events, not HTML5 drag (dead on phones).

5.6 · partial Clearance dimensions only half-built

Grid reference (≈200 mm squares) exists, but no real dimension entry or clearance readout. Currently cosmetic.

To add: editable dimensions + clearance readout reporting real measurements.

5.7 · unresolved "are they already foxy"

Undecoded, left out. Best guess: a flag for already fitted / customer-owned vs supplied & installed by TJE. If so, a missing data point.

Needs: your confirmation of what "foxy" means.

6 Installer workflow & status

6.1 Status lifecycle

In Stock→ Recently Sold→ Install Completed→ Archive
6.2External (SVC) machines sit outside this lifecycle. Never "sold" — they accumulate service records. Don't force them through it.
6.3.1Open the machine allocated to this customer from Recently Sold (Path B: scan/create the SVC tag).
6.3.2Optional: use the tray/van planner; check clearances.
6.3.3Do the work; fill the record — rego, linked customer, work, scanned parts, photos, notes, saved layout.
6.3.4Tap Install Completed — writes the PDF and flips status, one action.
6.3.5Machine → Archive; history preserved. Later service re-opens against the same ID, stays archived.

6.4 · unresolved "optional lockbox paths"

Undecoded. Treated as optional branch/fallback paths (delivered-no-install, external-machine, missing-tag). Confirm if you meant otherwise.

7 Gaps & logic errors — my input

Where the plan as described will bite later. Each numbered, each with a fix.

7.1 Vehicle rego is on the machine, but shouldn't be

A jetter moves between vehicles; as a permanent attribute, rego goes stale silently.

Fix: store rego per record; current vehicle is derived from the latest.

7.2 "Document exists → archive" is too implicit

A saved-but-incomplete draft would wrongly archive; two actions are conflated.

Fix: Install Completed is the single explicit action that generates the PDF and flips status.

7.3 Sold-but-never-installed machines get stuck

Customer collects / self-installs → no doc → stuck in Recently Sold forever.

Fix: add "Delivered — no install required" that archives directly.

7.4 Status should be an explicit field, not inferred

Today derived from Date Sold; new transitions make that fragile.

Fix: one Status column (In Stock / Sold / Installed / Archived). Sheet is A–AB (28 cols) — new vs reused column?

7.5 NFC won't work with your scanner — and excludes iPhones

html5-qrcode (#38) reads QR + barcodes via camera only. NFC = Web NFC, Chrome-Android only, no iOS.

Fix: QR is primary (encodes SVC-#####); NFC optional, Android-only.

7.6 Service PDFs collide on filename

Birth certs use {jetterId}.pdf; repeated services overwrite.

Fix: {id}-SVC-{yyyymmdd}-{n}.pdf so they coexist as a history.

7.7 Customer data could fragment

Free-text Path B customers drift from the Clients tab.

Fix: always link to a Clients record; create if new.

7.8 Photos eat Drive quota — on whose account?

uploadPDF() uses the user's own token/quota, bypassing the Worker.

Fix: decide the storage account up front (the Workspace shared drive); compress photos client-side.

7.9 SVC / Jetter ID namespace collision

Both are folder keys; overlapping ranges clash.

Fix: distinct schemes — SVC-##### vs zero-padded Jetter ID.

7.10 Save the layout, not just show it

The plan is a spec the customer agreed to; unsaved = no record of promised vs delivered.

Fix: save layout config (JSON + image) on the install record.

7.11 Technician identity

Free-text tech names cause typos, break reporting.

Fix: auto-capture from the signed-in Google account.

8 Data collection & handling

8.1Sheets — existing: Birthing Information (+ new Status col); Clients (single customer source).
8.2Sheets — new: External Machines tab (Path B identity); Services tab (one row per visit — queryable log).
8.3Drive: one folder per machine (Jetter ID or SVC-#####) — birth cert, sale docs, service PDFs, photos.
8.4Worker: sheetsRequest()/driveRequest() via service account; PDF + photo upload via user token.
8.5New Worker routes: Graph proxy + MYOB proxy — server-side OAuth + token caching (same shape as Google).

9 Calendar & booking

Decided — 30 June 2026

Booking lives natively inside TJE1, not synced from Microsoft/Outlook Calendar. A new Services sheet tab (date, time, Jetter ID, customer, job type, status, notes) plus a simple booking/list view in the app. A booked job is born already linked to the Jetter ID — service history is automatic, not bolted on afterward. No second OAuth system, no sync conflicts between two calendars.

✓ 9.1 — Microsoft Graph is fully doable, but not the chosen path

Outlook / M365 calendars are scriptable via Microsoft Graph — create/read/update/delete events, read free/busy, over REST + OAuth 2.0 (Entra ID). Kept here as reference in case Outlook visibility is wanted later.

9.2 POST /me/events Scope Calendars.ReadWrite Auth OAuth 2.0 Token ~1 hr → refresh
// 9.3  POST https://graph.microsoft.com/v1.0/me/events
{
  "subject": "Service — Jetter 00421 @ Smith Plumbing",
  "start": { "dateTime":"2026-07-14T08:00:00", "timeZone":"AUS Eastern Standard Time" },
  "end":   { "dateTime":"2026-07-14T09:30:00", "timeZone":"AUS Eastern Standard Time" },
  "location": { "displayName":"On site — customer vehicle" }
}
9.4.1Register an app in Entra ID; https redirect URI. The Worker owns token exchange + refresh — never the front end.
9.4.2Delegated access = signed-in user's calendar; Application access = unattended bookings (admin consent).
9.4.3If ever needed: one-direction-out only (TJE1 → Outlook for visibility), never pulling bookings in. Keeps TJE1 as the single source of truth.

10 MYOB invoicing

Decided — 30 June 2026

TJE1 stays history-only — it never knows prices. Client name/details pulled from TJE1's own Client tab. Parts get scanned on the mobile device during the service and saved against the job. MYOB pulls the part numbers from the job record and builds the invoice itself, using its own pricing and tax codes. TJE1's job is the record of what was done and what was used — not the money.

✓ 10.1 — Simpler than originally scoped, and avoids price duplication

This flips the original plan (TJE1 pushes fully-priced invoice lines) into MYOB pulling a plain parts list from a completed job. No UnitPrice, no TaxCode, no pricing logic of any kind lives in TJE1 — that stays entirely MYOB's responsibility, which is where it already lives today.

Lives in TJE1Lives in MYOB
Client name & detailsread, not duplicated
Machine / Jetter ID—
Parts used (scanned barcodes)matched to item + priced
Notes — what was done to the machine—
Pricing, GST, totalsowns this entirely
Open Q pull vs push Auth OAuth 2.0 File cloud-hosted
10.2.1Open question: does MYOB pull on demand ("go get job X"), or does TJE1 push a plain job summary once marked complete? Either works — changes who initiates and where the integration logic lives.
10.2.2Barcode / part number is still the link — MYOB matches it to its own item catalogue for pricing. TJE1 just needs to capture the part number scanned, nothing about its price.
10.2.3Customer match — TJE1's client record needs a way to resolve to the matching MYOB customer (by name, or a stored MYOB customer reference) so the invoice lands on the right account.
10.2.4OAuth + March 2025 scope change — register at developer.myob.com; post-12-Mar-2025 keys use new scopes.
Claude's note

This is a meaningfully simpler integration than the original push-priced-invoice plan — TJE1 never needs item UIDs, tax code UIDs, or pricing logic at all. It just needs to be a clean, reliable record of parts + notes per job, and let MYOB do what MYOB is already good at.

11 Audit — what got captured

11.1 Captured cleanly

11.1.1Both paths, the SVC tag and External Machines tab.
11.1.2All Path B identity data points.
11.1.3Tag mediums; tray + van planner with all items and door configs.
11.1.4Full installer logic + lifecycle; calendar + MYOB; all "point out" asks.

11.2 Not captured cleanly — needs you

11.2.1"foxy" (2.2.1) — undecoded; left out. See 5.7.
11.2.2Clearance dimensions (2.2.1) — only a grid reference. See 5.6.
11.2.3"optional lockbox paths" — undecoded; treated as branch paths. See 6.4.
11.2.4Gaps 7.9–7.11 originally buried; now promoted to their own flags.

12 Decisions before any code

Per the workflow, nothing is built until these are settled.

12.1SvcID numbering — ✅ DECIDED: Pre-stamped metal tags numbered 1, 2, 3... displayed as SVC-001, SVC-002 etc. Manually allocated — office/mechanic reads tag, types number. Job record ID renamed to "Job ID" to avoid confusion with machine SvcID.
12.2Status field — ✅ DECIDED: Booked → In progress → Waiting parts → Quoted → Completed.
12.3Tag medium — QR primary confirmed? NFC in or out?
12.4Calendar — ✅ DECIDED: Native TJE1 calendar, not Microsoft Graph. Booking lives in TJE1, one-way-out to Outlook if needed later.
12.5Photos / docs home — personal account or Workspace shared drive?
12.6MYOB scope — ✅ DECIDED: TJE1 stays history-only, no pricing. Parts scanned as part numbers only. MYOB pulls part numbers from job record and builds invoice itself. TJE1 never knows prices.
12.7Decode "foxy" (5.7).
12.8Decode "lockbox paths" (6.4).
12.9Clearance dimensions — ✅ DECIDED: Added to Install template (H/W in mm).

13 SvcID system — external machine workflow

Decided — 1 July 2026

Pre-stamped metal tags (physical) numbered sequentially 1, 2, 3... affixed to external/non-TJE machines when they come in for service. Displayed in app as SVC-001, SVC-002 etc.

13.1Two machine types coexist — TJE-built machines use Jetter ID (#01607). External machines use SvcID (SVC-001). Both appear in the same booking search and services calendar. Both link to the same Clients tab and Services tab.
13.2External Machines tab — new Sheet tab. Columns: SvcID, Company, Rego, Engine Serial (primary identifier), Engine Brand/Model, Jetter Name/Type, Pump Serial, Notes, Date created.
13.3Engine serial is the most important field for external machines — it's the primary identifier. Rego is secondary. Jetter name/type can be filled later by the mechanic when the machine arrives.
13.4Mixed fleet companies — e.g. Smith Plumbing has #01607 (TJE-built) AND SVC-004 (external). Both appear when searching "Smith Plumbing" in the booking form.

Step-by-step workflow

Step 1Customer calls in — office searches by company name, rego, engine serial, or SvcID. If machine not found → "Add external machine" flow appears inline.
Step 2Quick machine create — enter SvcID (from metal tag), rego, engine serial, company. Jetter name/type optional. Saves to External Machines tab.
Step 3Booking saved — Services tab stores SvcID as the machine ID (same column as Jetter ID). Status = Booked.
Step 4Machine arrives — mechanic opens job from calendar. Technician Data Sheet pre-filled with what's known. Mechanic adds full details: engine serial confirmed, pump serial, full service work.
Step 5Record complete — External Machines tab now has a permanent record for SVC-001 linked to this company. Future bookings: search by SvcID, rego, engine serial, or company name — machine found instantly.
Naming note

The job record ID in Services tab col A is renamed Job ID (was "SVC ID") to avoid confusion with the machine's SvcID tag number.

TJE1 · Services & Installs — full design record · Draft v0.1 · Sydney UTC+10
Integration facts verified against MYOB & Microsoft developer docs, June 2026. Payloads illustrative.
Loading clients…
New client
App preferences
Default seller — ›
Engine warranty 3 years ›
Pump warranty 4 years ›
Font size
Dashboard columns
In stock columns — ›
Recently sold columns — ›
Sales card layout
Sales card fields Top & bottom rows ›
Appearance
Colour theme Navy & Orange ›
Services setup
Services sheet columns Design & create ›
Mechanics
Max jobs per day
Leave & unavailability — ›
Reference data
Machines — ›
Pumps — ›
Engines — ›
Locations — ›
Header row — extra fields
#ID · Jetter name always shown. Toggle extras below.
Bottom tags
Step 1 — Find customer or machine
Step 2 — Which machine?
+ New customer
+ External machine (SvcID tag)
Step 3 — Job type
Step 4 — Schedule
Dave's schedule
Guidance slots — tap to snap
Available gaps
⚠ This time overlaps with an existing booking — pick a different slot
Step 5 — Booking notes
Job type
Timing
Problem
Checklist
Work carried out
Parts used
Observations
Status
Sign off
Ute body layout
Tap to mark machine position, cable routes, water points
Install checklist
Clearance dimensions
Notes
Sign off

Mark when a mechanic is unavailable. They won't appear as bookable on that day.

Add leave / unavailability
Upcoming leave

Design the Services sheet columns. Reorder by dragging. When done, tap "Create tab" to write the header row to Google Sheets.

In stock — choose columns
Recently sold — choose columns
App preferences
Loading…
Scan barcode
Point camera at barcode or QR code
Rego
Customer
Phone
Job type
Time
Mechanic
Engine
Status
Notes
Settings PIN

Adjust how the calendar works. Changes take effect immediately.

Working hours & snap points
Job type default durations
Capacity
Mechanics
Known issues list

These appear as checkboxes on the booking form.

Colour theme
· ·
Double-click to book