Skip to main content 홈 크리에이터 jeremylongshore tons-of-skills-marketplace maintainx-upgrade-migration
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/tons-of-skills-marketplace --skill maintainx-upgrade-migration명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
Zip 다운로드 다운로드 중... 이 저장소의 다른 Skills langchain-deploy-integration Deploy a LangChain 1.0 / LangGraph 1.0 app to Cloud Run, Vercel, or LangServe correctly — with timeouts sized for chain length, cold-start mitigation, SSE anti-buffering headers, and Secret Manager over .env. Use when prepping a first production deploy, debugging a stream that hangs behind a proxy, or diagnosing p99 latency spikes. Trigger with "langchain deploy", "langchain cloud run", "langchain vercel python", "langchain langserve", or "langchain docker".
langchain-langgraph-agents Build a correct LangGraph 1.0 ReAct agent with create_react_agent — typed tools, error propagation, recursion caps, and stop conditions that actually stop. Use when writing a first tool-calling agent, migrating from AgentExecutor or initialize_agent, or diagnosing an agent that loops on vague prompts. Trigger with "langgraph agent", "create_react_agent", "langgraph tool calling", "AgentExecutor migration", or "agent loop cost".
langchain-langgraph-human-in-loop Build LangGraph 1.0 human-in-the-loop approval flows with interrupt_before /
interrupt_after and Command(resume=...) — JSON-serializable state, clean
resume semantics, and UI wiring for approval decisions. Use when adding an
approval gate before an expensive tool call, wiring a Slack/web UI for agent
approvals, or debugging a graph that crashes on interrupt.
Trigger with "langgraph human in loop", "langgraph interrupt_before",
"langgraph approval flow", "Command resume", "langgraph HITL".
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
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;
}