ワンクリックで
review-api-endpoint
Use when reviewing API endpoint implementations or modifications in the C# SDK, before approving any PR
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use when reviewing API endpoint implementations or modifications in the C# SDK, before approving any PR
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Use when cutting a new release of the Smartsheet C# SDK — version bump, changelog, tag, and GitHub Release
Use when implementing or modifying Smartsheet API endpoints in the C# SDK, before writing any code or tests
SOC 職業分類に基づく
| name | review-api-endpoint |
| description | Use when reviewing API endpoint implementations or modifications in the C# SDK, before approving any PR |
Code review for API endpoints requires spec-first verification: fetch the OpenAPI specification, validate request/response mapping, verify test completeness, then evaluate architecture. Spec compliance is non-negotiable - architectural quality comes second.
Core principle: A beautifully architected implementation of the wrong API is worse than a messy implementation of the right API.
Use this skill when:
Use BEFORE giving approval or feedback.
SPEC VERIFICATION IS MANDATORY STEP 1. NEVER APPROVE WITHOUT IT.
Don't assume:
⚠️ BREAKING CHANGES TO PUBLIC API ARE EXTREMELY SERIOUS ⚠️
Before ANY other review activity, check if this PR breaks the public SDK contract. Breaking changes without explicit documentation and migration path can cause production failures for all SDK users.
ALWAYS BREAKING:
*Async method signature (params, return type, removing the CancellationToken)HttpClient interface, RequestAsync, ShouldRetryAsync, or RetrySleep contracts (e.g. the v6 PR #195 made RetrySleep async — a documented breaking change)NOT BREAKING:
[Obsolete] while keeping them functionalFor ANY change to public method signatures, ask:
Is the old signature still available?
[Obsolete] attributeCan existing code compile without changes?
Is breaking change documented?
IF breaking changes found AND NOT explicitly documented by author:
IMMEDIATELY REQUEST CHANGES
Required actions:
1. Author MUST acknowledge this is a breaking change
2. Author MUST provide migration guide showing old → new code
3. Author MUST update CHANGELOG under "Breaking Changes"
4. Author MUST confirm major version bump planned (e.g., v6.x → v7.0)
5. Consider: Can this be made non-breaking by keeping old signature with [Obsolete]?
ONLY IF author explicitly states "This PR introduces breaking changes" in description:
Breaking changes without warning:
One undocumented breaking change can break thousands of production applications.
❌ BREAKING - Block This:
// Before (v6.7.0)
Report GetReport(long id, IEnumerable<ReportInclusion>? include);
// After (PR) - OLD SIGNATURE REMOVED
Report GetReport(long id, ReportOptions options);
Impact: Every single existing call to GetReport() will fail to compile.
✅ NON-BREAKING - Safe:
// Before (v6.7.0)
Report GetReport(long id, IEnumerable<ReportInclusion>? include);
// After (PR) - OLD SIGNATURE KEPT
[Obsolete("Use GetReport(long id, ReportOptions options) instead. Will be removed in v8.0.0")]
Report GetReport(long id, IEnumerable<ReportInclusion>? include);
Report GetReport(long id, ReportOptions options); // New signature added
Impact: Existing code continues working, gets deprecation warnings, has time to migrate.
| Excuse | Reality |
|---|---|
| "Tests all pass, so it's safe" | Tests were updated. User code was not. |
| "It's a better API" | Better API doesn't justify breaking user code. |
| "Old signature was inconsistent" | Fix with non-breaking addition, deprecate old. |
| "Users should update their code" | Users update when THEY choose, not when forced. |
| "It's just a refactor" | Signature changes are never "just refactors". |
| "Build is green" | User builds will be red. |
NEVER accept these rationalizations. Breaking changes require explicit acknowledgment.
| Step | Action | Why |
|---|---|---|
| 0. Check Breaking Changes | Verify public API compatibility | Breaking changes break all user code |
| 1. Fetch Spec | Get OpenAPI JSON for the endpoint | Source of truth for review decisions |
| 2. Compare Parameters | Verify ALL query/path/body params match spec | Missing parameters = incomplete functionality |
| 3. Verify Models | Check response properties align with spec exactly | Wrong mapping = API contract violation |
| 4. Validate Tests | Confirm tests cover ALL spec-defined properties | Gaps in tests = unverified functionality |
| 5. Verify Async Parity | Confirm *Async method exists with full async test coverage | Async is a mandatory, blocking requirement |
| 6. Check Architecture | Evaluate patterns, deprecations, code quality | Only after functional correctness verified |
digraph review_endpoint {
"PR submitted" [shape=doublecircle];
"Check for breaking changes" [shape=diamond];
"Breaking changes found?" [shape=diamond];
"Documented by author?" [shape=diamond];
"BLOCK - Request changes" [shape=box, style=filled, fillcolor=red];
"Verify migration guide" [shape=box];
"Fetch OpenAPI spec" [shape=box];
"Find endpoint in spec" [shape=box];
"Extract spec definition" [shape=box];
"Compare parameters" [shape=diamond];
"Compare response schema" [shape=diamond];
"Verify test coverage" [shape=diamond];
"Check architecture" [shape=diamond];
"Document issues" [shape=box];
"Request changes" [shape=box];
"Approve PR" [shape=box];
"Done" [shape=doublecircle];
"PR submitted" -> "Check for breaking changes";
"Check for breaking changes" -> "Breaking changes found?";
"Breaking changes found?" -> "Documented by author?" [label="yes"];
"Breaking changes found?" -> "Fetch OpenAPI spec" [label="no"];
"Documented by author?" -> "BLOCK - Request changes" [label="no"];
"Documented by author?" -> "Verify migration guide" [label="yes"];
"Verify migration guide" -> "Fetch OpenAPI spec";
"Fetch OpenAPI spec" -> "Find endpoint in spec";
"Find endpoint in spec" -> "Extract spec definition";
"Extract spec definition" -> "Compare parameters";
"Compare parameters" -> "Document issues" [label="mismatch"];
"Compare parameters" -> "Compare response schema" [label="match"];
"Compare response schema" -> "Document issues" [label="mismatch"];
"Compare response schema" -> "Verify test coverage" [label="match"];
"Verify test coverage" -> "Document issues" [label="incomplete"];
"Verify test coverage" -> "Check architecture" [label="complete"];
"Check architecture" -> "Document issues" [label="issues"];
"Check architecture" -> "Approve PR" [label="good"];
"Document issues" -> "Request changes";
"Request changes" -> "Done";
"BLOCK - Request changes" -> "Done";
"Approve PR" -> "Done";
}
Default spec location: https://developers.smartsheet.com/_spec/api/smartsheet/openapi.json
Fetch the spec before any review commentary:
curl -s https://developers.smartsheet.com/_spec/api/smartsheet/openapi.json > /tmp/smartsheet-openapi.json
Or use WebFetch if available.
No exceptions:
For the PR's target endpoint, extract:
Path and method:
/workspaces/{workspaceId}/folders)ALL request parameters:
{workspaceId})Response schema:
"required" array)Expected errors:
Create checklist of ALL spec parameters:
**Spec Parameters:**
- [ ] workspaceId (path, required)
- [ ] includeAll (query, boolean, optional)
- [ ] pageSize (query, integer, optional, default 100)
- [ ] page (query, integer, optional, default 1)
**Implementation Parameters:**
- [x] workspaceId - ✓ present
- [x] pageSize - ✓ present
- [x] page - ✓ present
- [ ] includeAll - ✗ MISSING
Every missing parameter = REQUEST CHANGES
Compare model properties to spec schema:
**Spec Response Properties (Folder schema):**
- id (integer, optional)
- name (string, optional)
- permalink (string, optional)
- favorite (boolean, optional)
- createdAt (string/datetime, optional)
- modifiedAt (string/datetime, optional)
**C# Model Properties:**
- [x] Id - ✓ present
- [x] Name - ✓ present
- [x] Permalink - ✓ present
- [ ] Favorite - ✗ MISSING
- [ ] CreatedAt - ✗ MISSING
- [ ] ModifiedAt - ✗ MISSING
Missing properties in model = REQUEST CHANGES
Extra properties not in spec = COMMENT (might be tech debt, not blocking)
Check spec's "required" array:
{
"Folder": {
"required": [], // Empty array = ALL properties optional
"properties": { ... }
}
}
If implementation treats optional fields as required (e.g., throws on null) = REQUEST CHANGES
Tests must verify EVERY spec-defined aspect:
JsonConvert.SerializeObject(new Dictionary<string, object>{...}), compared against foundRequest.BodyRequired: Two test methods
Required properties test:
[TestMethod]
public void Test{Method}RequiredResponseProperties()
"required" array"required": [], test minimal valid responseAll properties test:
[TestMethod]
public void Test{Method}AllResponseProperties()
Compare test assertions to spec properties:
**Spec properties:** id, name, permalink, favorite, createdAt, modifiedAt (6 total)
**Test assertions:** id, name, permalink (3 total)
**Missing from tests:** favorite, createdAt, modifiedAt
= REQUEST CHANGES (incomplete test coverage)
Minimum required (if spec defines these):
Each error test must:
A new or modified endpoint with an *Async method requires full async parity. Confirm all four async tests exist:
Test{Method}AsyncGeneratedUrlIsCorrectTest{Method}AsyncAllResponseBodyPropertiesTest{Method}AsyncError400ResponseTest{Method}AsyncError500ResponseAlso verify:
public async Task (never async void)AssertRaisesExceptionAsync (not the sync AssertRaisesException)*Async method is declared on BOTH the public interface and the *Impl.GetAwaiter().GetResult() (not .Result/.Wait())Missing *Async method OR missing async tests = REQUEST CHANGES.
Only after spec compliance verified, check:
Pattern consistency:
Deprecation status:
Code quality:
Architecture issues are COMMENTS unless:
CRITICAL - ALWAYS BLOCKING:
SPEC COMPLIANCE - BLOCKING:
*Async counterpart for a new/modified endpoint*Async tests)ARCHITECTURE - BLOCKING:
ALL of the following:
| Mistake | Fix |
|---|---|
| "Tests pass, must be correct" | Tests validate what was tested, not what should be tested. Check spec. |
| "Experienced author, trust them" | Everyone makes mistakes. Spec verification is non-negotiable. |
| "Architecture looks good, approve" | Architecture ≠ correctness. Verify spec first. |
| "Time pressure, quick approval" | Wrong approval merged takes longer to fix than proper review. |
| "Pattern matches existing code" | Existing code may have bugs. Patterns propagate mistakes. |
| "Build green means ready" | Build verifies compilation, not spec compliance. |
All of these mean: STOP. Fetch spec. Verify systematically.
| Excuse | Reality |
|---|---|
| "Too tedious to check every property" | Missing properties = broken API. Check them all. |
| "Tests existing means tested well" | Tests must match spec, not implementation assumptions. |
| "Would slow down review process" | Wrong code merged is slower than thorough review. |
| "Author already checked spec" | You're the reviewer. You check spec. |
| "Architectural issues more important" | Spec compliance is non-negotiable. Architecture is negotiable. |
| "This is a minor change" | Minor changes can have major spec violations. |
### Stage 0: Breaking Changes Check (FIRST - CRITICAL)
- [ ] Checked for method signature changes
- [ ] Checked for removed/reordered parameters
- [ ] Checked for removed properties/methods
- [ ] Checked for return type changes
- [ ] If breaking changes found: PR description states "BREAKING CHANGE"?
- [ ] If breaking changes found: Migration guide provided?
- [ ] If breaking changes found: CHANGELOG updated?
**If breaking changes found and NOT documented → IMMEDIATELY REQUEST CHANGES**
### Stage 1: Spec Compliance (MANDATORY)
- [ ] Fetched OpenAPI spec
- [ ] Verified ALL parameters present
- [ ] Verified ALL response properties present
- [ ] Verified required/optional correct
- [ ] Verified test coverage complete
- [ ] Verified error handling complete
- [ ] Verified `*Async` counterpart exists (interface + impl)
- [ ] Verified all four `*Async` tests present and using `AssertRaisesExceptionAsync` for errors
**If any unchecked → REQUEST CHANGES**
### Stage 2: Architecture Review (AFTER Stage 0 & 1)
- [ ] Pattern consistency
- [ ] Deprecation status
- [ ] Code quality
- [ ] Documentation
**Issues here → COMMENT or REQUEST CHANGES depending on severity**
Use this template for API endpoint reviews:
## Spec Compliance Verification
**Endpoint:** `{METHOD} {path}`
**OpenAPI Spec:** [Verified ✓]
### Parameters
- [x] param1 - present
- [x] param2 - present
- [ ] param3 - **MISSING from implementation**
### Response Properties
Checked against spec schema `{SchemaName}`:
- [x] property1 - present and tested
- [x] property2 - present and tested
- [ ] property3 - present but **NOT TESTED**
- [ ] property4 - **MISSING from model**
### Test Coverage
- [x] URL generation tested
- [x] Required properties tested
- [ ] All properties tested - **INCOMPLETE**
- [x] 404 error tested
- [x] 500 error tested
- [ ] 400 error tested - **MISSING**
- [x] Async URL generation tested
- [x] Async all-properties tested
- [ ] Async 400/500 errors tested - **verify**
### Required/Optional Handling
- [x] Spec `"required": []` - all properties optional
- [x] Implementation treats fields as optional
- [x] Tests don't assume required fields
## Architecture Review
- [x] Extends AbstractResources
- [x] Uses SDK helper methods
- [x] No deprecated patterns
- [x] No duplicate functionality
## Decision
**REQUEST CHANGES** due to:
1. Missing param3 parameter
2. Missing property4 in model
3. Incomplete test coverage for all properties
4. Missing 400 error test
## Detailed Issues
[List specific findings with line numbers and fix suggestions]
Following spec-first review:
Example from baseline testing: Reviewer caught architectural issues but would have approved without spec check, missing: exclude parameter, wrong documentation (500 vs 10,000 rows), untested properties.
Review order matters:
Never reverse this. Never skip step 1.
A spec-compliant implementation can be refactored for better architecture.
An architecturally perfect implementation of the wrong API is just wrong.
Spec verification is not optional. It's not tedious. It's not slow. It's mandatory.