fix: port search and dimension safety guardrails

- enforce canonical dimensions across app and MCP surfaces
- prioritize title-first node search in UI and query tools
- add regression tests for ranking and dimension validation
This commit is contained in:
“BeeRad”
2026-03-23 10:47:18 +11:00
parent c1eda905d3
commit 545dc6e2e8
18 changed files with 250 additions and 78 deletions
@@ -0,0 +1,27 @@
import { describe, expect, it, vi } from 'vitest';
vi.mock('@/services/database/sqlite-client', () => ({
getSQLiteClient: vi.fn(),
}));
import { getSQLiteClient } from '@/services/database/sqlite-client';
import { formatUnknownDimensionsError, getUnknownDimensions } from '@/services/database/dimensionValidation';
describe('dimensionValidation', () => {
it('returns dimensions missing from the canonical dimensions table', () => {
vi.mocked(getSQLiteClient).mockReturnValue({
query: vi.fn().mockReturnValue({
rows: [{ name: 'ra-h' }, { name: 'ai' }],
}),
} as unknown as ReturnType<typeof getSQLiteClient>);
expect(getUnknownDimensions(['ra-h', 'Building RA-H — Personal Knowledge Graph', 'ai'])).toEqual([
'Building RA-H — Personal Knowledge Graph',
]);
});
it('formats a clear error for unknown dimensions', () => {
expect(formatUnknownDimensionsError(['Building RA-H — Personal Knowledge Graph']))
.toBe('Unknown dimension: "Building RA-H — Personal Knowledge Graph". Create it first or use an existing dimension.');
});
});
+25
View File
@@ -0,0 +1,25 @@
import { describe, expect, it } from 'vitest';
import { scoreNodeSearchMatch } from '@/services/database/searchRanking';
describe('scoreNodeSearchMatch', () => {
it('strongly prefers the closest title match for hub-node queries', () => {
const query = 'building ra-h';
const hubScore = scoreNodeSearchMatch({
title: 'Building RA-H — Personal Knowledge Graph',
description: 'Brad project hub',
source: '',
updated_at: '2026-03-23T00:00:00.000Z',
}, query);
const broadScore = scoreNodeSearchMatch({
title: 'the ra-h project',
description: 'Foundational project document for RA-H',
source: '',
updated_at: '2026-03-23T00:00:00.000Z',
}, query);
expect(hubScore).toBeGreaterThan(broadScore);
});
});
+5
View File
@@ -0,0 +1,5 @@
import { afterEach, vi } from 'vitest';
afterEach(() => {
vi.restoreAllMocks();
});