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)
| Field | Notes |
| TJE service tag REQ | Master key SVC-#####, encoded into the tag. Own range — never collide with Jetter ID. |
| Engine make+model REQ | e.g. Honda GX390. |
| Engine serial REQ | Scannable if barcoded. |
| Drive train REQ | Gearbox RTI 131/RTI 123 + clutch or belt. |
| Drive notes opt | Belt size, clutch model, oddities. |
| Pump serial opt | If visible. |
| Customer REQ | Link to Clients tab — don't re-type. |
| Vehicle rego REQ | On the record, not the machine — gap 7.1. |
4.2 Service / install record (both paths, every visit)
| Field | Notes |
| Machine key REQ | Jetter ID or SVC-##### — decides the folder. |
| Record type REQ | Install · service · repair · warranty. |
| Date REQ | dd/mm/yyyy — mind date-format bug #35. |
| Technician REQ | Auto-capture from signed-in account. |
| Vehicle rego REQ | Point-in-time; current = latest record. |
| Work performed REQ | Checklist + notes. |
| Parts used opt | Barcode line items → MYOB (§10). |
| Layout config install | Saved tray/van plan (JSON + image). |
| Photos opt | In machine folder. Quota — gap 7.8. |
| Next service due opt | Drives 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 TJE1 | Lives in MYOB |
| Client name & details | read, not duplicated |
| Machine / Jetter ID | — |
| Parts used (scanned barcodes) | matched to item + priced |
| Notes — what was done to the machine | — |
| Pricing, GST, totals | owns 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.