feat(db): conversations.findOrCreateForSpace for the ambient companion
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -42,3 +42,20 @@ export async function setSummary(id, summary) {
|
|||||||
);
|
);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function findOrCreateForSpace(space_id, agent_id, actor) {
|
||||||
|
const { rows: [existing] } = await pool.query(
|
||||||
|
`SELECT * FROM conversations
|
||||||
|
WHERE space_id=$1 AND agent_id=$2 AND status='open'
|
||||||
|
ORDER BY started_at DESC LIMIT 1`,
|
||||||
|
[space_id, agent_id]
|
||||||
|
);
|
||||||
|
if (existing) return existing;
|
||||||
|
const { rows: [r] } = await pool.query(
|
||||||
|
`INSERT INTO conversations(title, space_id, agent_id, metadata)
|
||||||
|
VALUES($1,$2,$3,$4) RETURNING *`,
|
||||||
|
['Companion', space_id, agent_id, {}]
|
||||||
|
);
|
||||||
|
await recordAudit(actor, 'create', 'conversation', r.id, null, r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|||||||
26
tests/db/conversations_companion.test.js
Normal file
26
tests/db/conversations_companion.test.js
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { describe, it, expect, beforeAll } from 'vitest';
|
||||||
|
import { pool } from '../../lib/db/pool.js';
|
||||||
|
import { resetDb } from '../helpers/db.js';
|
||||||
|
import { migrateUp } from '../../lib/db/migrate.js';
|
||||||
|
import * as conversations from '../../lib/db/repos/conversations.js';
|
||||||
|
|
||||||
|
const ACTOR = { kind: 'user', id: null };
|
||||||
|
let spaceId, agentId;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await resetDb(); await migrateUp();
|
||||||
|
({ rows: [{ id: spaceId }] } = await pool.query(
|
||||||
|
`INSERT INTO spaces(slug,name) VALUES('s','S') RETURNING id`));
|
||||||
|
({ rows: [{ id: agentId }] } = await pool.query(
|
||||||
|
`SELECT id FROM agents WHERE slug='companion'`));
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('findOrCreateForSpace', () => {
|
||||||
|
it('creates once then returns the same row', async () => {
|
||||||
|
const a = await conversations.findOrCreateForSpace(spaceId, agentId, ACTOR);
|
||||||
|
const b = await conversations.findOrCreateForSpace(spaceId, agentId, ACTOR);
|
||||||
|
expect(a.id).toBe(b.id);
|
||||||
|
expect(a.space_id).toBe(spaceId);
|
||||||
|
expect(a.agent_id).toBe(agentId);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user