Taxonomy Module
Overview
The Taxonomy module in @ever-works/agent manages the classification and organizational structures within a work -- categories, tags, and collections. These taxonomy elements are stored as YAML files in the data repository and provide the organizational backbone for work items.
Categories represent hierarchical groupings, tags provide flat labeling, and collections offer curated item groupings. The taxonomy service handles full CRUD operations with slug generation, duplicate detection, and persistence through the data generator layer.
Module Structure
packages/agent/src/
services/
work-taxonomy.service.ts # Full CRUD for categories, tags, collections
generators/
data-generator/
data-repository.ts # File I/O for taxonomy YAML files
data-generator.service.ts # Persistence layer (saveCategories, saveTags, etc.)
entities/
types.ts # Shared type definitions
Taxonomy types are defined in @ever-works/contracts:
packages/contracts/src/
types/
category.ts # Category interface
tag.ts # Tag interface
collection.ts # Collection interface
Key Classes and Services
WorkTaxonomyService
The primary service managing all taxonomy operations. It coordinates between the data repository (for reading current state) and the data generator service (for persisting changes).
Category operations:
getCategories(work, user)-- retrieve all categories from the data repositorycreateCategory(work, user, data)-- create a new category with auto-generated slug, duplicate name detectionupdateCategory(work, user, categoryId, data)-- update category name/description with rename conflict checkingdeleteCategory(work, user, categoryId)-- remove a category from the taxonomy
Tag operations:
getTags(work, user)-- retrieve all tagscreateTag(work, user, data)-- create a new tag with slug generationupdateTag(work, user, tagId, data)-- update tag propertiesdeleteTag(work, user, tagId)-- remove a tag
Collection operations:
getCollections(work, user)-- retrieve all collectionscreateCollection(work, user, data)-- create a new collectionupdateCollection(work, user, collectionId, data)-- update collection propertiesdeleteCollection(work, user, collectionId)-- remove a collection
Slug generation:
All taxonomy elements use slugifyText() from @ever-works/agent/utils to generate URL-safe identifiers from names. The function handles unicode normalization, special character removal, and whitespace-to-hyphen conversion.
Duplicate detection:
On both create and update operations, the service checks for existing elements with the same name (case-insensitive comparison). If a duplicate is found, an error is thrown before any persistence occurs.
DataRepository (Taxonomy Methods)
The DataRepository class provides file-level I/O for taxonomy data stored in the Git-backed data repository:
getCategories()-- readscategories.ymlfrom the repository rootgetTags()-- readstags.ymlfrom the repository rootgetCollections()-- readscollections.ymlfrom the repository root
DataGeneratorService (Persistence)
The DataGeneratorService provides the persistence layer that writes taxonomy changes back to the data repository and commits them via Git:
saveCategories(work, user, categories)-- writescategories.ymland commitssaveTags(work, user, tags)-- writestags.ymland commitssaveCollections(work, user, collections)-- writescollections.ymland commits
API Reference
WorkTaxonomyService
// Categories
getCategories(work: Work, user: User): Promise<Category[]>
createCategory(work: Work, user: User, data: CreateCategoryDto): Promise<Category>
updateCategory(work: Work, user: User, categoryId: string, data: UpdateCategoryDto): Promise<Category>
deleteCategory(work: Work, user: User, categoryId: string): Promise<void>
// Tags
getTags(work: Work, user: User): Promise<Tag[]>
createTag(work: Work, user: User, data: CreateTagDto): Promise<Tag>
updateTag(work: Work, user: User, tagId: string, data: UpdateTagDto): Promise<Tag>
deleteTag(work: Work, user: User, tagId: string): Promise<void>
// Collections
getCollections(work: Work, user: User): Promise<Collection[]>
createCollection(work: Work, user: User, data: CreateCollectionDto): Promise<Collection>
updateCollection(work: Work, user: User, collectionId: string, data: UpdateCollectionDto): Promise<Collection>
deleteCollection(work: Work, user: User, collectionId: string): Promise<void>
Configuration
Category Interface
interface Category {
id: string; // Auto-generated slug from name
name: string; // Display name
description?: string; // Optional description
icon?: string; // Optional icon identifier
order?: number; // Sort order
}
Tag Interface
interface Tag {
id: string; // Auto-generated slug from name
name: string; // Display name
description?: string;
}
Collection Interface
interface Collection {
id: string;
name: string;
description?: string;
items: string[]; // Array of item slugs
}
Data Repository Format
Taxonomy data is stored as YAML files in the data repository root:
# categories.yml
- id: developer-tools
name: Developer Tools
description: Tools for software development
order: 1
- id: ai-platforms
name: AI Platforms
description: AI and machine learning platforms
order: 2
# tags.yml
- id: open-source
name: Open Source
- id: freemium
name: Freemium
Dependencies
| Dependency | Purpose |
|---|---|
@ever-works/contracts | Category, Tag, Collection type definitions |
@ever-works/agent/generators | DataGeneratorService for Git-backed persistence |
@ever-works/agent/utils | slugifyText for ID generation |
@ever-works/agent/facades | GitFacadeService (via DataGeneratorService) for repository operations |
Usage Examples
Managing Categories
import { WorkTaxonomyService } from '@ever-works/agent/services';
// Create a category
const category = await taxonomyService.createCategory(work, user, {
name: 'Developer Tools',
description: 'Tools for software developers'
});
// category.id === 'developer-tools' (auto-generated slug)
// List all categories
const categories = await taxonomyService.getCategories(work, user);
// Update a category
await taxonomyService.updateCategory(work, user, 'developer-tools', {
name: 'Dev Tools',
description: 'Updated description'
});
// Delete a category
await taxonomyService.deleteCategory(work, user, 'developer-tools');
Managing Tags
const tag = await taxonomyService.createTag(work, user, {
name: 'Open Source'
});
// tag.id === 'open-source'
const tags = await taxonomyService.getTags(work, user);
Managing Collections
const collection = await taxonomyService.createCollection(work, user, {
name: 'Top Picks',
description: 'Our recommended tools',
items: ['vscode', 'github-copilot', 'cursor']
});