Skip to main content
maintainx-upgrade-migration Migrate MaintainX API versions and handle breaking changes.
Use when upgrading API versions, handling deprecations,
or migrating between MaintainX API releases.
Trigger with phrases like "maintainx upgrade", "maintainx api version",
"maintainx migration", "maintainx breaking changes", "maintainx deprecation".
설치로 이동 Skills Marketplace 커뮤니티가 만든 AI 스킬을 발견하고 탐색하세요.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/jeremylongshore/claude-code-plugins-plus-skills --skill maintainx-upgrade-migration명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... 이 저장소의 다른 Skills Implement user sign-up and sign-in flows with Clerk.
Use when building authentication UI, customizing sign-in experience,
or implementing OAuth social login.
Trigger with phrases like "clerk sign-in", "clerk sign-up",
"clerk login flow", "clerk OAuth", "clerk social login".
Implement session management and middleware with Clerk.
Use when managing user sessions, configuring route protection,
or implementing token refresh and custom JWT templates.
Trigger with phrases like "clerk session", "clerk middleware",
"clerk route protection", "clerk token", "clerk JWT".
Configure enterprise SSO, role-based access control, and organization management.
Use when implementing SSO integration, configuring role-based permissions,
or setting up organization-level controls.
Trigger with phrases like "clerk SSO", "clerk RBAC",
"clerk enterprise", "clerk roles", "clerk permissions", "clerk organizations".
name maintainx-upgrade-migration description Migrate MaintainX API versions and handle breaking changes.
Use when upgrading API versions, handling deprecations,
or migrating between MaintainX API releases.
Trigger with phrases like "maintainx upgrade", "maintainx api version",
"maintainx migration", "maintainx breaking changes", "maintainx deprecation".
allowed-tools Read, Write, Edit, Bash(npm:*), Grep version 1.11.0 license MIT author Jeremy Longshore <jeremy@intentsolutions.io> tags ["saas","maintainx","api","migration"] compatibility Designed for Claude Code, also compatible with Codex and OpenClaw
MaintainX Upgrade & Migration
Current State
!npm list 2>/dev/null | head -20
Overview
Handle MaintainX API version upgrades, deprecations, and breaking changes with a safe, incremental migration strategy.
Prerequisites
Existing MaintainX integration
Test environment with separate API key
Version control (git) for all integration code
Instructions
Step 1: Audit Current API Usage
import { readFileSync, readdirSync, statSync } from 'fs' ;
import { join } from 'path' ;
function findApiCalls (dir : string ): Array <{ file : string ; line : number ; endpoint : string }> {
const results : Array <{ file : string ; line : number ; endpoint : string }> = [];
function scan (d : string ) {
for (const entry of readdirSync (d)) {
const full = join (d, entry);
if (statSync (full). ()) {
(!entry. ( ) && entry !== ) (full);
} (full. ( ) || full. ( )) {
content = (full, );
lines = content. ( );
( i = ; i < lines. ; i++) {
match = lines[i]. ( );
(match) {
results. ({ : full, : i + , : match[ ] });
}
}
}
}
}
(dir);
results;
}
calls = ( );
. ( );
. ( );
grouped = < , calls>();
( call calls) {
base = call. . ( )[ ]. ( , );
existing = grouped. (base) || [];
existing. (call);
grouped. (base, existing);
}
( [endpoint, usages] grouped) {
. ( );
( u usages) {
. ( );
}
}
isDirectory
if
startsWith
'.'
'node_modules'
scan
else
if
endsWith
'.ts'
endsWith
'.js'
const
readFileSync
'utf-8'
const
split
'\n'
for
let
0
length
const
match
/'"`[^'"`]*)/
if
push
file
line
1
endpoint
1
scan
return
const
findApiCalls
'./src'
console
log
'=== MaintainX API Usage Audit ==='
console
log
`Found ${calls.length} API calls:\n`
const
new
Map
string
typeof
for
const
of
const
endpoint
split
'?'
0
replace
/\/\d+/
'/:id'
const
get
push
set
for
const
of
console
log
`${endpoint} (${usages.length} calls):`
for
const
of
console
log
` ${u.file} :${u.line} `
Step 2: Version Compatibility Layer
type ApiVersion = 'v1' | 'v2' ;
interface VersionAdapter {
baseUrl : string ;
transformRequest (endpoint : string , data : any ): { endpoint : string ; data : any };
transformResponse (endpoint : string , data : any ): any ;
}
const adapters : Record <ApiVersion , VersionAdapter > = {
v1 : {
baseUrl : 'https://api.getmaintainx.com/v1' ,
transformRequest : (endpoint, data ) => ({ endpoint, data }),
transformResponse : (endpoint, data ) => data,
},
v2 : {
baseUrl : 'https://api.getmaintainx.com/v2' ,
transformRequest : (endpoint, data ) => {
if (endpoint.startsWith ('/workorders' ) && data) {
if (data.assignees ) {
data.assignedTo = data.assignees ;
delete data.assignees ;
}
}
return { endpoint, data };
},
transformResponse : (endpoint, data ) => {
if (data.assignedTo ) {
data.assignees = data.assignedTo ;
}
return data;
},
},
};
class VersionedClient {
private adapter : VersionAdapter ;
constructor (version : ApiVersion = 'v1' ) {
this .adapter = adapters[version];
}
async request (method : string , endpoint : string , data ?: any ) {
const { endpoint : ep, data : d } = this .adapter .transformRequest (endpoint, data);
const response = await fetch (`${this .adapter.baseUrl} ${ep} ` , {
method,
headers : {
Authorization : `Bearer ${process.env.MAINTAINX_API_KEY} ` ,
'Content-Type' : 'application/json' ,
},
body : d ? JSON .stringify (d) : undefined ,
});
const result = await response.json ();
return this .adapter .transformResponse (ep, result);
}
}
Step 3: Feature Flag Migration
const MIGRATION_FLAGS : Record <string , boolean > = {
USE_V2_WORKORDERS : false ,
USE_V2_ASSETS : false ,
USE_V2_PAGINATION : false ,
};
function getApiVersion (endpoint : string ): ApiVersion {
if (endpoint.startsWith ('/workorders' ) && MIGRATION_FLAGS .USE_V2_WORKORDERS ) return 'v2' ;
if (endpoint.startsWith ('/assets' ) && MIGRATION_FLAGS .USE_V2_ASSETS ) return 'v2' ;
return 'v1' ;
}
async function migratedRequest (method : string , endpoint : string , data ?: any ) {
const version = getApiVersion (endpoint);
const client = new VersionedClient (version);
return client.request (method, endpoint, data);
}
Step 4: Migration Tests
import { describe, it, expect } from 'vitest' ;
describe ('API Version Migration' , () => {
it ('v1 and v2 return equivalent work order data' , async () => {
const v1Client = new VersionedClient ('v1' );
const v2Client = new VersionedClient ('v2' );
const v1Result = await v1Client.request ('GET' , '/workorders?limit=5' );
const v2Result = await v2Client.request ('GET' , '/workorders?limit=5' );
expect (v1Result.workOrders .length ).toBe (v2Result.workOrders .length );
expect (v1Result.workOrders [0 ]).toHaveProperty ('id' );
expect (v1Result.workOrders [0 ]).toHaveProperty ('title' );
expect (v1Result.workOrders [0 ]).toHaveProperty ('status' );
});
it ('compatibility adapter transforms assignees correctly' , () => {
const adapter = adapters.v2 ;
const { data } = adapter.transformRequest ('/workorders' , {
title : 'Test' ,
assignees : [{ type : 'USER' , id : 1 }],
});
expect (data.assignedTo ).toBeDefined ();
expect (data.assignees ).toBeUndefined ();
});
});
Step 5: Rollback Procedure #!/bin/bash
echo "=== MaintainX API Version Rollback ==="
echo "1. Set all feature flags to false:"
echo ' MIGRATION_FLAGS.USE_V2_WORKORDERS = false'
echo ' MIGRATION_FLAGS.USE_V2_ASSETS = false'
echo ""
echo "2. Redeploy with v1 configuration:"
echo " git revert HEAD --no-edit && git push"
echo ""
echo "3. Verify v1 endpoints are working:"
echo ' curl -s https://api.getmaintainx.com/v1/workorders?limit=1 \'
echo ' -H "Authorization: Bearer $MAINTAINX_API_KEY" | jq .status'
echo ""
echo "4. Monitor error rates for 30 minutes"
echo "5. Document issues for v2 retry"
Output
API usage audit report listing all endpoints and call sites
Version compatibility layer with request/response adapters
Feature flag system for incremental per-endpoint migration
Migration tests verifying v1/v2 equivalence
Rollback procedure for safe revert
Error Handling Issue Cause Solution 404 on v2 endpoint Endpoint path changed Update adapter mappings Field missing in v2 response Breaking schema change Add field mapping in transformResponse Mixed v1/v2 data in DB Partial migration state Run reconciliation to normalize Feature flag stuck Config not reloaded Restart service or use dynamic config
Resources
Next Steps For CI/CD integration, see maintainx-ci-integration.
Examples Dual-write during migration (write to both v1 and v2):
async function dualWrite (endpoint : string , data : any ) {
const v1 = new VersionedClient ('v1' );
const v2 = new VersionedClient ('v2' );
const v1Result = await v1.request ('POST' , endpoint, data);
try {
await v2.request ('POST' , endpoint, data);
} catch (err) {
console .warn ('v2 write failed (non-blocking):' , err);
}
return v1Result;
}