feat: comprehensive metadata namespace architecture and cleanup system
BREAKING CHANGE: Remove hard delete option from deleteVerb() for consistent API - Add complete metadata namespace architecture with O(1) soft delete performance - Implement periodic cleanup system for old soft-deleted items - Add restore methods for both nouns and verbs - Require metadata contracts for all augmentations - Eliminate namespace collisions with clean separation (_brainy, _augmentations, _audit) - Optimize index performance using flattened dot-notation for O(1) lookups - Add comprehensive augmentation safety system with type-safe access control - Maintain full backward compatibility for existing data - Add enterprise-grade cleanup with configurable age thresholds and batch processing 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
9220ca6748
commit
7e243b6f2b
35 changed files with 2700 additions and 125 deletions
|
|
@ -518,6 +518,38 @@ export class MetadataIndexManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all IDs in the index
|
||||
*/
|
||||
async getAllIds(): Promise<string[]> {
|
||||
// Collect all unique IDs from all index entries
|
||||
const allIds = new Set<string>()
|
||||
|
||||
// First, add all IDs from the in-memory cache
|
||||
for (const entry of this.indexCache.values()) {
|
||||
entry.ids.forEach(id => allIds.add(id))
|
||||
}
|
||||
|
||||
// If storage has a method to get all nouns, use it as the source of truth
|
||||
// This ensures we include items that might not be indexed yet
|
||||
if (this.storage && typeof (this.storage as any).getNouns === 'function') {
|
||||
try {
|
||||
const result = await (this.storage as any).getNouns({
|
||||
pagination: { limit: 100000 }
|
||||
})
|
||||
if (result && result.items) {
|
||||
result.items.forEach((item: any) => {
|
||||
if (item.id) allIds.add(item.id)
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
// Fall back to using only indexed IDs
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(allIds)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IDs for a specific field-value combination with caching
|
||||
*/
|
||||
|
|
@ -782,6 +814,25 @@ export class MetadataIndexManager {
|
|||
fieldResults = Array.from(allIds)
|
||||
}
|
||||
break
|
||||
|
||||
// Negation operators
|
||||
case 'notEquals':
|
||||
case 'isNot':
|
||||
case 'ne':
|
||||
// For notEquals, we need all IDs EXCEPT those matching the value
|
||||
// This is especially important for soft delete: deleted !== true
|
||||
// should include items without a deleted field
|
||||
|
||||
// First, get all IDs in the database
|
||||
const allItemIds = await this.getAllIds()
|
||||
|
||||
// Then get IDs that match the value we want to exclude
|
||||
const excludeIds = await this.getIds(field, operand)
|
||||
const excludeSet = new Set(excludeIds)
|
||||
|
||||
// Return all IDs except those to exclude
|
||||
fieldResults = allItemIds.filter(id => !excludeSet.has(id))
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue