@@ -46,13 +46,17 @@ export async function createVersion(
4646}
4747
4848/**
49- * Get the next version number for a skill
49+ * Get the next version number for a skill.
50+ * Should be called inside a transaction session to avoid version number races.
5051 */
51- export async function getNextVersionNumber ( skillId : string ) : Promise < number > {
52+ export async function getNextVersionNumber (
53+ skillId : string ,
54+ session ?: ClientSession
55+ ) : Promise < number > {
5256 const lastVersion = await MongoAgentSkillsVersion . findOne (
5357 { skillId, isDeleted : false } ,
5458 { version : 1 } ,
55- { sort : { version : - 1 } }
59+ { sort : { version : - 1 } , session }
5660 ) . lean ( ) ;
5761
5862 return ( lastVersion ?. version ?? - 1 ) + 1 ;
@@ -140,7 +144,8 @@ export async function setActiveVersion(
140144}
141145
142146/**
143- * Soft delete a version
147+ * Soft delete a version.
148+ * Active versions cannot be deleted — deactivate or switch to another version first.
144149 */
145150export async function deleteVersion (
146151 skillId : string ,
@@ -157,18 +162,24 @@ export async function deleteVersion(
157162 throw new Error ( `Version ${ version } not found for skill ${ skillId } ` ) ;
158163 }
159164
160- // If this is the active version, we should not allow deletion
161- // or we should deactivate it first
162- const updateData : Record < string , any > = {
163- isDeleted : true ,
164- isActive : false
165- } ;
165+ // Refuse to delete the currently active version to prevent data orphaning
166+ if ( versionDoc . isActive ) {
167+ throw new Error (
168+ `Cannot delete active version ${ version } . Switch to another version before deleting.`
169+ ) ;
170+ }
166171
167- await MongoAgentSkillsVersion . updateOne ( { skillId, version } , { $set : updateData } , { session } ) ;
172+ await MongoAgentSkillsVersion . updateOne (
173+ { skillId, version } ,
174+ { $set : { isDeleted : true } } ,
175+ { session }
176+ ) ;
168177}
169178
170179/**
171- * Restore a deleted version
180+ * Restore a deleted version.
181+ * The restored version is set back to isDeleted=false but remains inactive (isActive=false).
182+ * Call setActiveVersion explicitly if you want to make it the active version.
172183 */
173184export async function restoreVersion (
174185 skillId : string ,
0 commit comments