feat: add topic alias resolution APIs
This commit is contained in:
@@ -51,4 +51,41 @@ describe('IdentityDB topic and fact writes', () => {
|
||||
expect(typeScriptFacts).toHaveLength(1);
|
||||
expect(typeScriptFacts[0]?.statement).toBe('I have worked with TypeScript since 2025.');
|
||||
});
|
||||
|
||||
it('resolves alias names to a canonical topic', async () => {
|
||||
await db.upsertTopic({
|
||||
name: 'TypeScript',
|
||||
category: 'entity',
|
||||
granularity: 'concrete',
|
||||
});
|
||||
|
||||
await db.addTopicAlias('TypeScript', 'TS');
|
||||
|
||||
const resolved = await db.resolveTopic('ts');
|
||||
const aliases = await db.getTopicAliases('TypeScript');
|
||||
|
||||
expect(resolved?.name).toBe('TypeScript');
|
||||
expect(aliases).toEqual(['TS']);
|
||||
});
|
||||
|
||||
it('reuses the canonical topic when a fact is added through an alias', async () => {
|
||||
await db.upsertTopic({
|
||||
name: 'TypeScript',
|
||||
category: 'entity',
|
||||
granularity: 'concrete',
|
||||
});
|
||||
|
||||
await db.addTopicAlias('TypeScript', 'TS');
|
||||
|
||||
await db.addFact({
|
||||
statement: 'TS compiles to JavaScript.',
|
||||
topics: [{ name: 'TS', category: 'entity', granularity: 'concrete' }],
|
||||
});
|
||||
|
||||
const topics = await db.listTopics({ includeFacts: false });
|
||||
const facts = await db.getTopicFacts('TypeScript');
|
||||
|
||||
expect(topics.map((topic) => topic.name)).toEqual(['TypeScript']);
|
||||
expect(facts.map((fact) => fact.statement)).toEqual(['TS compiles to JavaScript.']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@ afterEach(async () => {
|
||||
});
|
||||
|
||||
describe('initializeSchema', () => {
|
||||
it('creates the topics, facts, fact_topics, and topic_relations tables', async () => {
|
||||
it('creates the topics, facts, fact_topics, topic_relations, and topic_aliases tables', async () => {
|
||||
const connection = await createDatabase({ client: 'sqlite', filename: ':memory:' });
|
||||
openConnections.push(connection.destroy);
|
||||
|
||||
@@ -35,6 +35,7 @@ describe('initializeSchema', () => {
|
||||
expect(tableNames).toContain('facts');
|
||||
expect(tableNames).toContain('fact_topics');
|
||||
expect(tableNames).toContain('topic_relations');
|
||||
expect(tableNames).toContain('topic_aliases');
|
||||
});
|
||||
|
||||
it('creates the expected columns for each table', async () => {
|
||||
@@ -47,6 +48,7 @@ describe('initializeSchema', () => {
|
||||
const factsColumns = await sql<{ name: string }>`PRAGMA table_info(facts)`.execute(connection.db);
|
||||
const factTopicsColumns = await sql<{ name: string }>`PRAGMA table_info(fact_topics)`.execute(connection.db);
|
||||
const topicRelationsColumns = await sql<{ name: string }>`PRAGMA table_info(topic_relations)`.execute(connection.db);
|
||||
const topicAliasesColumns = await sql<{ name: string }>`PRAGMA table_info(topic_aliases)`.execute(connection.db);
|
||||
|
||||
expect(topicsColumns.rows.map((row) => row.name)).toEqual([
|
||||
'id',
|
||||
@@ -85,6 +87,16 @@ describe('initializeSchema', () => {
|
||||
'relation',
|
||||
'created_at',
|
||||
]);
|
||||
|
||||
expect(topicAliasesColumns.rows.map((row) => row.name)).toEqual([
|
||||
'id',
|
||||
'topic_id',
|
||||
'alias',
|
||||
'normalized_alias',
|
||||
'is_primary',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
]);
|
||||
});
|
||||
|
||||
it('is idempotent when called more than once', async () => {
|
||||
|
||||
@@ -113,4 +113,12 @@ describe('IdentityDB queries', () => {
|
||||
'software technology',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
it('resolves alias names in topic lookups', async () => {
|
||||
await db.addTopicAlias('TypeScript', 'TS');
|
||||
|
||||
const topic = await db.getTopicByName('ts');
|
||||
|
||||
expect(topic?.name).toBe('TypeScript');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user