@revfleet/hscli 0.8.6 → 0.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGELOG.md +240 -0
  2. package/CONTRIBUTING.md +120 -0
  3. package/README.md +14 -6
  4. package/brand/readme-hero.svg +25 -0
  5. package/dist/cli.js +10 -0
  6. package/dist/cli.js.map +1 -1
  7. package/dist/commands/account/index.js +5 -6
  8. package/dist/commands/account/index.js.map +1 -1
  9. package/dist/commands/api/index.js +43 -3
  10. package/dist/commands/api/index.js.map +1 -1
  11. package/dist/commands/auth/index.js +32 -6
  12. package/dist/commands/auth/index.js.map +1 -1
  13. package/dist/commands/cms/hubdb.js +64 -1
  14. package/dist/commands/cms/hubdb.js.map +1 -1
  15. package/dist/commands/cms/index.js +27 -0
  16. package/dist/commands/cms/index.js.map +1 -1
  17. package/dist/commands/cms/source-code.js +21 -0
  18. package/dist/commands/cms/source-code.js.map +1 -1
  19. package/dist/commands/communication-preferences/index.js +11 -12
  20. package/dist/commands/communication-preferences/index.js.map +1 -1
  21. package/dist/commands/crm/shared.d.ts +1 -0
  22. package/dist/commands/crm/shared.js +3 -4
  23. package/dist/commands/crm/shared.js.map +1 -1
  24. package/dist/commands/events/index.js +7 -8
  25. package/dist/commands/events/index.js.map +1 -1
  26. package/dist/commands/marketing/index.js +58 -3
  27. package/dist/commands/marketing/index.js.map +1 -1
  28. package/dist/commands/settings/index.js +12 -13
  29. package/dist/commands/settings/index.js.map +1 -1
  30. package/dist/commands/workflows/index.js +43 -0
  31. package/dist/commands/workflows/index.js.map +1 -1
  32. package/dist/core/http.d.ts +27 -0
  33. package/dist/core/http.js +102 -18
  34. package/dist/core/http.js.map +1 -1
  35. package/dist/core/plugins.d.ts +5 -2
  36. package/dist/core/plugins.js +18 -1
  37. package/dist/core/plugins.js.map +1 -1
  38. package/dist/core/telemetry-context.d.ts +13 -0
  39. package/dist/core/telemetry-context.js +30 -0
  40. package/dist/core/telemetry-context.js.map +1 -0
  41. package/dist/mcp/hubspot-modules.d.ts +30 -0
  42. package/dist/mcp/hubspot-modules.js +305 -0
  43. package/dist/mcp/hubspot-modules.js.map +1 -0
  44. package/dist/mcp/server.d.ts +2 -0
  45. package/dist/mcp/server.js +30 -26
  46. package/dist/mcp/server.js.map +1 -1
  47. package/docs/ARCHITECTURE.md +39 -0
  48. package/docs/CAPABILITY_LIBRARY.md +638 -0
  49. package/docs/CMS_SETUP.md +349 -0
  50. package/docs/COMMAND_COMPATIBILITY.md +24 -0
  51. package/docs/COMMAND_TREE.md +183 -0
  52. package/docs/COMMERCE_SETUP.md +400 -0
  53. package/docs/COMPARISON.md +146 -0
  54. package/docs/COOKBOOK.md +800 -0
  55. package/docs/INTEGRATIONS_NOTIFICATIONS_SETUP.md +352 -0
  56. package/docs/MARKETING_SETUP.md +503 -0
  57. package/docs/MCP.md +171 -0
  58. package/docs/OPERATIONAL_PLAYBOOKS.md +322 -0
  59. package/docs/OPERATIONS_SETUP.md +362 -0
  60. package/docs/PLUGIN_GUIDE.md +158 -0
  61. package/docs/POLICY_EXAMPLE.json +57 -0
  62. package/docs/PORTAL_SETUP.md +683 -0
  63. package/docs/PUBLISHING.md +154 -0
  64. package/docs/RELEASE_GOVERNANCE.md +34 -0
  65. package/docs/REPORTING_SETUP.md +310 -0
  66. package/docs/ROADMAP-DATE-BASED-API.md +103 -0
  67. package/docs/ROADMAP_PHASE1_TO_3.md +96 -0
  68. package/docs/SAFETY_MODEL.md +37 -0
  69. package/docs/SALES_SETUP.md +369 -0
  70. package/docs/SERVICE_SETUP.md +403 -0
  71. package/docs/TESTING_PLAN.md +89 -0
  72. package/docs/TIERS.md +320 -0
  73. package/docs/TUTORIALS/audit-portal-writes.md +150 -0
  74. package/docs/TUTORIALS/secure-agent-writes.md +177 -0
  75. package/docs/TUTORIALS/trace-replay-repro.md +147 -0
  76. package/docs/WHY_HOW_WHAT.md +81 -0
  77. package/package.json +7 -2
