brainy/src/types/typeMigration.ts

175 lines
4.7 KiB
TypeScript
Raw Normal View History

/**
* Type Migration Utilities for Stage 3 Taxonomy (v6.0.0)
*
* Provides migration helpers for code using removed types from v5.x
*
* ## Removed Types
*
* ### Nouns (2 removed):
* - `user` merged into `person`
* - `topic` merged into `concept`
*
* ### Verbs (4 removed):
* - `succeeds` use inverse of `precedes`
* - `belongsTo` use inverse of `owns`
* - `createdBy` use inverse of `creates`
* - `supervises` use inverse of `reportsTo`
*/
import { NounType, VerbType } from './graphTypes.js'
/**
* Migration mapping for removed noun types
*/
export const REMOVED_NOUN_TYPES = {
user: NounType.Person,
topic: NounType.Concept
} as const
/**
* Migration mapping for removed verb types
* Note: Some verbs should use inverse relationships in Stage 3
*/
export const REMOVED_VERB_TYPES = {
succeeds: VerbType.Precedes, // Use with inverted source/target
belongsTo: VerbType.Owns, // Use with inverted source/target
createdBy: VerbType.Creates, // Use with inverted source/target
supervises: VerbType.ReportsTo // Use with inverted source/target
} as const
/**
* Check if a type was removed in Stage 3
*/
export function isRemovedNounType(type: string): type is keyof typeof REMOVED_NOUN_TYPES {
return type in REMOVED_NOUN_TYPES
}
/**
* Check if a verb type was removed in Stage 3
*/
export function isRemovedVerbType(type: string): type is keyof typeof REMOVED_VERB_TYPES {
return type in REMOVED_VERB_TYPES
}
/**
* Migrate a noun type from v5.x to v6.0 Stage 3
* Returns the migrated type or the original if no migration needed
*/
export function migrateNounType(type: string): NounType {
if (isRemovedNounType(type)) {
console.warn(`⚠️ NounType "${type}" was removed in v6.0. Migrating to "${REMOVED_NOUN_TYPES[type]}"`)
return REMOVED_NOUN_TYPES[type]
}
return type as NounType
}
/**
* Migrate a verb type from v5.x to v6.0 Stage 3
* Returns the migrated type or the original if no migration needed
*
* WARNING: Some verbs require inverting source/target relationships!
* See VERB_REQUIRES_INVERSION for details.
*/
export function migrateVerbType(type: string): VerbType {
if (isRemovedVerbType(type)) {
console.warn(`⚠️ VerbType "${type}" was removed in v6.0. Migrating to "${REMOVED_VERB_TYPES[type]}" (may require source/target inversion)`)
return REMOVED_VERB_TYPES[type]
}
return type as VerbType
}
/**
* Verbs that require inverting source/target when migrating
*
* Example:
* - Old: `A createdBy B` New: `B creates A`
* - Old: `A belongsTo B` New: `B owns A`
* - Old: `A supervises B` New: `B reportsTo A`
* - Old: `A succeeds B` New: `B precedes A`
*/
export const VERB_REQUIRES_INVERSION = new Set([
'succeeds',
'belongsTo',
'createdBy',
'supervises'
])
/**
* Check if a verb type requires inverting source/target during migration
*/
export function requiresInversion(oldVerbType: string): boolean {
return VERB_REQUIRES_INVERSION.has(oldVerbType)
}
/**
* Migrate a relationship, handling source/target inversion if needed
*
* @returns Object with migrated verb and potentially inverted source/target
*/
export function migrateRelationship(params: {
verb: string
source: string
target: string
}): {
verb: VerbType
source: string
target: string
inverted: boolean
} {
const verb = migrateVerbType(params.verb)
const inverted = requiresInversion(params.verb)
if (inverted) {
return {
verb,
source: params.target, // Swap source and target
target: params.source,
inverted: true
}
}
return {
verb,
source: params.source,
target: params.target,
inverted: false
}
}
/**
* Stage 3 Type Compatibility Check
* Helps developers identify code that needs updating for v6.0
*/
export function checkTypeCompatibility(nounTypes: string[], verbTypes: string[]): {
valid: boolean
removedNouns: string[]
removedVerbs: string[]
warnings: string[]
} {
const removedNouns = nounTypes.filter(isRemovedNounType)
const removedVerbs = verbTypes.filter(isRemovedVerbType)
const warnings: string[] = []
if (removedNouns.length > 0) {
warnings.push(
`Found ${removedNouns.length} removed noun type(s): ${removedNouns.join(', ')}. ` +
`These were merged in Stage 3. Use Person instead of User, Concept instead of Topic.`
)
}
if (removedVerbs.length > 0) {
warnings.push(
`Found ${removedVerbs.length} removed verb type(s): ${removedVerbs.join(', ')}. ` +
`These require using inverse relationships in Stage 3. ` +
`Example: "A createdBy B" becomes "B creates A".`
)
}
return {
valid: removedNouns.length === 0 && removedVerbs.length === 0,
removedNouns,
removedVerbs,
warnings
}
}