Skip to main content
Glama
entities.test.ts6.97 kB
import { describe, it, expect } from '@jest/globals'; import type { Entity, Requirement, Solution, Decision, Phase, Link, PlanManifest, Tag, EntityType, RelationType, } from '../../src/domain/entities/types.js'; describe('Entity Types', () => { describe('Tag', () => { it('should have key and value', () => { const tag: Tag = { key: 'priority', value: 'high' }; expect(tag.key).toBe('priority'); expect(tag.value).toBe('high'); }); }); describe('EntityType', () => { it('should support all entity types', () => { const types: EntityType[] = ['requirement', 'solution', 'decision', 'phase']; expect(types).toHaveLength(4); }); }); describe('Requirement', () => { it('should have all required fields', () => { const requirement: Requirement = { id: 'req-001', type: 'requirement', createdAt: '2024-12-01T10:00:00Z', updatedAt: '2024-12-01T10:00:00Z', version: 1, metadata: { createdBy: 'claude-code', tags: [{ key: 'feature', value: 'auth' }], annotations: [], }, title: 'User Authentication', description: 'Users can login with email/password', source: { type: 'user-request' }, acceptanceCriteria: ['Login works', 'JWT returned'], priority: 'critical', category: 'functional', status: 'draft', }; expect(requirement.type).toBe('requirement'); expect(requirement.priority).toBe('critical'); expect(requirement.acceptanceCriteria).toHaveLength(2); }); it('should support optional fields', () => { const requirement: Requirement = { id: 'req-002', type: 'requirement', createdAt: '2024-12-01T10:00:00Z', updatedAt: '2024-12-01T10:00:00Z', version: 1, metadata: { createdBy: 'claude-code', tags: [], annotations: [] }, title: 'Performance', description: 'API response < 200ms', rationale: 'User experience', source: { type: 'derived', parentId: 'req-001' }, acceptanceCriteria: ['Response time measured'], priority: 'high', category: 'non-functional', status: 'approved', impact: { scope: ['api', 'database'], complexityEstimate: 7, riskLevel: 'medium', }, }; expect(requirement.rationale).toBe('User experience'); expect(requirement.impact?.riskLevel).toBe('medium'); }); }); describe('Solution', () => { it('should have tradeoffs', () => { const solution: Solution = { id: 'sol-001', type: 'solution', createdAt: '2024-12-01T10:00:00Z', updatedAt: '2024-12-01T10:00:00Z', version: 1, metadata: { createdBy: 'claude-code', tags: [], annotations: [] }, title: 'Use jsonwebtoken', description: 'JWT library for auth', approach: 'Install and configure jwt', tradeoffs: [ { aspect: 'Security', pros: ['Battle-tested'], cons: ['Additional dependency'], score: 8, }, ], addressing: ['req-001'], evaluation: { effortEstimate: { value: 4, unit: 'hours', confidence: 'high' }, technicalFeasibility: 'high', riskAssessment: 'Low risk', }, status: 'proposed', }; expect(solution.tradeoffs).toHaveLength(1); expect(solution.tradeoffs[0].score).toBe(8); }); }); describe('Phase', () => { it('should support hierarchy', () => { const phase: Phase = { id: 'phase-001', type: 'phase', createdAt: '2024-12-01T10:00:00Z', updatedAt: '2024-12-01T10:00:00Z', version: 1, metadata: { createdBy: 'claude-code', tags: [], annotations: [] }, title: 'Core Implementation', description: 'Build core features', parentId: null, order: 1, depth: 0, path: '1', objectives: ['Build auth'], deliverables: ['Login API'], successCriteria: ['Tests pass'], schedule: { estimatedEffort: { value: 2, unit: 'days', confidence: 'medium' }, }, status: 'planned', progress: 0, }; expect(phase.depth).toBe(0); expect(phase.path).toBe('1'); expect(phase.parentId).toBeNull(); }); it('should track status and progress', () => { const phase: Phase = { id: 'phase-002', type: 'phase', createdAt: '2024-12-01T10:00:00Z', updatedAt: '2024-12-01T12:00:00Z', version: 2, metadata: { createdBy: 'claude-code', tags: [], annotations: [] }, title: 'Login Implementation', description: 'Implement login endpoint', parentId: 'phase-001', order: 1, depth: 1, path: '1.1', objectives: ['Login endpoint'], deliverables: ['POST /api/auth/login'], successCriteria: ['Unit tests pass'], schedule: { estimatedEffort: { value: 4, unit: 'hours', confidence: 'high' }, actualEffort: 3.5, }, status: 'completed', progress: 100, startedAt: '2024-12-01T10:00:00Z', completedAt: '2024-12-01T12:00:00Z', }; expect(phase.status).toBe('completed'); expect(phase.progress).toBe(100); expect(phase.schedule.actualEffort).toBe(3.5); }); }); describe('Link', () => { it('should support all relation types', () => { const relations: RelationType[] = [ 'implements', 'addresses', 'depends_on', 'blocks', 'alternative_to', 'supersedes', 'references', 'derived_from', ]; expect(relations).toHaveLength(8); }); it('should have required fields', () => { const link: Link = { id: 'link-001', sourceId: 'sol-001', targetId: 'req-001', relationType: 'implements', createdAt: '2024-12-01T10:00:00Z', createdBy: 'claude-code', }; expect(link.relationType).toBe('implements'); }); }); describe('PlanManifest', () => { it('should have statistics', () => { const manifest: PlanManifest = { id: 'plan-001', name: 'Auth Implementation', description: 'Implement user authentication', status: 'active', author: 'claude-code', createdAt: '2024-12-01T10:00:00Z', updatedAt: '2024-12-01T10:00:00Z', version: 1, lockVersion: 1, statistics: { totalRequirements: 5, totalSolutions: 3, totalDecisions: 2, totalPhases: 4, totalArtifacts: 0, completionPercentage: 25, }, }; expect(manifest.statistics.totalRequirements).toBe(5); expect(manifest.lockVersion).toBe(1); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cppmyjob/cpp-mcp-planner'

If you have feedback or need assistance with the MCP directory API, please join our Discord server