@@ -0,0 +1,403 @@
1
+ # Service Setup Guide
2
+
3
+ > See also: [PORTAL_SETUP.md](PORTAL_SETUP.md) · [SALES_SETUP.md](SALES_SETUP.md) · [OPERATIONS_SETUP.md](OPERATIONS_SETUP.md) · [REPORTING_SETUP.md](REPORTING_SETUP.md)
4
+
5
+ Complete configuration guide for HubSpot Service Hub settings. Covers tickets, knowledge base, customer portal, feedback surveys, SLAs, and service automation.
6
+
7
+ **Prerequisites:**
8
+ - Portal authenticated (`hscli auth whoami`)
9
+ - Private App scopes: `tickets`, `crm.schemas.tickets.read/write`
10
+ - Users & Teams configured (see [PORTAL_SETUP.md](./PORTAL_SETUP.md))
11
+
12
+ ---
13
+
14
+ ## 1. Tickets & Pipelines
15
+
16
+ **Where:** Settings > Objects > Tickets
17
+
18
+ ### 1.1 Ticket Pipeline Configuration
19
+
20
+ | Setting | What to configure | Why it matters |
21
+ |---------|-------------------|----------------|
22
+ | Pipeline name | Name per support process (e.g., "Support", "Bug Reports", "Feature Requests") | Separate workflows for different request types |
23
+ | Ticket statuses | Ordered statuses: Open → In Progress → Waiting on Contact → Closed | Tracks ticket lifecycle |
24
+ | Status categories | Map each status to Open, In Progress, or Closed | Powers reporting and SLAs |
25
+ | Conditional properties | Required properties per status | Data quality at each stage |
26
+ | Multiple pipelines | Different pipelines for different support tiers or request types | Tailored processes |
27
+
28
+ **hscli:**
29
+ ```bash
30
+ # List ticket pipelines
31
+ hscli crm pipelines list tickets
32
+
33
+ # Get pipeline details
34
+ hscli crm pipelines get tickets <pipelineId>
35
+
36
+ # Create a support pipeline
37
+ hscli crm pipelines create tickets --data '{
38
+ "label": "Customer Support",
39
+ "displayOrder": 0,
40
+ "stages": [
41
+ {"label": "New", "displayOrder": 0, "metadata": {"ticketState": "OPEN"}},
42
+ {"label": "In Progress", "displayOrder": 1, "metadata": {"ticketState": "OPEN"}},
43
+ {"label": "Waiting on Contact", "displayOrder": 2, "metadata": {"ticketState": "OPEN"}},
44
+ {"label": "Waiting on Third Party", "displayOrder": 3, "metadata": {"ticketState": "OPEN"}},
45
+ {"label": "Resolved", "displayOrder": 4, "metadata": {"ticketState": "CLOSED"}},
46
+ {"label": "Closed", "displayOrder": 5, "metadata": {"ticketState": "CLOSED"}}
47
+ ]
48
+ }' --force
49
+ ```
50
+
51
+ ### 1.2 Ticket Properties
52
+
53
+ | Property | Type | Purpose |
54
+ |----------|------|---------|
55
+ | `subject` | Text | Ticket subject line |
56
+ | `content` | Text | Ticket description |
57
+ | `hs_ticket_priority` | Select | Priority level (Low, Medium, High, Urgent) |
58
+ | `hs_ticket_category` | Select | Category (Billing, Technical, General, etc.) |
59
+ | `hubspot_owner_id` | Owner | Assigned agent |
60
+ | `hs_pipeline` | Select | Which pipeline |
61
+ | `hs_pipeline_stage` | Select | Current status |
62
+ | `source_type` | Select | How ticket was created (Email, Chat, Form, Phone) |
63
+
64
+ **hscli:**
65
+ ```bash
66
+ # Create custom ticket property
67
+ hscli crm properties create tickets --data '{
68
+ "name": "ticket_product_area",
69
+ "label": "Product Area",
70
+ "type": "enumeration",
71
+ "fieldType": "select",
72
+ "groupName": "ticketinformation",
73
+ "options": [
74
+ {"label": "Core Platform", "value": "core_platform", "displayOrder": 0},
75
+ {"label": "Integrations", "value": "integrations", "displayOrder": 1},
76
+ {"label": "Billing", "value": "billing", "displayOrder": 2},
77
+ {"label": "Mobile App", "value": "mobile_app", "displayOrder": 3}
78
+ ]
79
+ }' --force
80
+
81
+ # Search tickets by priority
82
+ hscli crm tickets search --data '{
83
+ "filterGroups": [{
84
+ "filters": [{
85
+ "propertyName": "hs_ticket_priority",
86
+ "operator": "EQ",
87
+ "value": "HIGH"
88
+ }]
89
+ }],
90
+ "limit": 20
91
+ }'
92
+ ```
93
+
94
+ ---
95
+
96
+ ## 2. Help Desk & Inbox
97
+
98
+ **Where:** Settings > Inbox > Inboxes (or Settings > Help Desk)
99
+
100
+ ### 2.1 Help Desk Configuration
101
+
102
+ | Setting | What to configure | Why it matters |
103
+ |---------|-------------------|----------------|
104
+ | Help desk workspace | Enable help desk view | Unified agent workspace |
105
+ | Default pipeline | Which pipeline for new tickets | Auto-routing |
106
+ | SLA settings | Response and resolution time targets | Service quality management |
107
+ | Working hours | Business hours for SLA calculation | SLAs pause outside hours |
108
+ | Auto-assignment | Round-robin or skill-based routing | Fair distribution, faster response |
109
+
110
+ ### 2.2 Channels
111
+
112
+ | Channel | Configuration | Creates ticket? |
113
+ |---------|--------------|----------------|
114
+ | Team email | Forward support@ to HubSpot | Yes, automatically |
115
+ | Live chat | Chat widget on website | Yes, when converted |
116
+ | Facebook Messenger | Connect Facebook page | Yes, when converted |
117
+ | Form submissions | Connect support forms | Yes, per form settings |
118
+ | Calling | HubSpot or third-party calling | Manual ticket creation |
119
+ | WhatsApp Business | Connect WhatsApp (requires Meta Business) | Yes, when converted |
120
+
121
+ ### 2.3 Routing Rules
122
+
123
+ | Rule | Configuration | Example |
124
+ |------|--------------|---------|
125
+ | By topic/category | Route based on form field or keyword | Billing → Finance team |
126
+ | By language | Route based on detected language | Spanish → Spanish-speaking agents |
127
+ | By customer tier | Route based on company property | Enterprise → Senior agents |
128
+ | Round-robin | Equal distribution within team | Default for general inquiries |
129
+ | Skill-based | Match ticket properties to agent skills | Technical → Engineering support |
130
+
131
+ ---
132
+
133
+ ## 3. Knowledge Base
134
+
135
+ **Where:** Service > Knowledge Base | Settings > Content > Knowledge Base
136
+
137
+ ### 3.1 Knowledge Base Settings
138
+
139
+ | Setting | What to configure | Why it matters |
140
+ |---------|-------------------|----------------|
141
+ | Domain | Subdomain for KB (e.g., `help.yourcompany.com`) | Professional, branded help center |
142
+ | Template | Theme and layout | Match brand design |
143
+ | Logo & favicon | Brand assets | Visual consistency |
144
+ | Navigation | Category structure | Easy content discovery |
145
+ | Search | Built-in search functionality | Self-service resolution |
146
+ | Language | Primary language + translations | Serve global customers |
147
+ | Contact support link | Link/button to submit ticket | Escalation path when self-service fails |
148
+
149
+ ### 3.2 Category Structure
150
+
151
+ | Level | Example | Purpose |
152
+ |-------|---------|---------|
153
+ | Category | "Getting Started" | Top-level grouping |
154
+ | Subcategory | "Account Setup" | Second-level grouping |
155
+ | Article | "How to Reset Your Password" | Individual help article |
156
+
157
+ ### 3.3 Article Best Practices
158
+
159
+ | Element | Configuration |
160
+ |---------|--------------|
161
+ | Title | Clear, question-based (matches search queries) |
162
+ | Body | Step-by-step with screenshots |
163
+ | Tags | Keywords for search discoverability |
164
+ | Related articles | Cross-linked articles for deeper context |
165
+ | Feedback | Enable "Was this helpful?" rating |
166
+ | Visibility | Public (all) or Private (logged-in customers only) |
167
+
168
+ > **API:** Knowledge base articles are not currently exposed via public API. Management is UI-only.
169
+
170
+ ---
171
+
172
+ ## 4. Customer Portal
173
+
174
+ **Where:** Settings > Content > Customer Portal (Service Hub Professional+)
175
+
176
+ ### 4.1 Portal Settings
177
+
178
+ | Setting | What to configure | Why it matters |
179
+ |---------|-------------------|----------------|
180
+ | Portal URL | Custom domain or subdomain | Branded self-service |
181
+ | Login method | Email + password, SSO | Secure customer access |
182
+ | Template | Theme matching your brand | Consistent experience |
183
+ | Logo & colors | Brand assets | Visual consistency |
184
+ | Navigation | Links to KB, ticket submission, account | Easy self-service |
185
+
186
+ ### 4.2 Portal Features
187
+
188
+ | Feature | Configuration | Purpose |
189
+ |---------|--------------|---------|
190
+ | Ticket list | Customers see their open/closed tickets | Transparency |
191
+ | Ticket submission | Form to create new tickets | Self-service |
192
+ | Ticket detail | Full conversation history | Context |
193
+ | Knowledge base | Embedded KB search | Self-resolution |
194
+ | File attachment | Allow file uploads on tickets | Rich support context |
195
+
196
+ ### 4.3 Portal Access Control
197
+
198
+ | Setting | What to configure | Why it matters |
199
+ |---------|-------------------|----------------|
200
+ | Registration | Open registration or invite-only | Control who can access |
201
+ | Required properties | Contact properties needed at registration | Data collection |
202
+ | Visibility | Which tickets visible (own only, company-wide) | Privacy/transparency balance |
203
+ | Branding | Custom CSS for advanced styling | Pixel-perfect branding |
204
+
205
+ ---
206
+
207
+ ## 5. Feedback Surveys
208
+
209
+ **Where:** Service > Feedback Surveys | Settings > Service > Feedback Surveys
210
+
211
+ ### 5.1 Survey Types
212
+
213
+ | Survey type | Metric | Question | Scale |
214
+ |-------------|--------|----------|-------|
215
+ | NPS (Net Promoter Score) | Loyalty | "How likely are you to recommend us?" | 0–10 |
216
+ | CSAT (Customer Satisfaction) | Satisfaction | "How satisfied are you with your experience?" | 1–5 or 1–7 |
217
+ | CES (Customer Effort Score) | Ease | "How easy was it to get your issue resolved?" | 1–5 or 1–7 |
218
+ | Custom survey | Custom | Your own questions | Custom |
219
+
220
+ ### 5.2 Survey Configuration
221
+
222
+ | Setting | What to configure | Why it matters |
223
+ |---------|-------------------|----------------|
224
+ | Delivery method | Email, web page, or chat | Choose based on context |
225
+ | Trigger | After ticket close, after purchase, periodic | Timely feedback collection |
226
+ | Delay | Time after trigger to send (e.g., 1 hour after ticket close) | Avoid surveying too early |
227
+ | Frequency | Max surveys per contact per period | Survey fatigue prevention |
228
+ | Follow-up questions | Open-text follow-up based on score | Qualitative insights |
229
+ | Thank you message | Custom response per score range | Acknowledge feedback |
230
+ | Automation | Trigger workflow based on score | Act on feedback |
231
+
232
+ ### 5.3 Score-Based Automation
233
+
234
+ | Score range (NPS) | Classification | Recommended action |
235
+ |-------------------|----------------|-------------------|
236
+ | 9–10 | Promoter | Ask for review/referral, enroll in advocacy program |
237
+ | 7–8 | Passive | Send thank you, identify improvement areas |
238
+ | 0–6 | Detractor | Alert CS manager, create follow-up ticket, personal outreach |
239
+
240
+ ---
241
+
242
+ ## 6. SLAs (Service Level Agreements)
243
+
244
+ **Where:** Settings > Help Desk > SLAs (Service Hub Professional+)
245
+
246
+ ### 6.1 SLA Configuration
247
+
248
+ | Setting | What to configure | Why it matters |
249
+ |---------|-------------------|----------------|
250
+ | First response time | Max time to first reply (by priority) | Customer expectations |
251
+ | Time to close | Max time to resolve (by priority) | Resolution accountability |
252
+ | Working hours | Business hours for SLA clock | Realistic time calculations |
253
+ | Priority levels | Map ticket priority to SLA targets | Higher priority = faster response |
254
+
255
+ ### 6.2 SLA Targets by Priority
256
+
257
+ | Priority | First Response | Time to Close |
258
+ |----------|---------------|---------------|
259
+ | Urgent | 1 hour | 4 hours |
260
+ | High | 4 hours | 8 hours |
261
+ | Medium | 8 hours | 24 hours |
262
+ | Low | 24 hours | 72 hours |
263
+
264
+ ### 6.3 SLA Escalation
265
+
266
+ | Trigger | Action | Purpose |
267
+ |---------|--------|---------|
268
+ | 50% of SLA elapsed | Warning notification to agent | Proactive awareness |
269
+ | 75% of SLA elapsed | Escalate to team lead | Prevent breach |
270
+ | SLA breached | Alert manager, reassign if needed | Immediate attention |
271
+ | SLA at risk (pattern) | Flag in reporting | Systemic issue identification |
272
+
273
+ ---
274
+
275
+ ## 7. Snippets & Saved Replies
276
+
277
+ **Where:** Conversations > Snippets
278
+
279
+ | Setting | What to configure | Why it matters |
280
+ |---------|-------------------|----------------|
281
+ | Snippet name | Descriptive name with shortcut (e.g., `#greeting`) | Quick insertion via shortcut |
282
+ | Content | Pre-written response text | Consistency, speed |
283
+ | Personalization | Include tokens (contact name, ticket #) | Personalized yet efficient |
284
+ | Categories | Organize by type (greetings, closings, FAQs, escalation) | Easy discovery |
285
+ | Team sharing | Share across team | Consistent messaging |
286
+
287
+ ### Common Snippet Categories
288
+
289
+ | Category | Examples |
290
+ |----------|---------|
291
+ | Greetings | Welcome message, acknowledgment |
292
+ | Status updates | "We're investigating", "Awaiting your response" |
293
+ | Resolutions | "Issue resolved", "Bug fixed in latest release" |
294
+ | Escalations | "Escalating to engineering", "Transferring to billing" |
295
+ | Closings | "Is there anything else?", "Thank you for your patience" |
296
+ | FAQs | Common question answers (linked to KB articles) |
297
+
298
+ ---
299
+
300
+ ## 8. Service Automation & Workflows
301
+
302
+ **Where:** Automation > Workflows | Settings > Objects > Tickets > Automate
303
+
304
+ ### 8.1 Common Service Workflows
305
+
306
+ | Trigger | Actions | Purpose |
307
+ |---------|---------|---------|
308
+ | New ticket created | Auto-assign, set priority, send acknowledgment | Fast first response |
309
+ | Ticket idle > X hours | Notify agent, escalate if SLA at risk | Prevent SLA breaches |
310
+ | Ticket status → Waiting on Contact | Send reminder after 48 hours | Re-engage customer |
311
+ | Ticket status → Closed | Send CSAT survey after 1 hour | Collect feedback |
312
+ | CSAT score ≤ 2 | Create follow-up ticket, alert manager | Recover unhappy customers |
313
+ | Ticket reopened | Reassign to original agent, reset SLA clock | Continuity |
314
+ | High-priority ticket created | Slack notification to on-call team | Immediate attention |
315
+
316
+ ### 8.2 Ticket-Based Automation
317
+
318
+ **Where:** Settings > Objects > Tickets > Automate tab (per pipeline)
319
+
320
+ | Trigger | Action | Example |
321
+ |---------|--------|---------|
322
+ | Ticket enters status | Create task | "Review and classify" when ticket is New |
323
+ | Ticket enters status | Update property | Set resolution date when Closed |
324
+ | Ticket enters status | Send email | Acknowledgment when ticket created |
325
+ | Ticket enters status | Send notification | Alert team when escalated |
326
+
327
+ ---
328
+
329
+ ## Setup Checklist
330
+
331
+ ### Tickets & Pipelines
332
+ ```
333
+ [ ] Primary support pipeline created with statuses
334
+ [ ] Status categories mapped (Open, In Progress, Closed)
335
+ [ ] Custom ticket properties created (category, product area, etc.)
336
+ [ ] Priority levels configured
337
+ [ ] Conditional properties set per status
338
+ ```
339
+
340
+ ### Help Desk & Inbox
341
+ ```
342
+ [ ] Help desk workspace enabled
343
+ [ ] Team email channel connected (support@)
344
+ [ ] Live chat widget configured and deployed
345
+ [ ] Routing rules set up (round-robin or skill-based)
346
+ [ ] Working hours configured
347
+ [ ] Auto-assignment enabled
348
+ ```
349
+
350
+ ### Knowledge Base
351
+ ```
352
+ [ ] Knowledge base domain configured
353
+ [ ] Template/theme selected and branded
354
+ [ ] Category structure created
355
+ [ ] Initial articles published (top 10 FAQs)
356
+ [ ] Search enabled and tested
357
+ [ ] "Contact support" link configured
358
+ ```
359
+
360
+ ### Customer Portal
361
+ ```
362
+ [ ] Portal URL configured
363
+ [ ] Login method set (email or SSO)
364
+ [ ] Template branded (logo, colors)
365
+ [ ] Ticket visibility settings configured
366
+ [ ] Registration flow tested
367
+ ```
368
+
369
+ ### Feedback Surveys
370
+ ```
371
+ [ ] NPS survey configured and scheduled
372
+ [ ] CSAT survey set to trigger after ticket close
373
+ [ ] Follow-up questions added per score range
374
+ [ ] Score-based automation workflows created
375
+ [ ] Survey frequency limits set
376
+ ```
377
+
378
+ ### SLAs
379
+ ```
380
+ [ ] SLA targets defined per priority level
381
+ [ ] Working hours set for SLA calculation
382
+ [ ] Escalation rules configured (warning, breach)
383
+ [ ] SLA reporting dashboard created
384
+ ```
385
+
386
+ ### Snippets
387
+ ```
388
+ [ ] Greeting snippets created
389
+ [ ] FAQ response snippets created
390
+ [ ] Status update snippets created
391
+ [ ] Closing snippets created
392
+ [ ] Snippets shared with team
393
+ ```
394
+
395
+ ### Service Automation
396
+ ```
397
+ [ ] New ticket auto-assignment workflow active
398
+ [ ] Ticket idle alert workflow active
399
+ [ ] CSAT survey trigger workflow active
400
+ [ ] Detractor follow-up workflow active
401
+ [ ] SLA breach escalation workflow active
402
+ [ ] Ticket closure automation configured
403
+ ```
@@ -0,0 +1,89 @@
1
+ # TESTING PLAN
2
+
3
+ > See also: [ARCHITECTURE.md](ARCHITECTURE.md) · [SAFETY_MODEL.md](SAFETY_MODEL.md) · [RELEASE_GOVERNANCE.md](RELEASE_GOVERNANCE.md)
4
+
5
+ ## Strategy Overview
6
+
7
+ ### Unit tests
8
+ - Core output redaction logic
9
+ - CLI argument parsing and context propagation
10
+ - write-gate behavior (`--dry-run`, `--force`, block when missing)
11
+ - malformed payload and auth error handling
12
+
13
+ ### Integration tests (mocked HubSpot HTTP)
14
+ - command routing to expected endpoint paths
15
+ - query params (limit/after/properties/filter) correctness
16
+ - method correctness for create/update/remove operations
17
+
18
+ ### End-to-end tests
19
+ - **Sandbox first:** run against HubSpot developer sandbox only.
20
+ - **Production testing:** read-only smoke checks unless explicit manual approval window.
21
+ - `tests/contract.sandbox.test.ts` is opt-in and enabled with `HSCLI_ENABLE_SANDBOX_CONTRACT=1`.
22
+
23
+ ## Sandbox vs Production Policy
24
+ - Sandbox is mandatory for all mutation tests.
25
+ - Production writes require:
26
+ - approved change window
27
+ - backup/export plan
28
+ - explicit operator confirmation
29
+ - Default recommendation: run with `--dry-run` first, then re-run with `--force` only after review.
30
+
31
+ ## Domain Test Cases
32
+
33
+ ### Contacts / Companies / Deals
34
+ - list with pagination/filters
35
+ - get by ID + selected properties
36
+ - search with limit/after
37
+ - create/update dry-run and forced execution
38
+
39
+ ### Properties
40
+ - list/get property definitions
41
+ - create/update property definitions (dry-run and force paths)
42
+ - invalid JSON payload rejection
43
+
44
+ ### Associations
45
+ - list associations with paging
46
+ - create/remove association dry-run and force behavior
47
+ - path construction validation for object types/ids
48
+
49
+ ### Pipelines
50
+ - list by object type
51
+ - get pipeline by ID
52
+
53
+ ### Owners
54
+ - list with limit/after/email filters
55
+
56
+ ### Imports (Phase 1 gap)
57
+ - create import job payload validation
58
+ - status polling behavior
59
+ - failed-row error retrieval
60
+
61
+ ## Dry-Run Validation Matrix
62
+ - Every mutating command must satisfy:
63
+ - with `--dry-run`: no HTTP mutation call occurs
64
+ - without `--dry-run` and without `--force`: operation blocked
65
+ - with `--force`: HTTP mutation call allowed
66
+
67
+ ## Security Control Tests
68
+ - Redaction tests:
69
+ - token-like keys replaced with `[REDACTED]`
70
+ - bearer strings redacted in messages/details
71
+ - Non-mutation dry-run tests:
72
+ - ensure fetch is not called on writes
73
+ - Unauthorized/missing token behavior:
74
+ - `AUTH_PROFILE_NOT_FOUND` returned
75
+ - Malformed payload handling:
76
+ - invalid JSON returns `INVALID_JSON`
77
+ - Policy gate tests:
78
+ - policy can block writes/deletes even with `--force`
79
+ - policy can require change ticket context
80
+
81
+ ## Acceptance Criteria: External HubSpot Contact Testing
82
+ Checklist before sign-off:
83
+ - [ ] Sandbox contact list/get/search returns valid schema
84
+ - [ ] Contact create dry-run outputs exact request preview
85
+ - [ ] Contact create live write requires `--force`
86
+ - [ ] Contact update dry-run and live paths validated
87
+ - [ ] No token/authorization value appears in stdout/stderr
88
+ - [ ] Error envelopes are machine-parseable in `--json` mode
89
+ - [ ] Retry behavior observed for synthetic 429/5xx response simulation