Skip to main content

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 repository
  • createCategory(work, user, data) -- create a new category with auto-generated slug, duplicate name detection
  • updateCategory(work, user, categoryId, data) -- update category name/description with rename conflict checking
  • deleteCategory(work, user, categoryId) -- remove a category from the taxonomy

Tag operations:

  • getTags(work, user) -- retrieve all tags
  • createTag(work, user, data) -- create a new tag with slug generation
  • updateTag(work, user, tagId, data) -- update tag properties
  • deleteTag(work, user, tagId) -- remove a tag

Collection operations:

  • getCollections(work, user) -- retrieve all collections
  • createCollection(work, user, data) -- create a new collection
  • updateCollection(work, user, collectionId, data) -- update collection properties
  • deleteCollection(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() -- reads categories.yml from the repository root
  • getTags() -- reads tags.yml from the repository root
  • getCollections() -- reads collections.yml from 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) -- writes categories.yml and commits
  • saveTags(work, user, tags) -- writes tags.yml and commits
  • saveCollections(work, user, collections) -- writes collections.yml and 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

DependencyPurpose
@ever-works/contractsCategory, Tag, Collection type definitions
@ever-works/agent/generatorsDataGeneratorService for Git-backed persistence
@ever-works/agent/utilsslugifyText for ID generation
@ever-works/agent/facadesGitFacadeService (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']
});