From 1fa1a4209223b476be2dd1d19e4cf2879ea77952 Mon Sep 17 00:00:00 2001 From: Howard Enos Date: Fri, 10 Jul 2026 16:46:22 -0700 Subject: [PATCH] syncro: Phase-1b breadth findings (leads/vendors/products/PO/worksheets) Live-tested the remaining write resources on Howard Test. Recorded: - wrapped response shapes (.lead.id/.vendor.id/.product.id/.purchase_order.id/ .po_line_item.id/.worksheet_result.id) added to Verified Response Shapes. - create_po_line_item requires product maintain_stock:true. - worksheet templates live in GET /tickets/settings (.worksheet_templates[]), no standalone endpoint; need a valid worksheet_template_id. - PUT /products requires name+description; leads/vendors/products/POs have NO DELETE (global test records persist -> GUI cleanup). Co-Authored-By: Claude Opus 4.8 (1M context) --- .claude/commands/syncro.md | 6 +++++ .claude/standards/syncro/test-findings.md | 27 +++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/.claude/commands/syncro.md b/.claude/commands/syncro.md index ee82a951..8145d822 100644 --- a/.claude/commands/syncro.md +++ b/.claude/commands/syncro.md @@ -590,6 +590,12 @@ Every endpoint's response shape, verified against the live API. Parse exactly as | Create contract | POST `/contracts` | write OK but body does NOT echo the object | GET `/contracts` + match; never retry on null | | Email invoice | POST `/invoices/{id}/email` | `{"message": "Email sent."}` | **200 even with NO recipient** — verify `customer.email` first | | Email estimate | POST `/estimates/{id}/email` | `{"message": "Email sent"}` | **200 even with NO recipient** — verify `customer.email` first | +| Create lead | POST `/leads` | `{"lead": {...}}` | `.lead.id` | +| Create vendor | POST `/vendors` | `{"vendor": {...}}` | `.vendor.id` — no DELETE (persists) | +| Create/Update product | POST/PUT `/products/{id}` | `{"product": {...}}` | `.product.id` — `name`+`description` required; no DELETE | +| Create PO | POST `/purchase_orders` | `{"purchase_order": {...}}` | `.purchase_order.id` — no DELETE | +| Add PO line | POST `/purchase_orders/{id}/create_po_line_item` | `{"po_line_item": {...}}` | needs product `maintain_stock:true` | +| Create worksheet | POST `/tickets/{id}/worksheet_results` | `{"worksheet_result": {...}}` | `.worksheet_result.id` — template ids in `GET /tickets/settings` | **Invoice GET line_items field names differ from ticket line_items:** `item` = product name, `name` = description, `price` = unit rate. Do not use `price_retail` when reading invoice line items. diff --git a/.claude/standards/syncro/test-findings.md b/.claude/standards/syncro/test-findings.md index 4648da23..250afc61 100644 --- a/.claude/standards/syncro/test-findings.md +++ b/.claude/standards/syncro/test-findings.md @@ -29,6 +29,33 @@ policy-folder objects). Host is `rmm.syncromsp.com` (Kabuto/RMM), separate from - The token embeds an enrollment secret → it is a **credential**: vault it (per client), never commit plaintext. `policy_folder_id` comes from `GET /policy_folders?customer_id=N`. +## 2026-07-10 — Phase 1b (breadth: leads / vendors / products / PO / worksheets) + +**Response shapes — these are all WRAPPED (unlike contacts/contracts):** `POST /leads` → +`{"lead":{...}}` (`.lead.id`); `POST /vendors` → `{"vendor":{...}}`; `POST`/`PUT /products` → +`{"product":{...}}`; `POST /purchase_orders` → `{"purchase_order":{...}}`; +`POST /purchase_orders/{id}/create_po_line_item` → `{"po_line_item":{...}}`; +`POST /tickets/{id}/worksheet_results` → `{"worksheet_result":{...}}`; +`DELETE .../worksheet_results/{id}` → `{"message":"N: We deleted ."}`. + +**PO line items require the product to have `maintain_stock:true`.** `create_po_line_item` +against a non-stock product returns `{"errors":"...ensure that the item ... is set to +'Maintain Stock'."}`. Flip the product (`PUT /products/{id}` `maintain_stock:true`) first. + +**Worksheet templates are NOT a standalone endpoint — they live in `GET /tickets/settings` → +`.worksheet_templates[]`** (`{id,title,account_id}`). You need a valid `worksheet_template_id` +to create a worksheet result (e.g. "Virus Removal" = 11341). + +**`PUT /products/{id}` requires `name` AND `description`** (same as create) — 422 without. + +**No DELETE endpoint for leads, vendors, products, purchase_orders** — test records in those +GLOBAL catalogs PERSIST (can't be removed via API; archive/hide in the GUI). Mark test items +`[TEST]` and set products `disabled:true`. Created this run (need GUI cleanup): lead 43492446, +vendor 809317, product 23639304 (disabled), PO 2101221 (+ line 8918508). + +**Minor:** `POST /leads` `business_name` didn't persist (came back null); `first_name`/ +`last_name`/`email`/`customer_id` did. Re-check the correct field for a lead's company name. + ## 2026-07-10 — Phase 1 (PSA CRUD) **Emailing an invoice/estimate returns 200 "Email sent" even when it delivered to NOBODY.**