feat: migrate payment API to v2 schema#2
Conversation
|
❌ Decision: BLOCK • 🔴 Risk: 100/100 • ❌ Breaking: 13 • 🔍 Patterns: 13 • 🔴 CodeRifts — Risk Score: 100/100 (Critical)🏷️ Suggested version bump: 📌 Current version is v1.4.0 → next version should be v2.0.0 🛡️ Policy Violations🔴 Breaking budget exceeded: 13/3 allowed
❌ Why This PR Is BlockedThis PR is blocked because a policy rule was violated: Breaking budget exceeded: 13/3 allowed ✅ How to Unblock
🔬 Decision Audit — Ω_API V3
Reflex triggers:
Pattern config hash:
Risk Assessment
🔒 Security Analysis
🔒 Security score: 4/10 (poor) — 2 high findings 📊 API Stability Grade: F (critical risk) 🔧 Generator Impact AnalysisDetected generators:
📦 SDK Surface Impact2 generated SDKs detected in this repository:
Total SDK impact: 30 models and 0 methods across 2 SDKs need regeneration.
🔍 Top Detected Patterns
🔴 13 Breaking Changes Found
Change intent breakdown: 8 structural · 4 behavioral · 1 security 🤖 Agent Impact
🤖 How to update your agentThe following breaking changes affect AI agent workflows. Copy-paste ready migration code: Tool result shape changed (
|
| Pattern | Severity | Path | Field | Detail |
|---|---|---|---|---|
AUTH_FLOW_DRIFT |
🔴 CRITICAL | #/components/schemas/TokenResponse |
refresh_token |
refresh_token removed from auth response — clients will re-authenticate on every expiry |
NULLABLE_REMOVED |
🟠 HIGH | #/components/schemas/User |
phone |
field was nullable:true, now nullable:false (or removed) |
DEFAULT_VALUE_CHANGE |
🟠 HIGH | #/components/schemas/Order |
currency |
default changed from "USD" to "EUR" |
🪦 REST in peace:
/internal/health·/payments/refund— removed in this PR
📝 API Changelog
Breaking
- Removed endpoint
/internal/health - Removed endpoint
/payments/refund - Removed field
fieldfromGET /ordersresponse - Removed field
fieldfromPOST /ordersresponse - Removed field
fieldfromGET /orders/{id}response - Breaking change in
POST /payments/charge—response.status-code.remove - Removed field
fieldfromPOST /usersrequest - Removed field
namefromPOST /usersresponse - Breaking change in
GET /users/{id}—response.status-code.remove - Removed field
namefromGET /users/{id}response - Modified auth requirements on
POST /payments/charge - Breaking change in
Enum value 'pending' removed from 'status' in schema 'Order'—request-property-enum-value-removed - Breaking change in
Property 'total' in schema 'Order' type changed from 'number' to 'string'—response-property-type-changed
Added
- New endpoint
/payments/v2/refund - New endpoint
/v1/legacy/status - New optional field
fieldinPOST /webhooks/subscriberequest
Changed
- Removed field
fieldfromGET /ordersresponse - Removed field
fieldfromPOST /ordersresponse - Removed field
fieldfromGET /orders/{id}response - Removed field
namefromPOST /usersresponse - Removed field
namefromGET /users/{id}response
💡 Recommendations
- 📢 Notify external consumers — public endpoint(s) affected, prepare migration communication
- 📱 Mobile app update needed — Breaks iOS 3.2, Android 4.0
- 🔒 Security review required — OAuth scope changed
- 👤 Domain owner sign-off needed — critical domain affected
- 💰 Estimated migration impact — ~20 eng. day(s), ~$60,000
- 🔄 Consider creating replacement endpoints instead of removing:
• /payments/refund → /v2/payments/refund
💾 Migration & Impact Assessment
Rollback risk: 🔴 Hard to revert
Review estimate: ⏳ 1+ hours
| Icon | Trigger | Action needed |
|---|---|---|
| 🔄 | Response field field removed from GET /orders |
Cached responses may contain this field — consider cache invalidation |
| 🔄 | Response field field removed from POST /orders |
Cached responses may contain this field — consider cache invalidation |
| 🔄 | Response field field removed from GET /orders/{id} |
Cached responses may contain this field — consider cache invalidation |
| 🔄 | Response field field removed from POST /users |
Cached responses may contain this field — consider cache invalidation |
| 🔄 | Response field field removed from GET /users/{id} |
Cached responses may contain this field — consider cache invalidation |
| 💾 | New required field field in POST /webhooks/subscribe |
Ensure database column exists with a default value for existing rows |
| 🗄️ | New endpoint POST /payments/v2/refund |
New resource — verify database tables/collections exist |
| 🗄️ | New endpoint GET /v1/legacy/status |
New resource — verify database tables/collections exist |
✅ Pre-merge checklist
- Verify API documentation is updated
- Notify downstream consumers of breaking changes
- Update API client SDKs if applicable
- Check mobile app compatibility
- Run database migration before deploying
- Verify migration is backward-compatible (can roll back)
- Invalidate response caches after deploy
- Add integration tests for new endpoint(s)
💰 Economic Impact Estimate
├── Migration cost: $78,000 (520 eng-hours × $150/hr)
├── Testing cost: $117,000 (780 eng-hours × $150/hr)
├── Rollback risk: $234,000 (if rollback needed)
├── Downstream consumers: 1 service
└── Total estimated impact: $195,000
ℹ️ CodeRifts detected this before merge. Monthly cost: $49. Estimated impact prevented: $195,000.
⏰ Deprecation Calendar
| Endpoint | Deprecated Since | Scheduled Removal | Status |
|---|---|---|---|
POST /payments/refund |
— | 2026-04-01 (17d) | 🔴 Removal imminent |
👥 No
CODEOWNERSfile found. Consider adding one to auto-assign reviewers for API changes:# .github/CODEOWNERS # Auto-generated from .coderifts.yml domains api/openapi.yaml @payments-team @backend-team
📍 URL versioning detected (v1, v2). Breaking changes should go into a new version prefix rather than modifying existing endpoints.
📏 API Design Lint — 8 warnings
| Rule | Endpoint | Details |
|---|---|---|
POST /payments/charge |
POST uses 200 instead of 201 for resource creation | |
POST /payments/v2/refund |
POST uses 200 instead of 201 for resource creation | |
GET /v1/legacy/status |
Has 200 but no 4xx/5xx responses defined | |
/payments/refund |
Singular /refund — most paths use plural convention |
|
/payments/charge |
Singular /charge — most paths use plural convention |
|
/payments/v2/refund |
Singular /refund — most paths use plural convention |
|
/v1/legacy/status |
Singular /legacy — most paths use plural convention |
|
/webhooks/subscribe |
Singular /subscribe — most paths use plural convention |
⌛ Deprecation Lifecycle
| Item | Deprecated Since | Sunset Date | Days Active | Status |
|---|---|---|---|---|
paths./users.post.requestBody.content.application/json.schema |
(not deprecated) | — | — | 🔴 Missing deprecation period |
Deprecation policy: Minimum 30 days before removal.
Currently deprecated (not removed in this PR):
GET /v1/legacy/status— sunset: 2026-07-15 (121 days remaining) → useGET /internal/health
🔒 Auth Change Analysis
| Severity | Finding | Endpoint | Details |
|---|---|---|---|
| 🟠 High | Auth scheme downgraded | POST /payments/charge |
Was: bearer (bearerAuth), OAuth2 (oauth2). Now: API key in header (apiKey) |
| 🟠 High | OAuth scope removed | POST /payments/charge |
Removed scope: payments:write |
🔒 Auth change severity: 2 high
⚠️ Generated Spec Drift Warning
The OpenAPI spec api/openapi.yaml appears to be generated by OpenAPI Generator but was modified directly in this PR.
Drift confidence: 40% (medium)
Detected signals:
- 🔧 Generator config was not changed in this PR
- ✏️ Source annotations/code were not modified
Risk: Manual changes to generated specs will be overwritten on next generation. This can cause:
- Silent loss of the changes in this PR
- Merge conflicts when regenerating
- Inconsistency between source code and API contract
Recommended actions:
- Update the source (code annotations, config, or source spec) instead of editing the generated output
- Regenerate the spec from the updated source
- If this is an intentional override, add the file to
.openapi-generator-ignoreorgenerator_drift.ignore_filesin.coderifts.yml
📖 Documentation Coverage
Overall coverage: 87% ⬇️ (-5 from base)
| Schema | Score | Grade | Delta | Top Gap |
|---|---|---|---|---|
| api/openapi.yaml | 87% | 🟡 B (Good) | ⬇️ -5 | Examples (22%) |
📋 Raw diff details
path.remove— paths./internal/health (api/openapi.yaml)path.remove— paths./payments/refund (api/openapi.yaml)response.body.scope.add— paths./orders.get.responses.200.content.application/json.schema (api/openapi.yaml)response.body.scope.add— paths./orders.post.responses.201.content.application/json.schema (api/openapi.yaml)response.body.scope.add— paths./orders/{id}.get.responses.200.content.application/json.schema (api/openapi.yaml)response.status-code.remove— paths./payments/charge.post.responses.422 (api/openapi.yaml)request.body.scope.remove— paths./users.post.requestBody.content.application/json.schema (api/openapi.yaml)response.body.scope.add— paths./users.post.responses.201.content.application/json.schema (api/openapi.yaml)response.status-code.remove— paths./users/{id}.get.responses.401 (api/openapi.yaml)response.body.scope.add— paths./users/{id}.get.responses.200.content.application/json.schema (api/openapi.yaml)api-security-removed— paths./payments/charge.post.security (api/openapi.yaml)request-property-enum-value-removed— schemas.Order.status (api/openapi.yaml)response-property-type-changed— schemas.Order.total (api/openapi.yaml)path.add— paths./payments/v2/refund (api/openapi.yaml)path.add— paths./v1/legacy/status (api/openapi.yaml)response.body.scope.remove— paths./orders.get.responses.200.content.application/json.schema (api/openapi.yaml)response.body.scope.remove— paths./orders.post.responses.201.content.application/json.schema (api/openapi.yaml)response.body.scope.remove— paths./orders/{id}.get.responses.200.content.application/json.schema (api/openapi.yaml)response.body.scope.remove— paths./users.post.responses.201.content.application/json.schema (api/openapi.yaml)response.body.scope.remove— paths./users/{id}.get.responses.200.content.application/json.schema (api/openapi.yaml)request.body.scope.add— paths./webhooks/subscribe.post.requestBody.content.application/json.schema (api/openapi.yaml)
👥 Breaking change in
paymentsdomain — notify @Payments-Team
👥 Breaking change inusersdomain — notify @backend-team
💸 Removed without deprecation period — compatibility debt:
/internal/health
💸 Removed without deprecation period — compatibility debt:/payments/refund
💸 Breaking change in critical domainpayments— high compatibility debt:/payments/refund
💸 Breaking change in critical domainpayments— high compatibility debt:/payments/charge
💸 Breaking change in critical domainpayments— high compatibility debt:/payments/charge
📝 Documentation Drift
✅ Documentation files updated alongside API changes.
Updated: README.md
🏛️ Governance Health: A (95/100)
📋 Policy
| Rule | Condition | Action | Status |
|---|---|---|---|
| block-endpoint-removal | endpoint_removed | BLOCK | ✅ not triggered |
| warn-high-risk | risk_score >= 80 | WARN | ⛔ triggered |
Effective action: WARN (policy: warn-high-risk)
📋 Action Items
- Review all breaking changes above
- Update MCP manifest if agent-facing endpoints changed
- Prepare consumer-facing changelog
- Define rollout plan before merge
📊 API surface: 9 endpoints · 32 fields · 9 schemas
⚙️ Configure in .coderifts.yml · 🔗 CodeRifts
🎋 An endpoint departs
🎋 Clients still call its name in vain
🎋 Four-oh-four remains
☁️ You're on the Free plan. Pro features (risk scoring, governance, deprecation enforcement) are included during the beta. Lock in Pro pricing →
⏱️ PR Review Insights
This PR
| Metric | Value | Benchmark |
|---|---|---|
| Time to First Review | Awaiting review | — |
| Review Rounds | 0 | 🟢 Normal |
| PR Size | +138 / -116 | 🟡 Medium |
b33eca6 to
14ac7e1
Compare
|
/risk |
11 similar comments
|
/risk |
|
/risk |
|
/risk |
|
/risk |
|
/risk |
|
/risk |
|
/risk |
|
/risk |
|
/risk |
|
/risk |
|
/risk |
08bc46b to
8a3c6ce
Compare
|
/risk |
2 similar comments
|
/risk |
|
/risk |
|
/rerun |
2 similar comments
|
/rerun |
|
/rerun |
|
/risk |
|
/changelog |
|
/rerun |
|
/rerun |
9 similar comments
|
/rerun |
|
/rerun |
|
/rerun |
|
/rerun |
|
/rerun |
|
/rerun |
|
/rerun |
|
/rerun |
|
/rerun |
Migrates the payment API to v2, consolidating endpoints and updating
field naming conventions to match our new API style guide.
Changes:
This is part of the Q1 API modernization initiative.