sync: auto-sync from HOWARD-HOME at 2026-07-05 21:24:32
Author: Howard Enos Machine: HOWARD-HOME Timestamp: 2026-07-05 21:24:32
This commit is contained in:
@@ -155,3 +155,48 @@ Tedards DESKTOP-SUFJR0J last Success 2025-07-12 (~12 mo); Glaz-Tech GTI-INV-VMHO
|
||||
`https://acg.workplace.datto.com/api/v1/openapi.json`
|
||||
- Datto WP API scope docs: help.workplace.datto.com API Integrations (Super Administrator
|
||||
access enables full-team project visibility on the file API).
|
||||
|
||||
## Update: 21:23 PT — built the msp360 skill (full CRUD) + consolidated backup routing
|
||||
|
||||
Built the `msp360` skill (Howard asked for full management, not read-only), then reviewed,
|
||||
fixed, and published it; consolidated all backup-related skill routing behind a wiki-first
|
||||
rule.
|
||||
|
||||
**MSP360 API surface** — confirmed authoritative endpoint list against
|
||||
`help.mspbackups.com/mbs-api-specification/methods` and live `Allow`-header probing: full
|
||||
CRUD on Users, Companies, Licenses (Grant/Release/Revoke), Destinations, Accounts,
|
||||
Packages, Administrators; read-only Monitoring/Billing. `/api/Computers` returns HTTP 400
|
||||
"Remote Management API methods are not enabled" (feature off on this account). Pulled live
|
||||
User/Company/License schemas so write payloads use real field names, not guesses.
|
||||
|
||||
**Skill built** (`.claude/skills/msp360/`): `msp360_client.py` (Bearer login + typed
|
||||
helpers, reuses `backup_common.py`), `msp360.py` (CLI), `SKILL.md`, `.gitignore`.
|
||||
Reads: status, monitoring (`--failed`/`--company`/`--stale`/`--json`), companies, users,
|
||||
licenses, billing, raw GET. Writes (all `--confirm`-gated, dry-run preview otherwise):
|
||||
create/delete company, create/delete user (`--keep-data`), grant/release/revoke license,
|
||||
raw passthrough. Errors -> `errorlog.md`; expected conditions (feature-gate, no-match) not.
|
||||
|
||||
**Code review** (workflow, high effort, 18 agents): 10 findings, all fixed + re-verified.
|
||||
Notable: (1) CREDENTIAL LEAK — create-user dry-run echoed plaintext `--password`; now
|
||||
redacted. (2) main() caught only `Msp360Error`, not parent `bc.BackupError`, so vault/HTTP
|
||||
failures were mislabeled "unexpected"; now catches `bc.BackupError`. (3) non-list 2xx body
|
||||
crashed reads; added `_as_list` guard. (4) licenses `Number` format crash on None; coalesced.
|
||||
(5) `monitoring --failed` hid never-run/Unknown plans (the exact dead-plan case); now
|
||||
included. Plus stale-date parse robustness, feature-gate substring broadening, dead
|
||||
`--json` on billing, dead `update_*` client methods, and `_root()` now uses
|
||||
`bc.resolve_root()`. Refuted 1 (SKILL.md does not document passwords on CLI).
|
||||
|
||||
**Dry-test sweep:** 14/14 reads OK; 8/8 writes correctly gated (nothing executed without
|
||||
`--confirm`); password-redaction confirmed.
|
||||
|
||||
**Routing consolidation** (`.claude/SKILL_ROUTING.md`): seafile + owncloud had each written
|
||||
their own provisioning rows. Collapsed all five backup rows (msp360/b2/seafile/owncloud/
|
||||
datto) into ONE pointer row + a dedicated **"Backups (wiki-first routing)"** block: a backup
|
||||
request is a two-step route — (1) identify which backend THIS customer uses via the client
|
||||
wiki + `backup-map.md` (don't assume B2/MSP360), then (2) route to that backend's skill;
|
||||
provisioning uses the target backend's skill (all writes gated). Encodes both behaviors
|
||||
Howard asked for (check-the-wiki-for-status, and use-the-skills-to-set-up).
|
||||
|
||||
**Published:** commits `976bfe7` (skill) + `a8e76ba` (routing/memory) pushed to origin;
|
||||
Phase 5c installed msp360 to global. Memory `reference_msp360_backup_monitoring` updated
|
||||
(skill now exists, full not read-only).
|
||||
|
||||
Reference in New Issue
Block a user