/** * v4 schema-level tests for `Llm.poolName` and the dispatcher's * `findByPoolName` query semantics. Lives in the db package because it * exercises the actual Prisma column + index — the mcpd-side unit tests * already cover the dispatcher's behavior with a mocked LlmService. */ import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest'; import type { PrismaClient } from '@prisma/client'; import { setupTestDb, cleanupTestDb, clearAllTables } from './helpers.js'; /** Re-implementation of the LlmRepository query for direct schema verification. */ function findByPoolName(prisma: PrismaClient, poolName: string) { return prisma.llm.findMany({ where: { OR: [ { poolName }, { AND: [{ poolName: null }, { name: poolName }] }, ], }, orderBy: { name: 'asc' }, }); } describe('Llm.poolName (v4)', () => { let prisma: PrismaClient; beforeAll(async () => { prisma = await setupTestDb(); }, 30_000); afterAll(async () => { await cleanupTestDb(); }); beforeEach(async () => { await clearAllTables(prisma); }); it('defaults poolName to NULL for freshly inserted rows', async () => { const llm = await prisma.llm.create({ data: { name: 'plain', type: 'openai', model: 'gpt-4o' }, }); expect(llm.poolName).toBeNull(); }); it('allows multiple rows to share a poolName (the v4 stacking behavior)', async () => { await prisma.llm.create({ data: { name: 'qwen-prod-1', type: 'openai', model: 'qwen3-thinking', poolName: 'qwen-pool' }, }); await prisma.llm.create({ data: { name: 'qwen-prod-2', type: 'openai', model: 'qwen3-thinking', poolName: 'qwen-pool' }, }); await prisma.llm.create({ data: { name: 'qwen-prod-3', type: 'openai', model: 'qwen3-thinking', poolName: 'qwen-pool' }, }); const members = await findByPoolName(prisma, 'qwen-pool'); expect(members.map((m) => m.name).sort()).toEqual(['qwen-prod-1', 'qwen-prod-2', 'qwen-prod-3']); }); it('keeps `name` globally unique even when multiple rows share a poolName', async () => { await prisma.llm.create({ data: { name: 'qwen-prod-1', type: 'openai', model: 'qwen3-thinking', poolName: 'qwen-pool' }, }); await expect( prisma.llm.create({ data: { name: 'qwen-prod-1', type: 'openai', model: 'qwen3-thinking', poolName: 'qwen-pool' }, }), ).rejects.toThrow(); }); it('falls back to `name` as the effective pool key for solo rows (poolName=NULL)', async () => { // Solo row addressable via its own name as a "pool of 1". await prisma.llm.create({ data: { name: 'gpt-4o', type: 'openai', model: 'gpt-4o' }, }); const members = await findByPoolName(prisma, 'gpt-4o'); expect(members.map((m) => m.name)).toEqual(['gpt-4o']); }); it('a solo row with name=X joins the same pool as explicit poolName=X members', async () => { // Edge case: an existing solo Llm named "qwen-pool" pre-dates pool // adoption, then a publisher registers with poolName=qwen-pool. Both // should appear in the dispatcher's candidate list — the effective // pool key (poolName ?? name) is "qwen-pool" for each. await prisma.llm.create({ data: { name: 'qwen-pool', type: 'openai', model: 'qwen3-thinking' }, }); await prisma.llm.create({ data: { name: 'qwen-prod-2', type: 'openai', model: 'qwen3-thinking', poolName: 'qwen-pool' }, }); const members = await findByPoolName(prisma, 'qwen-pool'); expect(members.map((m) => m.name).sort()).toEqual(['qwen-pool', 'qwen-prod-2']); }); it('does not match a solo row by `name` when its poolName is set to something else', async () => { // Solo with name=foo but poolName=bar should NOT match findByPoolName('foo') // — the explicit poolName takes precedence over the name fallback. await prisma.llm.create({ data: { name: 'foo', type: 'openai', model: 'm', poolName: 'bar' }, }); const members = await findByPoolName(prisma, 'foo'); expect(members.map((m) => m.name)).toEqual([]); const inBar = await findByPoolName(prisma, 'bar'); expect(inBar.map((m) => m.name)).toEqual(['foo']); }); it('updates poolName via update() and round-trips correctly', async () => { const llm = await prisma.llm.create({ data: { name: 'qwen-prod-1', type: 'openai', model: 'qwen3-thinking' }, }); expect(llm.poolName).toBeNull(); const updated = await prisma.llm.update({ where: { id: llm.id }, data: { poolName: 'qwen-pool' }, }); expect(updated.poolName).toBe('qwen-pool'); // Revert to solo (NULL). const reverted = await prisma.llm.update({ where: { id: llm.id }, data: { poolName: null }, }); expect(reverted.poolName).toBeNull(); }); });