Compare commits

...

4 Commits

Author SHA1 Message Date
fd12ba247f syncro skill: document appointment move/edit — PUT /appointments/{id} verified
Added /syncro move-appointment to usage table; added Appointments CRUD section
to endpoints reference documenting GET/PUT/DELETE with verified move workflow
(verified 2026-04-24).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 20:13:20 -07:00
97f4218926 remediation: mark SANDTEKO MACHINERY consent status as done in tenant-consent.html
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 20:13:20 -07:00
16f95e8235 fix(onboard): auto-assign Exchange Admin to Exchange Operator SP; mark Sandteko fully onboarded
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 20:13:20 -07:00
b7bc99174f onboard: SANDTEKO MACHINERY LLC (partial) — all apps consented, roles assigned, Exch Op Exchange Admin pending
- tenants.md: updated status to PARTIAL with full detail note
- clients/sandteko-machinery/: new client directory with reports/ and session-logs/ scaffolding

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-24 20:13:20 -07:00
6 changed files with 50 additions and 2 deletions

View File

@@ -14,6 +14,7 @@ Create, update, close, comment on, and bill tickets in Syncro PSA.
/syncro bill <number> Add billable time and create invoice
/syncro search <query> Search tickets by subject/customer
/syncro customers <query> Search customers
/syncro move-appointment <customer> Find and reschedule an existing appointment
```
## API Configuration
@@ -248,6 +249,26 @@ Default: `"2 Normal"`. Use `"4 Urgent"` for emergency/after-hours.
**Tech user IDs:** Mike = 1735, Howard = 1750, Winter = 1737, Rob = 1760
#### Appointments
| Operation | Method | Endpoint | Notes |
|---|---|---|---|
| List (today) | GET | `/appointments?start_at=YYYY-MM-DD` | Filter by date; use `.summary` to match customer |
| Get | GET | `/appointments/<id>` | Returns `{"appointment": {...}}` |
| Create | POST | `/appointments` | Used in ticket creation flow (Call 3) |
| Move / edit | PUT | `/appointments/<id>` | Verified 2026-04-24 — updates `start_at`/`end_at` |
| Delete | DELETE | `/appointments/<id>` | Not yet verified |
**Finding an appointment by customer:** `GET /appointments?start_at=<date>` returns all appointments — filter client-side with `select(.summary | test("customer name"; "i"))` or `select(.ticket.customer_id == N)`. The `customer_id` query param does not filter correctly.
**Move workflow:**
1. `GET /appointments?start_at=<date>` — find appointment ID
2. Confirm new date/time with user
3. `PUT /appointments/<id>` with `{"start_at": "ISO8601", "end_at": "ISO8601"}`
4. Verify response: `.appointment.start_at` matches intended time
**Response shape:** `{"appointment": {...}}` — parse as `.appointment.id`, `.appointment.start_at`, etc.
---
### Ticket creation workflow (full — 3 API calls)

View File

@@ -104,7 +104,7 @@ const TENANTS = [
{ name: "Rincon Vista Vet Ctr", domain: "rinconvistavet.onmicrosoft.com", id: "b8cdcd89-d0f4-4747-bcf3-8bd8a25fd7e1", status: "pending" },
{ name: "Russo Law Firm", domain: "rrs-law.com", id: "bef1b190-f78f-4b1c-aa4b-fab186a30702", status: "pending" },
{ name: "Safe Site Utility Svcs", domain: "safesitellc.com", id: "71b4e637-c802-4137-a812-ae50dbc839e3", status: "done" },
{ name: "SANDTEKO MACHINERY", domain: "SANDTEKOMACHINERY.com", id: "739bb777-cf76-478f-866b-f61c830c8246", status: "pending" },
{ name: "SANDTEKO MACHINERY", domain: "SANDTEKOMACHINERY.com", id: "739bb777-cf76-478f-866b-f61c830c8246", status: "done" },
{ name: "Shave, Kevin", domain: "az2son.com", id: "984c05a9-708b-4ec1-9f43-558865cb3c9d", status: "pending" },
{ name: "Sonorangreenllc.com", domain: "sonorangreenllc.com", id: "ededa4fb-f6eb-4398-851d-5eb3e11fab27", status: "done" },
{ name: "Starr Pass Realty", domain: "starrpass.com", id: "222450dd-141f-435f-87b8-cec719aac99e", status: "pending" },

View File

@@ -41,7 +41,7 @@ After full onboarding, update the Onboarded column below.
| Rincon Vista Veterinary Center | rinconvistavet.onmicrosoft.com | b8cdcd89-d0f4-4747-bcf3-8bd8a25fd7e1 | NO | |
| Russo Law Firm | rrs-law.com | bef1b190-f78f-4b1c-aa4b-fab186a30702 | NO | |
| Safe Site Utility Services LLC | safesitellc.com | 71b4e637-c802-4137-a812-ae50dbc839e3 | NO | |
| SANDTEKO MACHINERY LLC | SANDTEKOMACHINERY.com | 739bb777-cf76-478f-866b-f61c830c8246 | NO | |
| SANDTEKO MACHINERY LLC | SANDTEKOMACHINERY.com | 739bb777-cf76-478f-866b-f61c830c8246 | YES | All apps consented 2026-04-24; Sec Inv + Exch Op Exchange Admin + User Mgr User Admin + Auth Admin roles assigned; no MDE |
| Shave, Kevin | az2son.com | 984c05a9-708b-4ec1-9f43-558865cb3c9d | NO | |
| Sonorangreenllc.com | sonorangreenllc.com | ededa4fb-f6eb-4398-851d-5eb3e11fab27 | NO | |
| Starr Pass Realty | starrpass.com | 222450dd-141f-435f-87b8-cec719aac99e | NO | |

View File

@@ -473,6 +473,7 @@ echo ""
echo "[INFO] Checking and assigning directory roles..."
SEC_INV_OID=$(get_sp_oid "$TENANT_ADMIN_TOKEN" "$APP_SEC_INV")
EXCH_OP_OID=$(get_sp_oid "$TENANT_ADMIN_TOKEN" "$APP_EXCH_OP")
USER_MGR_OID=$(get_sp_oid "$TENANT_ADMIN_TOKEN" "$APP_USER_MGR")
PARTIAL_FAILURE=false
@@ -499,6 +500,28 @@ else
fi
fi
# Exchange Operator -> Exchange Administrator
if [[ -z "$EXCH_OP_OID" ]]; then
echo "[WARNING] Exchange Operator SP still not found after consent attempt"
STATUS_MAP["Exchange Operator:Exchange Administrator"]="MISSING SP"
else
echo ""
echo "[CHECK] Exchange Operator SP: $EXCH_OP_OID"
IS_PRESENT=$(role_assigned "$TENANT_ADMIN_TOKEN" "$EXCH_OP_OID" "$ROLE_EXCHANGE_ADMIN")
if [[ "$IS_PRESENT" == "true" ]]; then
echo " Exchange Administrator: PRESENT"
STATUS_MAP["Exchange Operator:Exchange Administrator"]="OK"
else
echo " Exchange Administrator: MISSING -> ASSIGNING..."
if assign_role "$TENANT_ADMIN_TOKEN" "$EXCH_OP_OID" "$ROLE_EXCHANGE_ADMIN" "Exchange Administrator"; then
STATUS_MAP["Exchange Operator:Exchange Administrator"]=$( [[ "$DRY_RUN" == "true" ]] && echo "DRY-RUN" || echo "ASSIGNED" )
else
STATUS_MAP["Exchange Operator:Exchange Administrator"]="ERROR"
PARTIAL_FAILURE=true
fi
fi
fi
# User Manager -> User Administrator + Authentication Administrator
if [[ -z "$USER_MGR_OID" ]]; then
echo "[WARNING] User Manager SP still not found after consent attempt"
@@ -554,6 +577,10 @@ SEC_EXCH="${STATUS_MAP["Security Investigator:Exchange Administrator"]:-SKIPPED}
echo " Security Investigator:"
printf " Exchange Administrator: %s\n" "[$SEC_EXCH]"
EO_EXCH="${STATUS_MAP["Exchange Operator:Exchange Administrator"]:-SKIPPED}"
echo " Exchange Operator:"
printf " Exchange Administrator: %s\n" "[$EO_EXCH]"
UA="${STATUS_MAP["User Manager:User Administrator"]:-SKIPPED}"
AA="${STATUS_MAP["User Manager:Authentication Administrator"]:-SKIPPED}"
echo " User Manager:"