Skip to content

Commit da5a44d

Browse files
author
baton-admin[bot]
committed
chore: update baton-admin doc files
1 parent 5ce861c commit da5a44d

File tree

4 files changed

+79
-9
lines changed

4 files changed

+79
-9
lines changed

.claude/skills/connector/patterns-error-handling.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,51 @@ if err != nil {
3838

3939
---
4040

41+
## Wrapping Errors with uhttp.WrapErrors
42+
43+
Use `uhttp.WrapErrors` when returning errors from HTTP calls that did **not** go through `uhttp.BaseHttpClient` — for example, SDK library errors, raw `http.Client` calls, or errors you infer yourself (e.g., "status 200 but body indicates failure").
44+
45+
**Why it matters:** The SDK inspects the gRPC status code on errors to decide whether to retry, log, or surface the error to the operator. Without wrapping, the SDK treats all errors as opaque and cannot act appropriately.
46+
47+
**Signature:**
48+
```go
49+
func WrapErrors(preferredCode codes.Code, statusMsg string, errs ...error) error
50+
```
51+
52+
- `preferredCode` — a gRPC status code (from `google.golang.org/grpc/codes`), not an HTTP status code
53+
- `statusMsg` — human-readable message describing the error
54+
- `errs` — original errors to join into the result
55+
56+
**Common gRPC code mappings:**
57+
58+
| Situation | gRPC code |
59+
|-----------|-----------|
60+
| Auth failure (401) | `codes.Unauthenticated` |
61+
| Permission denied (403) | `codes.PermissionDenied` |
62+
| Not found (404) | `codes.NotFound` |
63+
| Rate limited (429) | `codes.ResourceExhausted` |
64+
| Server error (5xx) | `codes.Internal` |
65+
66+
```go
67+
// SDK library error — wrap with appropriate gRPC code:
68+
if err != nil {
69+
return nil, uhttp.WrapErrors(codes.Internal, "baton-myservice: failed to list users", err)
70+
}
71+
72+
// Developer-inferred error from response body or status code:
73+
if resp.StatusCode == http.StatusForbidden {
74+
return nil, uhttp.WrapErrors(
75+
codes.PermissionDenied,
76+
fmt.Sprintf("baton-myservice: access denied to %s", endpoint),
77+
fmt.Errorf("HTTP %d", resp.StatusCode),
78+
)
79+
}
80+
```
81+
82+
**When NOT to use it:** If you're using `uhttp.BaseHttpClient` for all requests, uhttp handles wrapping automatically. Only wrap manually when bypassing uhttp.
83+
84+
---
85+
4186
## Retryable vs Fatal Errors
4287

4388
| Error Type | Retryable? | Action |

.claude/skills/connector/review-breaking-changes.md

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@ Breaking change detection rules for connector reviews.
44

55
---
66

7+
## What Counts as a Breaking Change
8+
9+
- Resource type name change
10+
- Entitlement slug change
11+
- Resource ID format change
12+
- Removed resource type or entitlement
13+
- Changed parent hierarchy
14+
- Changed trait type
15+
- **New API endpoint added to an existing sync path** — even if the code change looks additive, it may require a new scope or permission that existing installations don't have
16+
- **New required OAuth scope or permission** — existing installations lose functionality until reconfigured
17+
- Any drastic change in existing feature behavior
18+
19+
---
20+
721
## What Breaks Downstream
822

923
When a connector changes, these break C1 sync:
@@ -13,6 +27,7 @@ When a connector changes, these break C1 sync:
1327
| Resource type name change | Existing grants orphaned | Critical |
1428
| Entitlement slug change | Grant matching fails | Critical |
1529
| Resource ID format change | Duplicate resources created | Critical |
30+
| New API endpoint (new scope required) | Existing installs lose data | High |
1631
| Removed resource type | Grants disappear | High |
1732
| Changed parent hierarchy | Relationships break | High |
1833
| Removed entitlement | Grants can't be revoked | High |
@@ -240,12 +255,17 @@ These are NOT breaking:
240255
241256
---
242257
243-
## Migration Guidance
258+
## Process for Breaking Changes
244259
245-
If a breaking change is necessary:
260+
If a breaking change is necessary, all of the following are required before merging:
246261
247-
1. **Document the break** in PR description
248-
2. **Coordinate with C1 team** for sync timing
249-
3. **Consider dual-emit** temporarily (old + new IDs)
250-
4. **Plan grant re-sync** after deployment
251-
5. **Update any hardcoded references** in C1 config
262+
1. **Gate behind a config flag** — breaking behavior must be opt-in; never default-on
263+
2. **Lead approval required** — get explicit sign-off before merging to main
264+
3. **Document in the PR description** — clearly state what breaks and why
265+
4. **Coordinate with C1 team** for sync timing
266+
5. **Update `docs/connector.mdx`** to reflect new scopes, auth requirements, or behavioral changes
267+
6. **File a DOCS ticket** to track the doc update if not done in the same PR
268+
7. **Note it in the Jira issue** so it's visible to the full team
269+
8. **Consider dual-emit** temporarily (old + new IDs) to smooth migration
270+
9. **Plan grant re-sync** after deployment
271+
10. **Update any hardcoded references** in C1 config

.claude/skills/connector/review-checklist.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ if resp.NextPage == "" {
5555
return resources, resp.NextPage, nil, nil
5656
```
5757

58+
**Testing:**
59+
- [ ] Verified pagination works by temporarily setting `page_size=1` during development (catches off-by-one and early-termination bugs that full-page tests miss)
60+
5861
---
5962

6063
## HTTP Safety Check
@@ -156,6 +159,7 @@ Look for:
156159
- [ ] README shows example usage
157160
- [ ] Complex logic has comments explaining WHY (not what)
158161
- [ ] No TODO comments for critical functionality
162+
- [ ] `docs/connector.mdx` updated if capabilities, auth requirements, or required scopes changed
159163

160164
---
161165

.claude/skills/connector/review-connector.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ Return a JSON array. Empty array if no issues. Only findings with confidence >=
8888
- R1: List methods return []*Type (pointer slices)
8989
- R2: No unused function parameters
9090
- R3: Clear variable names (groupMember not gm)
91-
- R4: Errors use %w (not %v), include baton-{service}: prefix, use uhttp.WrapErrors
91+
- R4: Errors use %w (not %v), include baton-{service}: prefix; use uhttp.WrapErrors(codes.Code, msg, err) for errors from non-uhttp HTTP calls, SDK library errors, or developer-inferred errors so the SDK can inspect the gRPC status code and decide whether to retry
9292
- R5: Use StaticEntitlements for uniform entitlements
9393
- R6: Use Skip annotations (SkipEntitlementsAndGrants, etc.) appropriately
9494
- R7: Missing API permissions = degrade gracefully, don't fail sync
@@ -110,7 +110,7 @@ Return a JSON array. Empty array if no issues. Only findings with confidence >=
110110
- H4: No error swallowing (log.Println + continue = silent data loss)
111111
- H5: No secrets in logs (apiKey, password, token values)
112112
113-
## BREAKING CHANGES (B1-B8) — Check in diffs:
113+
## BREAKING CHANGES (B1-B9) — Check in diffs:
114114
- B1: Resource type Id: field changes = CRITICAL (grants orphaned)
115115
- B2: Entitlement slug changes in NewAssignmentEntitlement/NewPermissionEntitlement = CRITICAL
116116
- B3: Resource ID derivation changes (user.ID→user.Email) = CRITICAL
@@ -119,6 +119,7 @@ Return a JSON array. Empty array if no issues. Only findings with confidence >=
119119
- B6: Trait type changes (NewUserResource→NewAppResource) = MEDIUM
120120
- B7: New required OAuth scopes = breaking
121121
- B8: SAFE: display name changes, adding new types, adding trait options, adding pagination
122+
- B9: New API endpoint added to an existing resource's sync path = breaking (requires scope change or different permissions)
122123
123124
## TOP BUG DETECTION PATTERNS
124125
1. Pagination: `return resources, "", nil, nil` without conditional = stops after page 1

0 commit comments

Comments
 (0)