sync: auto-sync from HOWARD-HOME at 2026-06-30 11:27:16
Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-06-30 11:27:16
This commit is contained in:
@@ -55,6 +55,10 @@ Create, update, close, comment on, and bill tickets in Syncro PSA.
|
||||
|
||||
**Always pass `"taxable": false` explicitly on labor line items.** Labor products are configured with `taxable: false` in Syncro, but `add_line_item` via API does not inherit the product's taxable setting — it posts the line item as `taxable: true` regardless. Always include `"taxable": false` in the payload to match the product's configured value.
|
||||
|
||||
**`product_category` is a CONTROLLED VOCABULARY — never invent one, never invoice a line blank.** Syncro categories are an admin-defined set; the CATEGORY column on every invoice line drives QuickBooks item mapping and revenue reporting. A blank category = an uncategorized line that breaks both. Two hard rules:
|
||||
- **Never make up a category string.** Use ONLY a value that already exists in the tenant. To see the live set, enumerate distinct `product_category` across products (do NOT hardcode — it changes): `for p in $(seq 1 N); do curl -s "${BASE}/products?per_page=100&page=$p&api_key=${API_KEY}"; done | jq -r '.products[].product_category' | sort -u`. Known good values include `Labor`, `Software`, `Hardware`, `Product`, `Service`/`Services`, `Subscriptions`, `Contract`, `Discount`, `Exempt Labor`, `Prepay Hours`, `Other`, `Deposit`, `Default`. If none clearly fits, **ASK — do not guess**.
|
||||
- **Never invoice a line whose product has `product_category: null`.** Before billing, `GET /products/<id>` and check `.product.product_category`. If it is `null`/blank, the product is mis-configured — STOP and flag it (a Windows/OS/software item → `Software`; a physical item → `Hardware`). Do not silently push the line out uncategorized. (Incident 2026-06-30, Cascades #32466/#32474 invoices 67887/67890: "Windows Pro Upgrade" product 23571919 has `product_category: null`, so every billed line showed a blank CATEGORY column. Winter corrected the records; the rule is here so the skill catches it next time.)
|
||||
|
||||
**`DELETE /schedules/{id}` destroys the recurring invoice template immediately — no confirmation, no undo.** Past generated invoices are unaffected but future billing stops. The schedule must be recreated manually with all line items if deleted accidentally. NEVER run destructive HTTP method probes against a live customer schedule — use ACG internal account (customer_id 15353550) for any testing. Incident: Russo Law Firm schedule 224454 deleted during API research 2026-05-26; recreated as 509659.
|
||||
|
||||
**Test articles — always prefix the subject/name with `[TEST]`.** Any ticket, estimate, appointment, or schedule created for testing or API research MUST have its subject or name prefixed with `[TEST]` (e.g. `[TEST] Schedule API research`, `[TEST] Estimate - hardware pricing`). This applies regardless of which customer account is used (including the ACG internal test account, customer_id 15353550). Test records must be instantly distinguishable from real customer work at a glance. If a test article was created without the prefix, PUT the subject to add it before continuing.
|
||||
@@ -670,6 +674,8 @@ JSON
|
||||
- `price_retail` — **must be set explicitly**; Syncro does NOT auto-populate from product rate via API
|
||||
- `taxable` — **must be set explicitly**; always `false` for labor; `true` for taxable hardware
|
||||
|
||||
**Pre-flight every line item's category.** `GET /products/<id>` and confirm `.product.product_category` is non-null and is a real existing category (see the controlled-vocabulary rule above). A `null` category means the line will invoice with a blank CATEGORY column — STOP and flag the product instead of billing it. Never substitute an invented category.
|
||||
|
||||
**Do NOT remove line items after invoicing.** Leave them on the ticket.
|
||||
|
||||
**Labor product IDs** — always fetch `price_retail` live, never hardcode:
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
- [INKY outbound breaks DMARC](reference_inky_outbound_breaks_dmarc.md) — Reverse-resolve DMARC rua failing IPs before blaming a sender: ipw-outbound.inkyphishfence.com / us.cloud-sec-av.com = INKY re-injection breaking DKIM+SPF. INKY is in-M365 (connectors+transport rules) per enrolled tenant, but hosting-level (IX/cPanel website) outbound also routes through it independent of M365 enrollment. Fix is INKY-side (outbound DKIM/SPF/ARC), not cPanel DNS.
|
||||
- [Syncro prepay: full-GET only](feedback_syncro_prepay_full_get_only.md) — read prepay_hours ONLY from GET /customers/{id}; the customer search/list endpoint returns null/stale prepay. Never assert "no block" in a billing preview from search data.
|
||||
- [Syncro priority/type format](feedback_syncro_priority_type_format.md) — every ticket create needs a number-prefixed priority ("2 Normal", not bare "Normal" which renders blank) AND a valid problem_type. Winter flagged #32193/#32194. Use the syncro skill's create flow.
|
||||
- [Syncro line-item category](feedback_syncro_line_item_category.md) — product_category is a controlled vocab: never invent one, never invoice a line whose product has product_category:null (blank CATEGORY breaks QB mapping). Pre-flight GET /products/<id>. Winter fixed Cascades 67887/67890 "Windows Pro Upgrade".
|
||||
- [RMM drive-map Explorer refresh](reference_rmm_drive_map_explorer_refresh.md) — drive mapped via RMM user_session works but the user's running Explorer won't show it until SHChangeNotify(DRIVEADD); also UNC \\ gets eaten in heredoc+jq, build it from [char]92.
|
||||
- [Verify live before acting](feedback_verify_live_before_acting.md) — pull LIVE data (OMSA/iDRAC/live API) before acting on a hardware/infra flag; wiki/logs go stale. Cascades CS-SERVER "degraded RAID" was 9-day-stale (mirror self-recovered, SSDs bought needlessly). Windows can't see RAID member health.
|
||||
- [Windows Pro upgrade billing](feedback_windows_pro_upgrade_billing.md) — ACG MAK key (vault infrastructure/windows-pro-mak, Mike's ACG key) for Home->Pro upgrades; RULE: invoice $99 PER machine activated, name the machine on the line item, bill after success. Each use consumes a MAK count.
|
||||
|
||||
15
.claude/memory/feedback_syncro_line_item_category.md
Normal file
15
.claude/memory/feedback_syncro_line_item_category.md
Normal file
@@ -0,0 +1,15 @@
|
||||
---
|
||||
name: feedback_syncro_line_item_category
|
||||
description: Syncro product_category is a controlled vocabulary — never invent one, never invoice a blank-category line
|
||||
metadata:
|
||||
type: feedback
|
||||
---
|
||||
|
||||
When billing in Syncro, every invoice/ticket line item carries a CATEGORY (`product_category`) that is a **controlled, admin-defined vocabulary** and drives QuickBooks item mapping + revenue reporting. Two hard rules:
|
||||
|
||||
1. **Never make up a category.** Use only values that already exist in the tenant (e.g. `Labor`, `Software`, `Hardware`, `Product`, `Service`/`Services`, `Subscriptions`, `Contract`, `Discount`, `Exempt Labor`, `Prepay Hours`, `Other`, `Deposit`, `Default`). Enumerate the live set from `GET /products` rather than hardcoding. If none fits, ASK — do not guess.
|
||||
2. **Never invoice a line whose product has `product_category: null`.** Pre-flight with `GET /products/<id>`; a blank category = an uncategorized line. Flag/fix the product (Windows/OS/software → `Software`, physical → `Hardware`) before billing.
|
||||
|
||||
**Why:** A blank or invented category silently breaks downstream accounting and makes humans clean up records. Incident 2026-06-30: Cascades "Windows Pro Upgrade" (product 23571919, `product_category: null`) invoiced on #32466/#32474 (invoices 67887/67890) with blank CATEGORY columns; Winter had to correct them. This keeps recurring as a skill-following gap.
|
||||
|
||||
**How to apply:** In the `/syncro` flow, before `add_line_item`/invoicing, GET the product and verify `product_category` is a real existing value. Rule lives in `.claude/commands/syncro.md` (taxable-rule block + add_line_item pre-flight). Related: [[feedback_syncro_billing]], [[feedback_syncro_preview_mandatory]], [[feedback_syncro_workflow]].
|
||||
Reference in New Issue
Block a user